|
|
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: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)output.c 5.14 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * Routing Table Management Daemon
26: */
27: #include "defs.h"
28:
29: /*
30: * Apply the function "f" to all non-passive
31: * interfaces. If the interface supports the
32: * use of broadcasting use it, otherwise address
33: * the output to the known router.
34: */
35: toall(f, rtstate, skipif)
36: int (*f)();
37: int rtstate;
38: struct interface *skipif;
39: {
40: register struct interface *ifp;
41: register struct sockaddr *dst;
42: register int flags;
43: extern struct interface *ifnet;
44:
45: for (ifp = ifnet; ifp; ifp = ifp->int_next) {
46: if (ifp->int_flags & IFF_PASSIVE || ifp == skipif)
47: continue;
48: dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
49: ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
50: &ifp->int_addr;
51: flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
52: (*f)(dst, flags, ifp, rtstate);
53: }
54: }
55:
56: /*
57: * Output a preformed packet.
58: */
59: /*ARGSUSED*/
60: sendmsg(dst, flags, ifp, rtstate)
61: struct sockaddr *dst;
62: int flags;
63: struct interface *ifp;
64: int rtstate;
65: {
66:
67: (*afswitch[dst->sa_family].af_output)(s, flags,
68: dst, sizeof (struct rip));
69: TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
70: }
71:
72: /*
73: * Supply dst with the contents of the routing tables.
74: * If this won't fit in one packet, chop it up into several.
75: */
76: supply(dst, flags, ifp, rtstate)
77: struct sockaddr *dst;
78: int flags;
79: register struct interface *ifp;
80: int rtstate;
81: {
82: register struct rt_entry *rt;
83: register struct netinfo *n = msg->rip_nets;
84: register struct rthash *rh;
85: struct rthash *base = hosthash;
86: int doinghost = 1, size;
87: int (*output)() = afswitch[dst->sa_family].af_output;
88: int (*sendroute)() = afswitch[dst->sa_family].af_sendroute;
89: int npackets = 0;
90:
91: msg->rip_cmd = RIPCMD_RESPONSE;
92: msg->rip_vers = RIPVERSION;
93: bzero(msg->rip_res1, sizeof(msg->rip_res1));
94: again:
95: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
96: for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
97: /*
98: * Don't resend the information on the network
99: * from which it was received (unless sending
100: * in response to a query).
101: */
102: if (ifp && rt->rt_ifp == ifp &&
103: (rt->rt_state & RTS_INTERFACE) == 0)
104: continue;
105: if (rt->rt_state & RTS_EXTERNAL)
106: continue;
107: /*
108: * For dynamic updates, limit update to routes
109: * with the specified state.
110: */
111: if (rtstate && (rt->rt_state & rtstate) == 0)
112: continue;
113: /*
114: * Limit the spread of subnet information
115: * to those who are interested.
116: */
117: if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
118: if (rt->rt_dst.sa_family != dst->sa_family)
119: continue;
120: if ((*sendroute)(rt, dst) == 0)
121: continue;
122: }
123: size = (char *)n - packet;
124: if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
125: TRACE_OUTPUT(ifp, dst, size);
126: (*output)(s, flags, dst, size);
127: /*
128: * If only sending to ourselves,
129: * one packet is enough to monitor interface.
130: */
131: if (ifp && (ifp->int_flags &
132: (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0)
133: return;
134: n = msg->rip_nets;
135: npackets++;
136: }
137: n->rip_dst = rt->rt_dst;
138: #if BSD < 198810
139: if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */
140: n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
141: #else
142: #define osa(x) ((struct osockaddr *)(&(x)))
143: osa(n->rip_dst)->sa_family = htons(n->rip_dst.sa_family);
144: #endif
145: n->rip_metric = htonl(rt->rt_metric);
146: n++;
147: }
148: if (doinghost) {
149: doinghost = 0;
150: base = nethash;
151: goto again;
152: }
153: if (n != msg->rip_nets || (npackets == 0 && rtstate == 0)) {
154: size = (char *)n - packet;
155: TRACE_OUTPUT(ifp, dst, size);
156: (*output)(s, flags, dst, size);
157: }
158: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.