📄 ospfd_freebsd.c
字号:
strcpy(filename, INSTALL_DIR); strcat(filename, ospfd_tcl_src); if (Tcl_EvalFile(interp, filename) != TCL_OK) syslog(LOG_INFO, "No additional TCL commands"); delete [] filename; // (Re)read kernel interfaces read_kernel_interfaces(); // (Re)read config file if (Tcl_EvalFile(interp, ospfd_config_file) != TCL_OK) { syslog(LOG_ERR, "Error in config file, line %d", interp->errorLine); return; } // Verify router ID was given if (!ospf || new_router_id == 0) { syslog(LOG_ERR, "Failed to set Router ID"); return; } // Request to change OSPF Router ID? if (ospf->my_id() != new_router_id) { changing_routerid = true; ospf->shutdown(10); return; } // Reset current config ospf->cfgStart(); // Download new config Tcl_Eval(interp, sendcfg); Tcl_DeleteInterp(interp); // Signal configuration complete ospf->cfgDone();}/* Complete the changing of the OSPF Router ID. */void FreeBSDOspfd::process_routerid_change(){ if (changing_routerid && change_complete) { printf("----\nprocess_routerid_change\n"); changing_routerid = false; change_complete = false; delete ospf; ospf = 0; read_config(); if (!ospf) { syslog(LOG_ERR, "Router ID change failed"); exit(1); } }}/* Find the physical interface to which a given address * belongs. Returns -1 if no matching interface * can be found. */int FreeBSDOspfd::get_phyint(InAddr addr){ printf("----\nget_phyint\n"); int i; for (i=0; i < MAXIFs; i++) { BSDPhyInt *phyp; phyp = phys[i]; if (phyp && (phyp->addr & phyp->mask) == (addr & phyp->mask)) return(i); } return(-1);}/* Read the IP interface information out of the FreeBSD * kernel. */void FreeBSDOspfd::read_kernel_interfaces(){ printf("----\nread_kernel_interfaces\n"); ifconf cfgreq; ifreq *ifrp; ifreq *end; size_t size; char *ifcbuf; int blen; AVLsearch iter(&directs); DirectRoute *rte; blen = MAXIFs*sizeof(ifreq); ifcbuf = new char[blen]; cfgreq.ifc_buf = ifcbuf; cfgreq.ifc_len = blen; if (ioctl(udpfd, SIOCGIFCONF, (char *)&cfgreq) < 0) { syslog(LOG_ERR, "Failed to read interface config: %m"); exit(1); } /* Clear current list of interfaces and directly * attached subnets, since we're going to reread * them. */ interface_map.clear(); while ((rte = (DirectRoute *)iter.next())) rte->valid = false; ifrp = (ifreq *) ifcbuf; end = (ifreq *)(ifcbuf + cfgreq.ifc_len); for (; ifrp < end; ifrp = (ifreq *)(((byte *)ifrp) + size)) { BSDPhyInt *phyp; byte *phystr; ifreq ifr; sockaddr_in *insock; InAddr addr; // Find next interface structure in list size=_SIZEOF_ADDR_IFREQ(*ifrp) ; // IP interfaces only if (ifrp->ifr_addr.sa_family != AF_INET) continue; printf("IFname: %s\n", ifrp->ifr_name); // Ignore loopback interfaces // Also ignore "down" interfaces // Get interface flags short ifflags; memcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(udpfd, SIOCGIFFLAGS, (char *)&ifr) < 0) { syslog(LOG_ERR, "SIOCGIFFLAGS Failed: %m"); exit(1); } if ((ifr.ifr_flags & IFF_LOOPBACK) != 0) continue; ifflags = ifr.ifr_flags; printf("Flags=%x\n", ifflags); /* Found a legitimate interface * Add physical interface and * IP address maps */ if (!(phyp = (BSDPhyInt *) phyints.find(ifrp->ifr_name))) { phyp = new BSDPhyInt; phystr = new byte[sizeof(ifrp->ifr_name)]; bzero(phystr, sizeof(ifrp->ifr_name)); memcpy(phystr, ifrp->ifr_name, sizeof(ifrp->ifr_name)); phyp->key = phystr; phyp->keylen = strlen(ifrp->ifr_name); phyp->phyint = ++next_phyint; printf("phyint number = %d, key=%s keylen=%d\n", phyp->phyint, phyp->key, phyp->keylen); phyp->flags = 0; phyints.add(phyp); // May have multiple interfaces attached to same physical // net if (!phys[phyp->phyint]) phys[phyp->phyint] = phyp; } if (!memchr(ifrp->ifr_name, ':', strlen(ifrp->ifr_name))) { set_flags(phyp, ifflags); } insock = (sockaddr_in *) &ifrp->ifr_addr; addr = phyp->addr = ntoh32(insock->sin_addr.s_addr); printf("addr = %s\n", inet_ntoa(insock->sin_addr)); // Get subnet mask if (ioctl(udpfd, SIOCGIFNETMASK, (char *)&ifr) < 0) { syslog(LOG_ERR, "SIOCGIFNETMASK Failed: %m"); exit(1); } insock = (sockaddr_in *) &ifr.ifr_addr; phyp->mask = ntoh32(insock->sin_addr.s_addr); printf("netmask = %x\n", phyp->mask); add_direct(phyp, addr, phyp->mask); add_direct(phyp, addr, 0xffffffffL); // Get interface MTU phyp->mtu = ((phyp->flags & IFF_BROADCAST) != 0) ? 1500 : 576; if (ioctl(udpfd, SIOCGIFMTU, (char *)&ifr) >= 0) phyp->mtu = ifr.ifr_mtu; printf("MTU: %d\n", phyp->mtu); // For point-to-point links, get other end's address phyp->dstaddr = 0; if ((phyp->flags & IFF_POINTOPOINT) != 0 && (ioctl(udpfd, SIOCGIFDSTADDR, (char *)&ifr) >= 0)) { printf("Point-to-point\n"); addr = phyp->dstaddr = ntoh32(insock->sin_addr.s_addr); add_direct(phyp, addr, 0xffffffffL); } // Install map from IP address to physical interface if (!interface_map.find(addr, 0)) { BSDIfMap *map; map = new BSDIfMap(addr, phyp); interface_map.add(map); } } /* Put back any routes that were obscured by formerly * operational direct routes. Take away routes that are * now supplanted by direct routes. */ iter.seek(0, 0); while ((rte = (DirectRoute *)iter.next())) { InAddr net=rte->index1(); InMask mask=rte->index2(); if (!rte->valid) { directs.remove(rte); delete rte; ospf->krt_delete_notification(net, mask); } #if LINUX_VERSION_CODE >= LINUX22 else sys->rtdel(net, mask, 0);#endif } delete [] ifcbuf;}/* Set the interface flags, If the IFF_UP flag * has changed, call the appropriate OSPFD API * routine. */void FreeBSDOspfd::set_flags(BSDPhyInt *phyp, short flags){ printf("----\nset_flags\n"); short old_flags=phyp->flags; phyp->flags = flags; if (((old_flags^flags) & IFF_UP) != 0 && ospf) { if ((flags & IFF_UP) != 0) ospf->phy_up(phyp->phyint); else ospf->phy_down(phyp->phyint); }}/* Add to the list of directly attached prefixes. These * we will let the kernel manage directly. */void FreeBSDOspfd::add_direct(BSDPhyInt *phyp, InAddr addr, InMask mask){ printf("----\nadd_direct\n"); DirectRoute *rte; if ((phyp->flags & IFF_UP) == 0) { printf("Interface is down!\n"); return; } addr = addr & mask; if (!(rte = (DirectRoute *)directs.find(addr, mask))) { rte = new DirectRoute(addr, mask); printf("new direct route: %x, %x\n", addr, mask); directs.add(rte); } rte->valid = true;}/* Parse an interface identifier, which can either be an address * or a name like "eth0". */bool FreeBSDOspfd::parse_interface(char *arg, in_addr &addr, BSDPhyInt *&phyp){ phyp = 0; printf("---\nparse_interface: %s\n", arg); if (inet_aton(arg, &addr) == 1) { BSDIfMap *map; InAddr ifaddr; ifaddr = ntoh32(addr.s_addr); map = (BSDIfMap *) interface_map.find(ifaddr, 0); if (map != 0) phyp = map->phyp; } else { char ifname[IFNAMSIZ]; strncpy((char *)ifname, arg, IFNAMSIZ); phyp = (BSDPhyInt *) phyints.find(ifname);#if 0 // Try to detect unnumbered interfaces if (!phyp) { int ifindex; byte *phystr; ifreq ifr; short ifflags; memcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (memchr(ifr.ifr_name, ':', sizeof(ifr.ifr_name))) goto done; if (ioctl(udpfd, SIOCGIFFLAGS, (char *)&ifr) < 0) goto done; if ((ifr.ifr_flags & IFF_LOOPBACK) != 0) goto done; ifflags = ifr.ifr_flags; // Get interface index if (ioctl(udpfd, SIOCGIFINDEX, (char *)&ifr) < 0) goto done; ifindex = ifr.ifr_ifindex; if (phys[ifindex]) goto done; phyp = new BSDPhyInt; phystr = new byte[sizeof(ifr.ifr_name)]; memcpy(phystr, ifr.ifr_name, sizeof(ifr.ifr_name)); phyp->key = phystr; phyp->keylen = strlen(ifr.ifr_name); phyp->phyint = ifindex; phyp->flags = 0; phyints.add(phyp); phys[phyp->phyint] = phyp; set_flags(phyp, ifflags); phyp->addr = 0; phyp->mask = 0; phyp->dstaddr = 0; }#endif }#if 0 done:#endif /* 0 */ if (!phyp) { syslog(LOG_ERR, "Bad interface identifier %s", arg); return(false); } return(true);}/* Set the Router ID of the OSPF Process. * Refuse to reset the OSPF Router ID if it has already * been set. */int SetRouterID(ClientData, Tcl_Interp *, int, char *argv[]){ new_router_id = ntoh32(inet_addr(argv[1])); if (!ospf) ospf = new OSPF(new_router_id); return(TCL_OK);}/* Download the global configuration values into the ospfd * software. If try to change Router ID, refuse reconfig. * If first time, create OSPF protocol instance. */int SendGeneral(ClientData, Tcl_Interp *, int, char *argv[]){ CfgGen m; m.lsdb_limit = atoi(argv[1]); m.mospf_enabled = atoi(argv[2]); m.inter_area_mc = atoi(argv[3]); m.ovfl_int = atoi(argv[4]); m.new_flood_rate = atoi(argv[5]); m.max_rxmt_window = atoi(argv[6]); m.max_dds = atoi(argv[7]); m.host_mode = atoi(argv[9]); m.log_priority = atoi(argv[8]); m.refresh_rate = atoi(argv[10]); m.PPAdjLimit = atoi(argv[11]); m.random_refresh = atoi(argv[12]); ospf->cfgOspf(&m); return(TCL_OK);}/* Dowload configuration of a single area */int SendArea(ClientData, Tcl_Interp *, int, char *argv[]){ CfgArea m; m.area_id = ntoh32(inet_addr(argv[1])); m.stub = atoi(argv[2]); m.dflt_cost = atoi(argv[3]); m.import_summs = atoi(argv[4]); ospf->cfgArea(&m, ADD_ITEM); return(TCL_OK);}int SendAggregate(ClientData, Tcl_Interp *, int, char *argv[]){ CfgRnge m; InAddr net; InAddr mask; if (get_prefix(argv[1], net, mask)) { m.net = net; m.mask = mask; m.area_id = ntoh32(inet_addr(argv[2])); m.no_adv = atoi(argv[3]); ospf->cfgRnge(&m, ADD_ITEM); } return(TCL_OK);}int SendHost(ClientData, Tcl_Interp *, int, char *argv[]){ CfgHost m; InAddr net; InAddr mask; if (get_prefix(argv[1], net, mask)) { m.net = net; m.mask = mask; m.area_id = ntoh32(inet_addr(argv[2])); m.cost = atoi(argv[3]); ospf->cfgHost(&m, ADD_ITEM); } return(TCL_OK);}/* Download an interface's configuration. * Interface can by identified by its address, name, or * for point-to-point addresses, the other end of the link. */int SendInterface(ClientData, Tcl_Interp *, int, char *argv[]){ CfgIfc m; in_addr addr; BSDPhyInt *phyp; int intval; printf("SendInterface\n"); if (!ospfd_sys->parse_interface(argv[1], addr, phyp)) return(TCL_OK); printf("here23\n"); m.address = phyp->addr; m.phyint = phyp->phyint; m.mask = phyp->mask; intval = atoi(argv[2]); m.mtu = (intval ? intval : phyp->mtu); m.IfIndex = atoi(argv[3]); m.area_id = ntoh32(inet_addr(argv[4])); intval = atoi(argv[5]); if (intval) m.IfType = intval; else if ((phyp->flags & IFF_BROADCAST) != 0) m.IfType = IFT_BROADCAST; else if ((phyp->flags & IFF_POINTOPOINT) != 0) m.IfType = IFT_PP; else m.IfType = IFT_NBMA; m.dr_pri = atoi(argv[6]); m.xmt_dly = atoi(argv[7]); m.rxmt_int = atoi(argv[8]); m.hello_int = atoi(argv[9]); m.if_cost = atoi(argv[10]); m.dead_int = atoi(argv[11]); m.poll_int = atoi(argv[12]); m.auth_type = atoi(argv[13]); memset(m.auth_key, 0, 8); strncpy((char *) m.auth_key, argv[14], (size_t) 8); m.mc_fwd = atoi(argv[15]); m.demand = atoi(argv[16]); m.passive = atoi(argv[17]); ospf->cfgIfc(&m, ADD_ITEM); return(TCL_OK);}int SendVL(ClientData, Tcl_Interp *, int, char *argv[]){ CfgVL m; m.nbr_id = ntoh32(inet_addr(argv[1])); m.transit_area = ntoh32(inet_addr(argv[2])); m.xmt_dly = atoi(argv[3]); m.rxmt_int = atoi(argv[4]); m.hello_int = atoi(argv[5]); m.dead_int = atoi(argv[6]); m.auth_type = atoi(argv[7]); strncpy((char *) m.auth_key, argv[8], (size_t) 8); ospf->cfgVL(&m, ADD_ITEM); return(TCL_OK);}int SendNeighbor(ClientData, Tcl_Interp *, int, char *argv[]){ CfgNbr m; m.nbr_addr = ntoh32(inet_addr(argv[1])); m.dr_eligible = atoi(argv[2]); ospf->cfgNbr(&m, ADD_ITEM); return(TCL_OK);}int SendExtRt(ClientData, Tcl_Interp *, int, char *argv[]){ CfgExRt m; InAddr net; InMask mask; if (get_prefix(argv[1], net, mask)) { m.net = net; m.mask = mask; m.type2 = (atoi(argv[3]) == 2); m.mc = (atoi(argv[5]) != 0); m.direct = 0; m.noadv = 0; m.cost = atoi(argv[4]); m.gw = ntoh32(inet_addr(argv[2])); m.phyint = ospfd_sys->get_phyint(m.gw); m.tag = atoi(argv[6]); ospf->cfgExRt(&m, ADD_ITEM); } return(TCL_OK);}int SendMD5Key(ClientData, Tcl_Interp *, int, char *argv[]){ CfgAuKey m; in_addr addr; BSDPhyInt *phyp; timeval now; tm tmstr; if (!ospfd_sys->parse_interface(argv[1], addr, phyp)) return(TCL_OK); gettimeofday(&now, 0); m.address = phyp->addr; m.phyint = phyp->phyint; m.key_id = atoi(argv[2]); memset(m.auth_key, 0, 16); strncpy((char *) m.auth_key, argv[3], (size_t) 16); if (strptime(argv[4], "%D@%T", &tmstr)) { m.start_accept = SPFtime(mktime(&tmstr), 0); } else { m.start_accept = now; } if (strptime(argv[5], "%D@%T", &tmstr)) { m.start_generate = SPFtime(mktime(&tmstr), 0); } else { m.start_accept = now; } if (strptime(argv[6], "%D@%T", &tmstr)) { m.stop_generate = SPFtime(mktime(&tmstr), 0); m.stop_generate_specified = true; } else { m.stop_generate_specified = false; } if (strptime(argv[7], "%D@%T", &tmstr)) { m.stop_accept = SPFtime(mktime(&tmstr), 0); m.stop_accept_specified = true; } else { m.stop_accept_specified = false; } ospf->cfgAuKey(&m, ADD_ITEM); return(TCL_OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -