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