-struct ifnet *ifnet;
-/*
- * Find the network interfaces attached to this machine.
- * The info is used to:
- *
- * (1) initialize the routing tables, as done by the kernel.
- * (2) ignore incoming packets we send.
- * (3) figure out broadcast capability and addresses.
- * (4) figure out if we're an internetwork gateway.
- *
- * We don't handle anything but Internet addresses.
- *
- * Note: this routine may be called periodically to
- * scan for new interfaces. In fact, the timer routine
- * does so based on the flag lookforinterfaces. The
- * flag performnlist is set whenever something odd occurs
- * while scanning the kernel; this is likely to occur
- * if /vmunix isn't up to date (e.g. someone booted /ovmunix).
- */
-getinterfaces()
-{
- struct ifnet *ifp;
- struct ifnet ifstruct, *next;
- struct sockaddr_in net;
- register struct sockaddr *dst;
- int nets;
-
- if (performnlist) {
- nlist("/vmunix", nl);
- if (nl[N_IFNET].n_value == 0) {
- performnlist++;
- printf("ifnet: not in namelist\n");
- return;
- }
- performnlist = 0;
- }
- if (kmem < 0) {
- kmem = open("/dev/kmem", 0);
- if (kmem < 0) {
- perror("/dev/kmem");
- return;
- }
- }
- if (lseek(kmem, (long)nl[N_IFNET].n_value, 0) == -1 ||
- read(kmem, (char *)&ifp, sizeof (ifp)) != sizeof (ifp)) {
- performnlist = 1;
- return;
- }
- bzero((char *)&net, sizeof (net));
- net.sin_family = AF_INET;
- lookforinterfaces = 0;
- nets = 0;
- while (ifp) {
- if (lseek(kmem, (long)ifp, 0) == -1 ||
- read(kmem, (char *)&ifstruct, sizeof (ifstruct)) !=
- sizeof (ifstruct)) {
- perror("read");
- lookforinterfaces = performnlist = 1;
- break;
- }
- ifp = &ifstruct;
- if ((ifp->if_flags & IFF_UP) == 0) {
- lookforinterfaces = 1;
- skip:
- ifp = ifp->if_next;
- continue;
- }
- if (ifp->if_addr.sa_family != AF_INET)
- goto skip;
- /* ignore software loopback networks. */
- if (ifp->if_net == LOOPBACKNET)
- goto skip;
- /* check if we already know about this one */
- if (if_ifwithaddr(&ifstruct.if_addr)) {
- nets++;
- goto skip;
- }
- ifp = (struct ifnet *)malloc(sizeof (struct ifnet));
- if (ifp == 0) {
- printf("routed: out of memory\n");
- break;
- }
- bcopy((char *)&ifstruct, (char *)ifp, sizeof (struct ifnet));
-
- /*
- * 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 ((ifp->if_flags & IFF_POINTOPOINT) == 0 ||
- if_ifwithaddr(&ifp->if_dstaddr) == 0)
- nets++;
-
- if (ifp->if_flags & IFF_POINTOPOINT)
- dst = &ifp->if_dstaddr;
- else {
- net.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY);
- dst = (struct sockaddr *)&net;
- }
- next = ifp->if_next;
- ifp->if_next = ifnet;
- ifnet = ifp;
- if (rtlookup(dst) == 0)
- rtadd(dst, &ifp->if_addr, 0);
- ifp = next;
- }
- supplier = nets > 1;
-}
-
-/*
- * Send a request message to all directly
- * connected hosts and networks.
- */
-request()
-{
- register struct rip *msg = (struct rip *)packet;
-
- msg->rip_cmd = RIPCMD_REQUEST;
- msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
- msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
- sendall();
-}
-
-/*
- * Broadcast a new, or modified, routing table entry
- * to all directly connected hosts and networks.
- */
-broadcast(entry)
- struct rt_entry *entry;
-{
- struct rip *msg = (struct rip *)packet;
-
- log("broadcast", entry);
- msg->rip_cmd = RIPCMD_RESPONSE;
- msg->rip_nets[0].rip_dst = entry->rt_dst;
- msg->rip_nets[0].rip_metric = min(entry->rt_metric+1, HOPCNT_INFINITY);
- sendall();
-}
-
-/*
- * Send "packet" to all neighbors.
- */
-sendall()