Commit | Line | Data |
---|---|---|
5ff67f98 DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
7e7de0c9 | 7 | #ifndef lint |
09069ad0 | 8 | static char sccsid[] = "@(#)output.c 5.3 (Berkeley) %G%"; |
5ff67f98 | 9 | #endif not lint |
7e7de0c9 SL |
10 | |
11 | /* | |
12 | * Routing Table Management Daemon | |
13 | */ | |
7fe7fe74 | 14 | #include "defs.h" |
7e7de0c9 SL |
15 | |
16 | /* | |
17 | * Apply the function "f" to all non-passive | |
18 | * interfaces. If the interface supports the | |
19 | * use of broadcasting use it, otherwise address | |
20 | * the output to the known router. | |
21 | */ | |
22 | toall(f) | |
23 | int (*f)(); | |
24 | { | |
25 | register struct interface *ifp; | |
26 | register struct sockaddr *dst; | |
7fe7fe74 | 27 | register int flags; |
7e7de0c9 SL |
28 | extern struct interface *ifnet; |
29 | ||
30 | for (ifp = ifnet; ifp; ifp = ifp->int_next) { | |
31 | if (ifp->int_flags & IFF_PASSIVE) | |
32 | continue; | |
33 | dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : | |
34 | ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : | |
35 | &ifp->int_addr; | |
55d340a4 | 36 | flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; |
7fe7fe74 | 37 | (*f)(dst, flags, ifp); |
7e7de0c9 SL |
38 | } |
39 | } | |
40 | ||
41 | /* | |
42 | * Output a preformed packet. | |
43 | */ | |
44 | /*ARGSUSED*/ | |
7fe7fe74 | 45 | sendmsg(dst, flags, ifp) |
7e7de0c9 | 46 | struct sockaddr *dst; |
7fe7fe74 | 47 | int flags; |
7e7de0c9 SL |
48 | struct interface *ifp; |
49 | { | |
50 | ||
7fe7fe74 | 51 | (*afswitch[dst->sa_family].af_output)(s, flags, |
7e7de0c9 SL |
52 | dst, sizeof (struct rip)); |
53 | TRACE_OUTPUT(ifp, dst, sizeof (struct rip)); | |
54 | } | |
55 | ||
56 | /* | |
57 | * Supply dst with the contents of the routing tables. | |
58 | * If this won't fit in one packet, chop it up into several. | |
59 | */ | |
7fe7fe74 | 60 | supply(dst, flags, ifp) |
7e7de0c9 | 61 | struct sockaddr *dst; |
7fe7fe74 | 62 | int flags; |
7e7de0c9 SL |
63 | struct interface *ifp; |
64 | { | |
65 | register struct rt_entry *rt; | |
66 | struct netinfo *n = msg->rip_nets; | |
67 | register struct rthash *rh; | |
68 | struct rthash *base = hosthash; | |
69 | int doinghost = 1, size; | |
70 | int (*output)() = afswitch[dst->sa_family].af_output; | |
4fad5a6e | 71 | int (*sendsubnet)() = afswitch[dst->sa_family].af_sendsubnet; |
7e7de0c9 SL |
72 | |
73 | msg->rip_cmd = RIPCMD_RESPONSE; | |
55d340a4 | 74 | msg->rip_vers = RIPVERSION; |
7e7de0c9 SL |
75 | again: |
76 | for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) | |
77 | for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { | |
4fad5a6e MK |
78 | /* |
79 | * Don't resend the information | |
80 | * on the network from which it was received. | |
81 | */ | |
82 | if (ifp && rt->rt_ifp == ifp) | |
83 | continue; | |
84 | if (rt->rt_state & RTS_EXTERNAL) | |
85 | continue; | |
86 | /* | |
87 | * Limit the spread of subnet information | |
88 | * to those who are interested. | |
89 | */ | |
90 | if (doinghost == 0 && rt->rt_state & RTS_SUBNET) { | |
91 | if (ifp && (ifp->int_flags & IFF_SUBNET) == 0) | |
92 | continue; | |
93 | if (rt->rt_dst.sa_family != dst->sa_family) | |
94 | continue; | |
09069ad0 | 95 | if ((*sendsubnet)(rt, dst) == 0) |
4fad5a6e MK |
96 | continue; |
97 | } | |
7e7de0c9 SL |
98 | size = (char *)n - packet; |
99 | if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { | |
7fe7fe74 | 100 | (*output)(s, flags, dst, size); |
7e7de0c9 SL |
101 | TRACE_OUTPUT(ifp, dst, size); |
102 | n = msg->rip_nets; | |
103 | } | |
104 | n->rip_dst = rt->rt_dst; | |
55d340a4 | 105 | n->rip_dst.sa_family = htons(n->rip_dst.sa_family); |
9b1c54bf | 106 | n->rip_metric = htonl(min(rt->rt_metric + 1, HOPCNT_INFINITY)); |
7e7de0c9 SL |
107 | n++; |
108 | } | |
109 | if (doinghost) { | |
110 | doinghost = 0; | |
111 | base = nethash; | |
112 | goto again; | |
113 | } | |
114 | if (n != msg->rip_nets) { | |
115 | size = (char *)n - packet; | |
7fe7fe74 | 116 | (*output)(s, flags, dst, size); |
7e7de0c9 SL |
117 | TRACE_OUTPUT(ifp, dst, size); |
118 | } | |
119 | } |