|
|
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.