|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * Includes material written at Cornell University by Bill Nesheim, ! 7: * by permission of the author. ! 8: */ ! 9: ! 10: ! 11: #ifndef lint ! 12: static char sccsid[] = "@(#)input.c 5.6 (Berkeley) 2/14/86"; ! 13: #endif not lint ! 14: ! 15: /* ! 16: * XNS Routing Table Management Daemon ! 17: */ ! 18: #include "defs.h" ! 19: ! 20: struct sockaddr * ! 21: xns_nettosa(net) ! 22: union ns_net net; ! 23: { ! 24: static struct sockaddr_ns sxn; ! 25: extern char ether_broadcast_addr[6]; ! 26: ! 27: bzero(&sxn, sizeof (struct sockaddr_ns)); ! 28: sxn.sns_family = AF_NS; ! 29: sxn.sns_addr.x_net = net; ! 30: sxn.sns_addr.x_host = *(union ns_host *)ether_broadcast_addr; ! 31: return( (struct sockaddr *)&sxn); ! 32: ! 33: } ! 34: ! 35: /* ! 36: * Process a newly received packet. ! 37: */ ! 38: rip_input(from, size) ! 39: struct sockaddr *from; ! 40: int size; ! 41: { ! 42: struct rt_entry *rt; ! 43: struct netinfo *n; ! 44: struct interface *ifp; ! 45: int newsize; ! 46: struct afswitch *afp; ! 47: ! 48: ! 49: ifp = 0; ! 50: TRACE_INPUT(ifp, from, size); ! 51: if (from->sa_family >= AF_MAX) ! 52: return; ! 53: afp = &afswitch[from->sa_family]; ! 54: ! 55: size -= sizeof (u_short) /* command */; ! 56: n = msg->rip_nets; ! 57: ! 58: switch (ntohs(msg->rip_cmd)) { ! 59: ! 60: case RIPCMD_REQUEST: ! 61: newsize = 0; ! 62: while (size > 0) { ! 63: if (size < sizeof (struct netinfo)) ! 64: break; ! 65: size -= sizeof (struct netinfo); ! 66: ! 67: /* ! 68: * A single entry with rip_dst == DSTNETS_ALL and ! 69: * metric ``infinity'' means ``all routes''. ! 70: */ ! 71: if (ns_neteqnn(n->rip_dst, ns_anynet) && ! 72: ntohs(n->rip_metric) == HOPCNT_INFINITY && ! 73: size == 0) { ! 74: ifp = if_ifwithnet(from); ! 75: supply(from, 0, ifp); ! 76: return; ! 77: } ! 78: /* ! 79: * request for specific nets ! 80: */ ! 81: rt = rtlookup(xns_nettosa(n->rip_dst)); ! 82: if (ftrace) { ! 83: fprintf(ftrace, ! 84: "specific request for %s", ! 85: xns_nettoa(n->rip_dst)); ! 86: fprintf(ftrace, ! 87: " yields route %x\n", ! 88: rt); ! 89: } ! 90: n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY : ! 91: min(rt->rt_metric+1, HOPCNT_INFINITY)); ! 92: n++; ! 93: newsize += sizeof (struct netinfo); ! 94: } ! 95: if (newsize > 0) { ! 96: msg->rip_cmd = htons(RIPCMD_RESPONSE); ! 97: newsize += sizeof (u_short); ! 98: /* should check for if with dstaddr(from) first */ ! 99: (*afp->af_output)(0, from, newsize); ! 100: ifp = if_ifwithnet(from); ! 101: TRACE_OUTPUT(ifp, from, newsize); ! 102: if (ftrace) { ! 103: fprintf(ftrace, ! 104: "request arrived on interface %s\n", ! 105: ifp->int_name); ! 106: } ! 107: } ! 108: return; ! 109: ! 110: case RIPCMD_RESPONSE: ! 111: /* verify message came from a router */ ! 112: if ((*afp->af_portmatch)(from) == 0) ! 113: return; ! 114: (*afp->af_canon)(from); ! 115: /* are we talking to ourselves? */ ! 116: if (ifp = if_ifwithaddr(from)) { ! 117: rt = rtfind(from); ! 118: if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0) ! 119: addrouteforif(ifp); ! 120: else ! 121: rt->rt_timer = 0; ! 122: return; ! 123: } ! 124: /* Update timer for interface on which the packet arrived. ! 125: * If from other end of a point-to-point link that isn't ! 126: * in the routing tables, (re-)add the route. ! 127: */ ! 128: if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE)) { ! 129: if(ftrace) fprintf(ftrace, "Got route\n"); ! 130: rt->rt_timer = 0; ! 131: } else if (ifp = if_ifwithdstaddr(from)) { ! 132: if(ftrace) fprintf(ftrace, "Got partner\n"); ! 133: addrouteforif(ifp); ! 134: } ! 135: for (; size > 0; size -= sizeof (struct netinfo), n++) { ! 136: struct sockaddr *sa; ! 137: if (size < sizeof (struct netinfo)) ! 138: break; ! 139: if ((unsigned) ntohs(n->rip_metric) >= HOPCNT_INFINITY) ! 140: continue; ! 141: rt = rtfind(sa = xns_nettosa(n->rip_dst)); ! 142: if (rt == 0) { ! 143: rtadd(sa, from, ntohs(n->rip_metric), 0); ! 144: continue; ! 145: } ! 146: ! 147: /* ! 148: * Update if from gateway and different, ! 149: * from anywhere and shorter, or getting stale and equivalent. ! 150: */ ! 151: if ((equal(from, &rt->rt_router) && ! 152: ntohs(n->rip_metric) != rt->rt_metric ) || ! 153: (unsigned) ntohs(n->rip_metric) < rt->rt_metric || ! 154: (rt->rt_timer > (EXPIRE_TIME/2) && ! 155: rt->rt_metric == ntohs(n->rip_metric))) { ! 156: rtchange(rt, from, ntohs(n->rip_metric)); ! 157: rt->rt_timer = 0; ! 158: } ! 159: } ! 160: return; ! 161: } ! 162: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.