📄 startup.c
字号:
} else if (ripIfWithAddrAndIndex (&ifs.int_addr, ifam->ifam_index)) continue; if (ifs.int_flags & IFF_LOOPBACK) { ifs.int_flags |= IFF_PASSIVE; foundloopback = 1; loopaddr = ifs.int_addr; for (ifp = ripIfNet; ifp; ifp = ifp->int_next) if (ifp->int_flags & IFF_POINTOPOINT) add_ptopt_localrt(ifp, 0); } /* Assign the broadcast address for the interface, if any. */ if (ifs.int_flags & IFF_BROADCAST) { if (BRDADDR == 0) { if (routedDebug) logMsg ("No broadcast address for %s.\n", (int)sdl->sdl_data, 0, 0, 0, 0, 0); continue; } ifs.int_dstaddr = *BRDADDR; } /* * Use a minimum metric of one; treat the interface metric * (default 0) as an increment to the hop count of one. */ ifs.int_metric = ifam->ifam_metric + 1; /* Assign the network and subnet values. */ if (NETMASK == 0) { if (routedDebug) logMsg ("No netmask for %s.\n", (int)sdl->sdl_data, 0, 0, 0, 0, 0); continue; } /* * For AF_INET addresses, the int_subnetmask field copied here * defaults to the class-based value for the associated int_addr * field, but will contain some other value if explicity specified. */ sin = (struct sockaddr_in *)NETMASK; ifs.int_subnetmask = ntohl (sin->sin_addr.s_addr); /* * The network number stored here may differ from the original * value accessed through the ifnet linked list. The original value * is equal to the class-based setting by default, but is reset * to the same value as the int_subnetmask field if a less * specific (i.e. supernetted) value is assigned. This value is * always set equal to the class-based value, even if a supernet * is specified. */ sin = (struct sockaddr_in *)&ifs.int_addr; i = ntohl(sin->sin_addr.s_addr); if (IN_CLASSA(i)) ifs.int_netmask = IN_CLASSA_NET; else if (IN_CLASSB(i)) ifs.int_netmask = IN_CLASSB_NET; else ifs.int_netmask = IN_CLASSC_NET; ifs.int_net = i & ifs.int_netmask; ifs.int_subnet = i & ifs.int_subnetmask; /* * The IFF_SUBNET flag indicates that the interface does not use the * class-based mask stored in the int_netmask field: it may be more * or less specific than that value. */ if (ifs.int_subnetmask != ifs.int_netmask) ifs.int_flags |= IFF_SUBNET; ifp = (struct interface *)malloc (sdl->sdl_nlen + 1 + sizeof(ifs)); if (ifp == 0) { if (routedDebug) logMsg ("routedIfInit: out of memory.\n", 0, 0, 0, 0, 0, 0); ripState.lookforinterfaces = TRUE; break; } *ifp = ifs; /* * Count the # of directly connected networks * and point to point links which aren't looped * back to ourself. This is used below to * decide if we should be a routing ``supplier''. */ if ( (ifs.int_flags & IFF_LOOPBACK) == 0 && ( (ifs.int_flags & IFF_POINTOPOINT) == 0 || ripIfWithAddr (&ifs.int_dstaddr) == 0)) ripState.externalinterfaces++; /* * If we have a point-to-point link, we want to act * as a supplier even if it's our only interface, * as that's the only way our peer on the other end * can tell that the link is up. */ if ( (ifs.int_flags & IFF_POINTOPOINT) && ripState.supplier < 0) ripState.supplier = 1; /* * Copy the interface name specified in the link-level address. * into the space provided. */ ifp->int_name = (char *)(ifp + 1); strcpy (ifp->int_name, sdl->sdl_data); /* Set the index of the interface */ ifp->int_index = ifam->ifam_index; /* Add the given entry to the ripIfNet linked list. */ *ifnext = ifp; ifnext = &ifp->int_next; /* Create a route to the network reachable with the new address. */ addrouteforif (ifp); /* Set the MIB variables for the configuration on this interface. */ bzero ( (char *)&ifp->ifStat, sizeof(ifp->ifStat)); bzero ( (char *)&ifp->ifConf, sizeof(ifp->ifConf)); sin = (struct sockaddr_in *)&ifs.int_addr; i = sin->sin_addr.s_addr; ifp->ifStat.rip2IfStatAddress = i; ifp->ifConf.rip2IfConfAddress = i; ifp->ifConf.rip2IfConfAuthType = ripState.ripConf.rip2IfConfAuthType; bcopy (ripState.ripConf.rip2IfConfAuthKey, ifp->ifConf.rip2IfConfAuthKey, 16); ifp->ifConf.rip2IfConfSend = ripState.ripConf.rip2IfConfSend; ifp->ifConf.rip2IfConfReceive = ripState.ripConf.rip2IfConfReceive; ifp->ifConf.rip2IfConfDefaultMetric = ripState.ripConf.rip2IfConfDefaultMetric; ifp->ifConf.rip2IfConfStatus = ripState.ripConf.rip2IfConfStatus; ifp->authHook = NULL; ifp->leakHook = NULL; ifp->sendHook = NULL; /* * If multicasting is enabled and the interface supports it, * attempt to join the RIP multicast group. */ if (ripState.multicast && (ifs.int_flags & IFF_MULTICAST)) { ipMreq.imr_interface.s_addr = i; if (setsockopt (ripState.s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ipMreq, sizeof (ipMreq)) < 0) { if (routedDebug) logMsg ("setsockopt IP_ADD_MEMBERSHIP error:\n", 0, 0, 0, 0, 0, 0); } } } if (ripState.externalinterfaces > 1 && ripState.supplier < 0) ripState.supplier = 1; free (buf); return (OK); }/* * Add route for interface if not currently installed. * Create route to other end if a point-to-point link, * otherwise a route to this (sub)network. * INTERNET SPECIFIC. */void addrouteforif(ifp) register struct interface *ifp;{ struct sockaddr_in net; struct sockaddr *dst; int state; register struct rt_entry *rt; int refcnt_save = 0; int subnets_cnt_save = 0; /* Clear the fact there there are no routes for this interface */ ifp->int_flags &= ~IFF_ROUTES_DELETED; /* * The algorithm explained.... * We are going to add route(s) for the interface. * The following cases exist: * 1) The interface is not PPP and not-subnetted * e.g, 164.10.1.1/16 * In this case we just want to add the following route * 164.10.0.0 255.255.0.0 --> 164.10.1.1 * If there already exists another route for that same network, * if that route is not an internally generated route * increment rt_refcnt * else * Delete the existing route and save its ref counts * Add route through this interface. * Set the reference counts from the previous route. * increment rt_refcnt and rt_subnets_cnt * else * Add the route through the inetrface * Set rt_refcnt and rt_subnets_cnt to zero * * 2) The interface is not PPP and is subnetted * e.g, 164.10.2.1/24 * In this case we want to add the following routes * 164.10.2.0 255.255.255.0 --> 164.10.2.1 * 164.10.0.0 255.255.0.0 --> 164.10.2.1 (Internal route) * The internal route is used for border gateway filtering. * * If there already exists another route for that same * (sub)network, * if that route is not an internally generated route * increment rt_refcnt * else * Delete the existing route and save its ref counts * Add route through this interface. * Set the reference counts from the previous route. * increment rt_refcnt and rt_subnets_cnt * else * Add the route through the inetrface * Set rt_refcnt and rt_subnets_cnt to zero * If there exists a route for the class based network * increment the rt_refcnt and rt_subnets_cnt for the route * else * Add the internal class based route. * Set both the ref counts to zero. * * 3) The interface is PPP * e.g, 164.10.1.1/32 --> 124.10.2.2 * In this case we just want to add the following routes * 124.10.2.2 255.255.255.255 --> 164.10.1.1 * 164.10.1.1 255.255.255.255 --> 127.0.0.1 * If there already exists another route for the destination * increment rt_refcnt * else * Add the route through the inetrface * Set rt_refcnt and rt_subnets_cnt to zero * Add a route for the local address of the link thru the * loopback interface. */ /* Check if there already exists a route for the network (remote end)*/ if (ifp->int_flags & IFF_POINTOPOINT) dst = &ifp->int_dstaddr; else { memset(&net, 0, sizeof (net)); net.sin_len = sizeof (net); net.sin_family = AF_INET; net.sin_addr.s_addr = htonl (ifp->int_subnet); dst = (struct sockaddr *)&net; } if ((rt = rtlookup(dst)) == NULL) rt = rtfind(dst); if (rt) { /* * If we have an indirect route to the destination, * delete it as we now have a direct route */ if ((rt->rt_state & RTS_INTERFACE) == 0) rtdelete (rt); else { if (ifp->int_flags & IFF_POINTOPOINT) { rt->rt_refcnt++; if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) add_ptopt_localrt(ifp, 0); return; } if ((rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE) { /* The route is not an internal route */ if (rt->rt_ifp->int_subnetmask == ifp->int_subnetmask) { /* * This interface is on the same (sub)network as the * retrieved route. Increment the reference count. */ rt->rt_refcnt++; /* * If the interface uses classless addressing, * an additional entry is stored in the routing table * which can be correctly interpreted by RIP-1 and * RIP-2 routers that are not directly connected to * the interface's network. The appropriate entry is * selected by the border gateway filtering performed * when updates are generated. */ if (ifp->int_flags & IFF_SUBNET) { net.sin_addr.s_addr = htonl (ifp->int_net); if ((rt = rtlookup(dst)) == NULL) rt = rtfind(dst); if (rt == 0) { if (routedDebug) logMsg ("Error! Didn't find classful route" " for %x, interface %s.\n", (int)ifp->int_net, (int)ifp->int_name, 0, 0, 0, 0); } else { rt->rt_refcnt++; rt->rt_subnets_cnt++; if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == (RTS_INTERNAL|RTS_SUBNET) && (ifp->int_metric < rt->rt_metric)) rtchange (rt, &ifp->int_addr, ifp->int_metric, NULL, 0, 0, ifp); } } return; } } else { /* * If this was a classful route installed by an earlier * subnetted interface, save the reference count values * as we'll need to restore them on the route that will * be installed later */ refcnt_save = rt->rt_refcnt + 1; subnets_cnt_save = rt->rt_subnets_cnt + 1; rtdelete (rt); } } } /* * If the interface uses classless addressing, an additional entry * is stored in the routing table which can be correctly interpreted * by RIP-1 and RIP-2 routers that are not directly connected to * the interface's network. The appropriate entry is selected by the * border gateway filtering performed when updates are generated. */ if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) { struct in_addr subnet; subnet = net.sin_addr; net.sin_addr.s_addr = htonl (ifp->int_net); if ((rt = rtlookup(dst)) == NULL) rt = rtfind(dst); if (rt == 0) rt = rtadd(dst, &ifp->int_addr, ifp->int_metric,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -