Commit | Line | Data |
---|---|---|
5ff67f98 DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
0eb85d71 KB |
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. | |
5ff67f98 DF |
11 | */ |
12 | ||
7e7de0c9 | 13 | #ifndef lint |
0eb85d71 KB |
14 | static char sccsid[] = "@(#)output.c 5.9 (Berkeley) %G%"; |
15 | #endif /* not lint */ | |
7e7de0c9 SL |
16 | |
17 | /* | |
18 | * Routing Table Management Daemon | |
19 | */ | |
7fe7fe74 | 20 | #include "defs.h" |
7e7de0c9 SL |
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; | |
7fe7fe74 | 33 | register int flags; |
7e7de0c9 SL |
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; | |
55d340a4 | 42 | flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; |
7fe7fe74 | 43 | (*f)(dst, flags, ifp); |
7e7de0c9 SL |
44 | } |
45 | } | |
46 | ||
47 | /* | |
48 | * Output a preformed packet. | |
49 | */ | |
50 | /*ARGSUSED*/ | |
7fe7fe74 | 51 | sendmsg(dst, flags, ifp) |
7e7de0c9 | 52 | struct sockaddr *dst; |
7fe7fe74 | 53 | int flags; |
7e7de0c9 SL |
54 | struct interface *ifp; |
55 | { | |
56 | ||
7fe7fe74 | 57 | (*afswitch[dst->sa_family].af_output)(s, flags, |
7e7de0c9 SL |
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 | */ | |
7fe7fe74 | 66 | supply(dst, flags, ifp) |
7e7de0c9 | 67 | struct sockaddr *dst; |
7fe7fe74 | 68 | int flags; |
7892134c | 69 | register struct interface *ifp; |
7e7de0c9 SL |
70 | { |
71 | register struct rt_entry *rt; | |
7892134c | 72 | register struct netinfo *n = msg->rip_nets; |
7e7de0c9 SL |
73 | register struct rthash *rh; |
74 | struct rthash *base = hosthash; | |
75 | int doinghost = 1, size; | |
76 | int (*output)() = afswitch[dst->sa_family].af_output; | |
7892134c | 77 | int (*sendroute)() = afswitch[dst->sa_family].af_sendroute; |
f2ce7d44 | 78 | int npackets = 0; |
7e7de0c9 SL |
79 | |
80 | msg->rip_cmd = RIPCMD_RESPONSE; | |
55d340a4 | 81 | msg->rip_vers = RIPVERSION; |
eabc591a | 82 | bzero(msg->rip_res1, sizeof(msg->rip_res1)); |
7e7de0c9 SL |
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) { | |
4fad5a6e | 86 | /* |
7892134c MK |
87 | * Don't resend the information on the network |
88 | * from which it was received (unless sending | |
89 | * in response to a query). | |
4fad5a6e | 90 | */ |
7127cc90 MK |
91 | if (ifp && rt->rt_ifp == ifp && |
92 | (rt->rt_state & RTS_INTERFACE) == 0) | |
4fad5a6e MK |
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) { | |
4fad5a6e MK |
101 | if (rt->rt_dst.sa_family != dst->sa_family) |
102 | continue; | |
7892134c | 103 | if ((*sendroute)(rt, dst) == 0) |
4fad5a6e MK |
104 | continue; |
105 | } | |
7e7de0c9 SL |
106 | size = (char *)n - packet; |
107 | if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { | |
7fe7fe74 | 108 | (*output)(s, flags, dst, size); |
7e7de0c9 SL |
109 | TRACE_OUTPUT(ifp, dst, size); |
110 | n = msg->rip_nets; | |
f2ce7d44 | 111 | npackets++; |
7e7de0c9 SL |
112 | } |
113 | n->rip_dst = rt->rt_dst; | |
55d340a4 | 114 | n->rip_dst.sa_family = htons(n->rip_dst.sa_family); |
7892134c | 115 | n->rip_metric = htonl(min(rt->rt_metric + 1, HOPCNT_INFINITY)); |
7e7de0c9 SL |
116 | n++; |
117 | } | |
118 | if (doinghost) { | |
119 | doinghost = 0; | |
120 | base = nethash; | |
121 | goto again; | |
122 | } | |
f2ce7d44 | 123 | if (n != msg->rip_nets || npackets == 0) { |
7e7de0c9 | 124 | size = (char *)n - packet; |
7fe7fe74 | 125 | (*output)(s, flags, dst, size); |
7e7de0c9 SL |
126 | TRACE_OUTPUT(ifp, dst, size); |
127 | } | |
128 | } |