|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)input.c 4.5 (Berkeley) 6/1/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Routing Table Management Daemon ! 7: */ ! 8: #include "defs.h" ! 9: ! 10: /* ! 11: * Process a newly received packet. ! 12: */ ! 13: rip_input(from, size) ! 14: struct sockaddr *from; ! 15: int size; ! 16: { ! 17: struct rt_entry *rt; ! 18: struct netinfo *n; ! 19: struct interface *ifp; ! 20: int newsize; ! 21: struct afswitch *afp; ! 22: ! 23: ifp = 0; ! 24: TRACE_INPUT(ifp, from, size); ! 25: if (from->sa_family >= AF_MAX) ! 26: return; ! 27: afp = &afswitch[from->sa_family]; ! 28: switch (msg->rip_cmd) { ! 29: ! 30: case RIPCMD_REQUEST: ! 31: newsize = 0; ! 32: size -= 4 * sizeof (char); ! 33: n = msg->rip_nets; ! 34: while (size > 0) { ! 35: if (size < sizeof (struct netinfo)) ! 36: break; ! 37: size -= sizeof (struct netinfo); ! 38: ! 39: if (msg->rip_vers > 0) { ! 40: n->rip_dst.sa_family = ! 41: ntohs(n->rip_dst.sa_family); ! 42: n->rip_metric = ntohl(n->rip_metric); ! 43: } ! 44: /* ! 45: * A single entry with sa_family == AF_UNSPEC and ! 46: * metric ``infinity'' means ``all routes''. ! 47: */ ! 48: if (n->rip_dst.sa_family == AF_UNSPEC && ! 49: n->rip_metric == HOPCNT_INFINITY && size == 0) { ! 50: supply(from, 0, ifp); ! 51: return; ! 52: } ! 53: rt = rtlookup(&n->rip_dst); ! 54: n->rip_metric = rt == 0 ? HOPCNT_INFINITY : ! 55: min(rt->rt_metric+1, HOPCNT_INFINITY); ! 56: if (msg->rip_vers > 0) { ! 57: n->rip_dst.sa_family = ! 58: htons(n->rip_dst.sa_family); ! 59: n->rip_metric = htonl(n->rip_metric); ! 60: } ! 61: n++, newsize += sizeof (struct netinfo); ! 62: } ! 63: if (newsize > 0) { ! 64: msg->rip_cmd = RIPCMD_RESPONSE; ! 65: newsize += sizeof (int); ! 66: (*afp->af_output)(s, 0, from, newsize); ! 67: } ! 68: return; ! 69: ! 70: case RIPCMD_TRACEON: ! 71: case RIPCMD_TRACEOFF: ! 72: /* verify message came from a priviledged port */ ! 73: if ((*afp->af_portcheck)(from) == 0) ! 74: return; ! 75: packet[size] = '\0'; ! 76: if (msg->rip_cmd == RIPCMD_TRACEON) ! 77: traceon(msg->rip_tracefile); ! 78: else ! 79: traceoff(); ! 80: return; ! 81: ! 82: case RIPCMD_RESPONSE: ! 83: /* verify message came from a router */ ! 84: if ((*afp->af_portmatch)(from) == 0) ! 85: return; ! 86: (*afp->af_canon)(from); ! 87: /* are we talking to ourselves? */ ! 88: ifp = if_ifwithaddr(from); ! 89: if (ifp) { ! 90: rt = rtfind(from); ! 91: if (rt == 0) ! 92: addrouteforif(ifp); ! 93: else ! 94: rt->rt_timer = 0; ! 95: return; ! 96: } ! 97: size -= 4 * sizeof (char); ! 98: n = msg->rip_nets; ! 99: for (; size > 0; size -= sizeof (struct netinfo), n++) { ! 100: if (size < sizeof (struct netinfo)) ! 101: break; ! 102: if (msg->rip_vers > 0) { ! 103: n->rip_dst.sa_family = ! 104: ntohs(n->rip_dst.sa_family); ! 105: n->rip_metric = ntohl(n->rip_metric); ! 106: } ! 107: if (n->rip_metric >= HOPCNT_INFINITY) ! 108: continue; ! 109: rt = rtlookup(&n->rip_dst); ! 110: if (rt == 0) { ! 111: rtadd(&n->rip_dst, from, n->rip_metric, 0); ! 112: continue; ! 113: } ! 114: ! 115: /* ! 116: * Update if from gateway, shorter, or getting ! 117: * stale and equivalent. ! 118: */ ! 119: if (equal(from, &rt->rt_router) || ! 120: n->rip_metric < rt->rt_metric || ! 121: (rt->rt_timer > (EXPIRE_TIME/2) && ! 122: rt->rt_metric == n->rip_metric)) { ! 123: rtchange(rt, from, n->rip_metric); ! 124: rt->rt_timer = 0; ! 125: } ! 126: } ! 127: return; ! 128: } ! 129: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.