📄 startup.c
字号:
((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET), NULL, M2_ipRouteProto_rip, 0, 0, ifp); 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); } net.sin_addr = subnet; } if (ifp->int_transitions++ > 0) if (routedDebug) logMsg ("Warning! Re-installing route for interface %s.\n", (int)ifp->int_name, 0, 0, 0, 0, 0); state = ifp->int_flags & (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET); if (ifp->int_flags & IFF_POINTOPOINT && (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) & ifp->int_netmask) != ifp->int_net) state &= ~RTS_SUBNET; if (ifp->int_flags & IFF_LOOPBACK) state |= RTS_EXTERNAL; rt = rtadd(dst, &ifp->int_addr, ifp->int_metric, state, NULL, M2_ipRouteProto_rip, 0, 0, ifp); /* * Now set the reference counts. * This might be a network route that replaced a previous * classful route. If we had any references on that earlier * route we need to transfer them here */ rt->rt_refcnt = refcnt_save; rt->rt_subnets_cnt = subnets_cnt_save; if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) add_ptopt_localrt(ifp, 0); }/* * Add route to local end of point-to-point using loopback. * If a route to this network is being sent to neighbors on other nets, * mark this route as subnet so we don't have to propagate it too. */int add_ptopt_localrt(ifp, refcnt) register struct interface *ifp; int refcnt; { struct rt_entry *rt; struct sockaddr *dst; struct sockaddr_in net; int state; struct sockaddr_in hostMask = { sizeof (struct sockaddr_in), AF_INET, 0, {INADDR_BROADCAST} }; state = RTS_INTERFACE | RTS_PASSIVE; /* look for route to logical network */ memset(&net, 0, sizeof (net)); net.sin_len = sizeof (net); net.sin_family = AF_INET; net.sin_addr.s_addr = htonl (ifp->int_net); dst = (struct sockaddr *)&net; if ((rt = rtlookup(dst)) == NULL) rt = rtfind(dst); if (rt && rt->rt_state & RTS_INTERNAL) state |= RTS_SUBNET; dst = &ifp->int_addr; rt = rtfind (dst); if (rt) { if (rt->rt_state & RTS_INTERFACE) { /* * We are piggybacking onto somebody else' route. So we * should increment the ref count */ if (refcnt == 0) refcnt = 1; rt->rt_refcnt += refcnt; return (ERROR); } rtdelete(rt); } rt = rtadd(dst, &loopaddr, 1, state, (struct sockaddr *)&hostMask, M2_ipRouteProto_rip, 0, 0, NULL); if (rt) rt->rt_refcnt = refcnt; return (OK); }/* * Add route for interface or an internal network route for * a subnetted interface * This routine is called from the rtdelete() routine when an * interface route is deleted and there exists other references to that * route. This routine will add the route through another interface * and adjust the reference count accordingly. * The internalFlag is set when an internally generated classful route * should be added. If the flag is not set, then a regular interface * route is added. * In the simplest of cases, wherein the route being deleted was referenced * by another interface on the same network, a new route is added through that * other interface. * * In other cases, the network route being deleted might be referenced by * point to point interfaces on the same network: e.g * 164.10.0.0/16 --> 164.10.1.1 (being deleted) * is referenced by the following PPP interface * src = 164.10.22.1, dst=164.10.22.2 * In the above case the rt_refcnt field of the route (prior to rtdelete) * would be 2 and rt_subnets_cnt would be 0. On call to this routine, * refCnt would be 1 and subnetsCnt would be 0 * This routine would need to add the following routes in response to the * deletion of the 164.10.0.0/16 --> 164.10.1.1 route: * 164.10.22.2/32 --> 164.10.22.1 * 164.10.22.1/32 --> 127.0.0.1 * Both the above routes should have rt_refcnt and rt_subnets_cnt set to zero * * There are many other cases where just the local or the remote end of the PPP * interface may be referencing the route being deleted, or there may be * multiple such interfaces. * * INPUT * pAddr - Destination of the interface route being deleted * refCnt - How many more references to this route exist * subnetsCnt- How many subnetted interfaces exist for this network * internalFlag-Should an internal or a regular interface route be added * subnetMask- Mask associated with the route being deleted * * NOMANUAL * * NOTE: INTERNET SPECIFIC. */void ifRouteAdd ( struct sockaddr * pAddr, int refCnt, int subnetsCnt, BOOL internalFlag, u_long subnetMask ) { register struct interface *ifp = 0; register struct interface *pPPPIfp = 0; register struct interface *pNetIfp = 0; register struct interface *pSubnetIfp = 0; register struct interface *pIfMax; register int af = pAddr->sa_family; register u_long dstaddr; int addLocalRoute = 0; int addDstRoute = 0; int state; struct rt_entry *rt; if (af >= AF_MAX) return; pIfMax = 0; dstaddr = ntohl (((struct sockaddr_in *)pAddr)->sin_addr.s_addr); /* * If we need to add an "internal" route (a classful route for a * subnetted network - to be used for border gateway filtering) * Look for a list of subnetted interfaces that are on the same network * as the current route, and add a class based network route through * the interface that has the least metric */ if (internalFlag) { for (ifp = ripIfNet; ifp; ifp = ifp->int_next) { if (ifp->int_flags & IFF_REMOTE || !(ifp->int_flags & IFF_UP) || ifp->int_flags & IFF_POINTOPOINT) continue; if (af != ifp->int_addr.sa_family) continue; if ((ifp->int_netmask != ifp->int_subnetmask) && (dstaddr == ifp->int_net)) { if (!pSubnetIfp || pSubnetIfp->int_metric > ifp->int_metric) pSubnetIfp = ifp; if (routedDebug > 2) { logMsg ("internalFlag: found ifp = %x\n", (int)pSubnetIfp, 0, 0, 0, 0, 0); _ripIfShow (pSubnetIfp); } } } ifp = pSubnetIfp; } else { for (ifp = ripIfNet; ifp; ifp = ifp->int_next) { if (ifp->int_flags & IFF_REMOTE || !(ifp->int_flags & IFF_UP)) continue; if (af != ifp->int_addr.sa_family) continue; /* See if the address matches any end of the PPP links */ if ((ifp->int_flags & IFF_POINTOPOINT)) { if (same (&ifp->int_dstaddr, pAddr) || same (&ifp->int_addr, pAddr)) { if (!pPPPIfp || pPPPIfp->int_metric > ifp->int_metric) pPPPIfp = ifp; if (routedDebug > 2) { logMsg ("PPP: found ifp = %x\n", (int)pPPPIfp, 0, 0, 0, 0, 0); _ripIfShow (pPPPIfp); } } } /* * It would seem that the two else if cases below could be * replaced with a single if (dstaddr == ifp->int_subnet) * but the above case will not be able to distinguish between * 164.10.0.0/16 and 164.10.0.0/24. Hence we need to * compare separately */ else if ((ifp->int_netmask == ifp->int_subnetmask) && (dstaddr == ifp->int_net)) { if (!pNetIfp || pNetIfp->int_metric > ifp->int_metric) pNetIfp = ifp; if (routedDebug > 2) { logMsg ("NET: found ifp = %x\n", (int)pNetIfp, 0, 0, 0, 0, 0); _ripIfShow (pNetIfp); } } else if ((ifp->int_netmask != ifp->int_subnetmask) && (dstaddr == ifp->int_subnet)) { if (!pSubnetIfp || pSubnetIfp->int_metric > ifp->int_metric) pSubnetIfp = ifp; if (routedDebug > 2) { logMsg ("SUBNET: found ifp = %x\n", (int)pSubnetIfp, 0, 0, 0, 0, 0); _ripIfShow (pSubnetIfp); } } } ifp = pPPPIfp ? pPPPIfp : (pNetIfp ? pNetIfp : pSubnetIfp); if (ifp == NULL) { /* * We did not find any interface that matched the address of the * route being deleted. This must be the following case: * 164.10.0.0/16 --> 164.10.1.1 (being deleted) * is referenced by the following PPP interface * src = 164.10.22.1, dst=164.10.22.2 * So now, search for PPP interfaces that lie on the same * network as the route being deleted. We do that by applying the * netmask of the route to the PPP interface address. * If we have both ends of the link on the same network, then we * will have to add two routes: * one for the remote end. * one for the local end */ pAddr = NULL; for (ifp = ripIfNet; ifp; ifp = ifp->int_next) { if (ifp->int_flags & IFF_REMOTE || !(ifp->int_flags & IFF_UP)) continue; if (af != ifp->int_addr.sa_family) continue; if ((ifp->int_flags & IFF_POINTOPOINT)) { if ((ntohl(((struct sockaddr_in *) &ifp->int_dstaddr)->sin_addr.s_addr) & subnetMask) == dstaddr) { addDstRoute = 1; if (routedDebug > 2) { logMsg ("Add PPP dest route for %x.\n", (int)ifp, 0, 0, 0, 0, 0); _ripIfShow (ifp); } if (!pPPPIfp || pPPPIfp->int_metric > ifp->int_metric) pPPPIfp = ifp; pAddr = &ifp->int_dstaddr; } if ((ntohl(((struct sockaddr_in *) &ifp->int_addr)->sin_addr.s_addr) & subnetMask) == dstaddr) { addLocalRoute = 1; if (routedDebug > 2) { logMsg ("Add PPP local route for %x.\n", (int)ifp, 0, 0, 0, 0, 0); _ripIfShow (ifp); } if (!pPPPIfp || pPPPIfp->int_metric > ifp->int_metric) pPPPIfp = ifp; break; } } } ifp = pPPPIfp; } } if (ifp == NULL) { if (routedDebug > 2) logMsg ("No ifp found\n", 0, 0, 0, 0, 0, 0); return; } /* * If both the local and remote end were on the same network, we had * incremented the refcount by 2 when we added the route. So account * for that. rtdelete() had already decremented the refcount by 1 */ if (addDstRoute && addLocalRoute) refCnt--; /* * pAddr will be set to NULL if we just need to add a route to the * local end of the PPP link. In all other cases, add the route */ if (pAddr) { state = ifp->int_flags & (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET); if (ifp->int_flags & IFF_POINTOPOINT && (same (&ifp->int_dstaddr, pAddr)) && (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) & ifp->int_netmask) != ifp->int_net) state &= ~RTS_SUBNET; if (internalFlag) rt = rtadd(pAddr, &ifp->int_addr, ifp->int_metric, ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET), NULL, M2_ipRouteProto_rip, 0, 0, ifp); else rt = rtadd(pAddr, &ifp->int_addr, ifp->int_metric, state, NULL, M2_ipRouteProto_rip, 0, 0, ifp); /* * Now set the reference counts. */ if (rt) { rt->rt_refcnt = refCnt; rt->rt_subnets_cnt = subnetsCnt; } } /* Now add route to the local end of PPP link, if needed */ if (addLocalRoute) add_ptopt_localrt(ifp, refCnt); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -