📄 startup.c
字号:
{ ripState.lookforinterfaces = TRUE; continue; } /* Store the remote address for the link in the correct place. */ ifs.int_dstaddr = *BRDADDR; } /* * Skip duplicate address entries already available with another * interface. This test allows multiple point-to-point links * to share a source address (possibly with one other link), but * assumes that each link has a separate destination address. */ if (ifs.int_flags & IFF_POINTOPOINT) { if (ripIfWithDstAddr (&ifs.int_dstaddr)) continue; } else if (ripIfWithAddr (&ifs.int_addr)) 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); } /* 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", 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", 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); /* 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)); 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 (ripState.externalinterfaces > 1 && ripState.supplier < 0) ripState.supplier = 1; free (buf); splx (splLevel); 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; if (ifp->int_flags & IFF_POINTOPOINT) dst = &ifp->int_dstaddr; else { memset(&net, 0, sizeof (net)); net.sin_family = AF_INET; net.sin_addr.s_addr = htonl (ifp->int_subnet); dst = (struct sockaddr *)&net; } rt = rtfind(dst); if (rt) { if (ifp->int_flags & IFF_POINTOPOINT) return; if ((rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE) { if (ntohl (rt->rt_ifp->int_subnetmask) == ifp->int_subnetmask) return; } else 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); rt = rtfind(dst); if (rt == 0) rtadd(dst, &ifp->int_addr, ifp->int_metric, ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET), NULL); else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == (RTS_INTERNAL|RTS_SUBNET) && ifp->int_metric < rt->rt_metric) rtchange(rt, &rt->rt_router, ifp->int_metric, NULL); net.sin_addr = subnet; } if (ifp->int_transitions++ > 0) if (routedDebug) logMsg ("Warning! Re-installing route for interface %s.\n", 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; rtadd(dst, &ifp->int_addr, ifp->int_metric, state, NULL); if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) add_ptopt_localrt(ifp);}/* * 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) register struct interface *ifp;{ struct rt_entry *rt; struct sockaddr *dst; struct sockaddr_in net; int state; state = RTS_INTERFACE | RTS_PASSIVE; /* look for route to logical network */ memset(&net, 0, sizeof (net)); net.sin_family = AF_INET; net.sin_addr.s_addr = htonl (ifp->int_net); dst = (struct sockaddr *)&net; 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) return (ERROR); rtdelete(rt); } rtadd(dst, &loopaddr, 1, state, NULL); return (OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -