|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that this notice is preserved and that due credit is given
7: * to the University of California at Berkeley. The name of the University
8: * may not be used to endorse or promote products derived from this
9: * software without specific prior written permission. This software
10: * is provided ``as is'' without express or implied warranty.
11: */
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)output.c 5.10 (Berkeley) 5/31/88";
15: #endif /* not lint */
16:
17: /*
18: * Routing Table Management Daemon
19: */
20: #include "defs.h"
21:
22: /*
23: * Apply the function "f" to all non-passive
24: * interfaces. If the interface supports the
25: * use of broadcasting use it, otherwise address
26: * the output to the known router.
27: */
28: toall(f)
29: int (*f)();
30: {
31: register struct interface *ifp;
32: register struct sockaddr *dst;
33: register int flags;
34: extern struct interface *ifnet;
35:
36: for (ifp = ifnet; ifp; ifp = ifp->int_next) {
37: if (ifp->int_flags & IFF_PASSIVE)
38: continue;
39: dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
40: ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
41: &ifp->int_addr;
42: flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
43: (*f)(dst, flags, ifp);
44: }
45: }
46:
47: /*
48: * Output a preformed packet.
49: */
50: /*ARGSUSED*/
51: sendmsg(dst, flags, ifp)
52: struct sockaddr *dst;
53: int flags;
54: struct interface *ifp;
55: {
56:
57: (*afswitch[dst->sa_family].af_output)(s, flags,
58: dst, sizeof (struct rip));
59: TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
60: }
61:
62: /*
63: * Supply dst with the contents of the routing tables.
64: * If this won't fit in one packet, chop it up into several.
65: */
66: supply(dst, flags, ifp)
67: struct sockaddr *dst;
68: int flags;
69: register struct interface *ifp;
70: {
71: register struct rt_entry *rt;
72: register struct netinfo *n = msg->rip_nets;
73: register struct rthash *rh;
74: struct rthash *base = hosthash;
75: int doinghost = 1, size;
76: int (*output)() = afswitch[dst->sa_family].af_output;
77: int (*sendroute)() = afswitch[dst->sa_family].af_sendroute;
78: int npackets = 0;
79:
80: msg->rip_cmd = RIPCMD_RESPONSE;
81: msg->rip_vers = RIPVERSION;
82: bzero(msg->rip_res1, sizeof(msg->rip_res1));
83: again:
84: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
85: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
86: /*
87: * Don't resend the information on the network
88: * from which it was received (unless sending
89: * in response to a query).
90: */
91: if (ifp && rt->rt_ifp == ifp &&
92: (rt->rt_state & RTS_INTERFACE) == 0)
93: continue;
94: if (rt->rt_state & RTS_EXTERNAL)
95: continue;
96: /*
97: * Limit the spread of subnet information
98: * to those who are interested.
99: */
100: if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
101: if (rt->rt_dst.sa_family != dst->sa_family)
102: continue;
103: if ((*sendroute)(rt, dst) == 0)
104: continue;
105: }
106: size = (char *)n - packet;
107: if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
108: (*output)(s, flags, dst, size);
109: TRACE_OUTPUT(ifp, dst, size);
110: /*
111: * If only sending to ourselves,
112: * one packet is enough to monitor interface.
113: */
114: if ((ifp->int_flags &
115: (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0)
116: return;
117: n = msg->rip_nets;
118: npackets++;
119: }
120: n->rip_dst = rt->rt_dst;
121: n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
122: n->rip_metric = htonl(rt->rt_metric);
123: n++;
124: }
125: if (doinghost) {
126: doinghost = 0;
127: base = nethash;
128: goto again;
129: }
130: if (n != msg->rip_nets || npackets == 0) {
131: size = (char *)n - packet;
132: (*output)(s, flags, dst, size);
133: TRACE_OUTPUT(ifp, dst, size);
134: }
135: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.