124328Ssklower /* 224328Ssklower * Copyright (c) 1985 Regents of the University of California. 324328Ssklower * All rights reserved. The Berkeley software License Agreement 424328Ssklower * specifies the terms and conditions for redistribution. 524328Ssklower * 624328Ssklower * Includes material written at Cornell University by Bill Nesheim, 724328Ssklower * by permission of the author. 824328Ssklower */ 924328Ssklower 1024328Ssklower 1124307Ssklower #ifndef lint 12*24875Ssklower static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 09/17/85"; 1324328Ssklower #endif not lint 1424307Ssklower 1524307Ssklower /* 1624307Ssklower * XNS Routing Table Management Daemon 1724307Ssklower */ 1824307Ssklower #include "defs.h" 1924307Ssklower 2024307Ssklower struct sockaddr * 2124307Ssklower xns_nettosa(net) 2224307Ssklower u_short *net; 2324307Ssklower { 2424317Ssklower static struct sockaddr_ns sxn; 2524317Ssklower extern char ether_broadcast_addr[6]; 2624307Ssklower 2724317Ssklower bzero(&sxn, sizeof (struct sockaddr_ns)); 2824317Ssklower sxn.sns_family = AF_NS; 2924317Ssklower xnnet(sxn.sns_addr.x_net) = xnnet(net[0]); 3024317Ssklower sxn.sns_addr.x_host = *(union ns_host *)ether_broadcast_addr; 3124307Ssklower return( (struct sockaddr *)&sxn); 3224307Ssklower 3324307Ssklower } 3424307Ssklower 3524307Ssklower /* 3624307Ssklower * Process a newly received packet. 3724307Ssklower */ 3824307Ssklower rip_input(from, size) 3924307Ssklower struct sockaddr *from; 4024307Ssklower int size; 4124307Ssklower { 4224307Ssklower struct rt_entry *rt; 4324307Ssklower struct netinfo *n; 4424307Ssklower struct interface *ifp; 4524307Ssklower int newsize; 4624307Ssklower struct afswitch *afp; 4724307Ssklower 4824307Ssklower 4924317Ssklower ifp = 0; 5024307Ssklower TRACE_INPUT(ifp, from, size); 5124307Ssklower if (from->sa_family >= AF_MAX) 5224307Ssklower return; 5324307Ssklower afp = &afswitch[from->sa_family]; 5424307Ssklower 5524307Ssklower size -= sizeof (u_short) /* command */; 5624307Ssklower n = msg->rip_nets; 5724307Ssklower 5824307Ssklower switch (ntohs(msg->rip_cmd)) { 5924307Ssklower 6024307Ssklower case RIPCMD_REQUEST: 6124307Ssklower newsize = 0; 6224307Ssklower while (size > 0) { 6324307Ssklower if (size < sizeof (struct netinfo)) 6424307Ssklower break; 6524307Ssklower size -= sizeof (struct netinfo); 6624307Ssklower 6724307Ssklower /* 6824307Ssklower * A single entry with rip_dst == DSTNETS_ALL and 6924307Ssklower * metric ``infinity'' means ``all routes''. 7024307Ssklower */ 7124317Ssklower if (ntohl(xnnet(n->rip_dst[0])) == DSTNETS_ALL && 7224317Ssklower ntohs(n->rip_metric) == HOPCNT_INFINITY && 7324317Ssklower size == 0) { 7424317Ssklower ifp = if_ifwithnet(from); 7524317Ssklower supply(from, 0, ifp); 7624307Ssklower return; 7724307Ssklower } 7824307Ssklower /* 7924307Ssklower * request for specific nets 8024307Ssklower */ 8124307Ssklower rt = rtlookup(xns_nettosa(n->rip_dst)); 82*24875Ssklower if (ftrace) { 8324328Ssklower fprintf(ftrace, 8424328Ssklower "specific request for %d", 8524328Ssklower ntohl(xnnet(n->rip_dst[0]))); 8624328Ssklower fprintf(ftrace, 8724328Ssklower "yields route %x", 8824328Ssklower rt); 8924328Ssklower } 9024307Ssklower n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY : 9124307Ssklower min(rt->rt_metric+1, HOPCNT_INFINITY)); 9224307Ssklower n++, newsize += sizeof (struct netinfo); 9324307Ssklower } 9424307Ssklower if (newsize > 0) { 9524307Ssklower msg->rip_cmd = htons(RIPCMD_RESPONSE); 9624307Ssklower newsize += sizeof (u_short); 9724307Ssklower /* should check for if with dstaddr(from) first */ 98*24875Ssklower (*afp->af_output)(0, from, newsize); 9924328Ssklower (ifp = if_ifwithnet(from)); 100*24875Ssklower if (ftrace) { 10124328Ssklower fprintf(ftrace, 10224328Ssklower ", request arriving on interface %x\n", 10324328Ssklower ifp); 10424328Ssklower } 10524307Ssklower } 10624307Ssklower return; 10724307Ssklower 10824307Ssklower case RIPCMD_RESPONSE: 10924307Ssklower /* verify message came from a router */ 11024307Ssklower if ((*afp->af_portmatch)(from) == 0) 11124307Ssklower return; 11224317Ssklower (*afp->af_canon)(from); 11324317Ssklower /* are we talking to ourselves? */ 11424317Ssklower if (ifp = if_ifwithaddr(from)) { 11524317Ssklower rt = rtfind(from); 11624317Ssklower if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0) 11724317Ssklower addrouteforif(ifp); 11824317Ssklower else 11924317Ssklower rt->rt_timer = 0; 12024317Ssklower return; 12124317Ssklower } 12224328Ssklower /* Update timer for interface on which the packet arrived. 12324328Ssklower * If from other end of a point-to-point link that isn't 12424328Ssklower * in the routing tables, (re-)add the route. 12524328Ssklower */ 12624328Ssklower if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE)) { 127*24875Ssklower if(ftrace) fprintf(ftrace, "Got route\n"); 12824307Ssklower rt->rt_timer = 0; 12924328Ssklower } else if (ifp = if_ifwithdstaddr(from)) { 130*24875Ssklower if(ftrace) fprintf(ftrace, "Got partner\n"); 13124328Ssklower addrouteforif(ifp); 13224328Ssklower } 13324307Ssklower for (; size > 0; size -= sizeof (struct netinfo), n++) { 13424328Ssklower struct sockaddr *sa; 13524307Ssklower if (size < sizeof (struct netinfo)) 13624307Ssklower break; 13724307Ssklower if ((unsigned) ntohs(n->rip_metric) > HOPCNT_INFINITY) 13824307Ssklower continue; 13924328Ssklower rt = rtfind(sa = xns_nettosa(n->rip_dst)); 14024307Ssklower if (rt == 0) { 14124328Ssklower rtadd(sa, from, ntohs(n->rip_metric), 0); 14224307Ssklower continue; 14324307Ssklower } 14424307Ssklower 14524307Ssklower /* 14624307Ssklower * Update if from gateway and different, 14724307Ssklower * from anywhere and shorter, or getting stale and equivalent. 14824307Ssklower */ 14924307Ssklower if ((equal(from, &rt->rt_router) && 15024307Ssklower ntohs(n->rip_metric) != rt->rt_metric ) || 15124307Ssklower (unsigned) ntohs(n->rip_metric) < rt->rt_metric || 15224307Ssklower (rt->rt_timer > (EXPIRE_TIME/2) && 15324307Ssklower rt->rt_metric == ntohs(n->rip_metric))) { 15424307Ssklower rtchange(rt, from, ntohs(n->rip_metric)); 15524307Ssklower rt->rt_timer = 0; 15624307Ssklower } 15724307Ssklower } 15824307Ssklower return; 15924307Ssklower } 16024307Ssklower } 161