Commit | Line | Data |
---|---|---|
72e4f44e | 1 | /* if.c 4.14 82/04/24 */ |
1bfd8df7 BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
ee787340 | 5 | #include "../h/socket.h" |
72e4f44e | 6 | #include "../h/protosw.h" |
8a13b737 BJ |
7 | #include "../net/in.h" |
8 | #include "../net/in_systm.h" | |
1bfd8df7 | 9 | #include "../net/if.h" |
ee787340 | 10 | #include "../net/af.h" |
1bfd8df7 | 11 | |
1e977657 BJ |
12 | int ifqmaxlen = IFQ_MAXLEN; |
13 | ||
ee787340 SL |
14 | /* |
15 | * Network interface utility routines. | |
16 | * | |
17 | * Routines with if_ifwith* names take sockaddr *'s as | |
18 | * parameters. Other routines take value parameters, | |
19 | * e.g. if_ifwithnet takes the network number. | |
20 | */ | |
21 | ||
85ce71f2 BJ |
22 | ifinit() |
23 | { | |
24 | register struct ifnet *ifp; | |
25 | ||
26 | for (ifp = ifnet; ifp; ifp = ifp->if_next) | |
1e977657 | 27 | if (ifp->if_init) { |
ee787340 | 28 | (*ifp->if_init)(ifp->if_unit); |
1e977657 BJ |
29 | if (ifp->if_snd.ifq_maxlen == 0) |
30 | ifp->if_snd.ifq_maxlen = ifqmaxlen; | |
31 | } | |
85ce71f2 BJ |
32 | } |
33 | ||
ee787340 SL |
34 | /* |
35 | * Call each interface on a Unibus reset. | |
36 | */ | |
85ce71f2 BJ |
37 | ifubareset(uban) |
38 | int uban; | |
39 | { | |
40 | register struct ifnet *ifp; | |
41 | ||
42 | for (ifp = ifnet; ifp; ifp = ifp->if_next) | |
43 | if (ifp->if_ubareset) | |
44 | (*ifp->if_ubareset)(uban); | |
45 | } | |
46 | ||
ee787340 SL |
47 | /* |
48 | * Attach an interface to the | |
49 | * list of "active" interfaces. | |
50 | */ | |
405c9168 BJ |
51 | if_attach(ifp) |
52 | struct ifnet *ifp; | |
53 | { | |
c4af8b24 | 54 | register struct ifnet **p = &ifnet; |
405c9168 BJ |
55 | |
56 | COUNT(IF_ATTACH); | |
c4af8b24 BJ |
57 | while (*p) |
58 | p = &((*p)->if_next); | |
59 | *p = ifp; | |
405c9168 BJ |
60 | } |
61 | ||
ee787340 SL |
62 | /* |
63 | * Locate an interface based on a complete address. | |
64 | */ | |
4ad99bae BJ |
65 | /*ARGSUSED*/ |
66 | struct ifnet * | |
ee787340 SL |
67 | if_ifwithaddr(addr) |
68 | struct sockaddr *addr; | |
1bfd8df7 BJ |
69 | { |
70 | register struct ifnet *ifp; | |
71 | ||
4ad99bae | 72 | COUNT(IF_IFWITHADDR); |
ee787340 SL |
73 | #define equal(a1, a2) \ |
74 | (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) | |
75 | for (ifp = ifnet; ifp; ifp = ifp->if_next) { | |
76 | if (ifp->if_addr.sa_family != addr->sa_family) | |
77 | continue; | |
78 | if (equal(&ifp->if_addr, addr)) | |
79 | break; | |
80 | if ((ifp->if_flags & IFF_BROADCAST) && | |
81 | equal(&ifp->if_broadaddr, addr)) | |
1bfd8df7 | 82 | break; |
ee787340 | 83 | } |
1bfd8df7 BJ |
84 | return (ifp); |
85 | } | |
86 | ||
ee787340 SL |
87 | /* |
88 | * Find an interface on a specific network. If many, choice | |
89 | * is first found. | |
90 | */ | |
4ad99bae | 91 | struct ifnet * |
ee787340 SL |
92 | if_ifwithnet(addr) |
93 | register struct sockaddr *addr; | |
94 | { | |
95 | register struct ifnet *ifp; | |
96 | register int af = addr->sa_family; | |
97 | register int (*netmatch)() = afswitch[af].af_netmatch; | |
98 | ||
99 | for (ifp = ifnet; ifp; ifp = ifp->if_next) { | |
100 | if (af != ifp->if_addr.sa_family) | |
101 | continue; | |
102 | if ((*netmatch)(addr, &ifp->if_addr)) | |
103 | break; | |
104 | } | |
105 | return (ifp); | |
106 | } | |
107 | ||
108 | /* | |
109 | * As above, but parameter is network number. | |
110 | */ | |
111 | struct ifnet * | |
112 | if_ifonnetof(net) | |
113 | register int net; | |
1bfd8df7 BJ |
114 | { |
115 | register struct ifnet *ifp; | |
1bfd8df7 | 116 | |
1bfd8df7 BJ |
117 | for (ifp = ifnet; ifp; ifp = ifp->if_next) |
118 | if (ifp->if_net == net) | |
119 | break; | |
1bfd8df7 BJ |
120 | return (ifp); |
121 | } | |
122 | ||
ee787340 SL |
123 | /* |
124 | * Find an interface using a specific address family | |
125 | */ | |
8a13b737 | 126 | struct ifnet * |
ee787340 SL |
127 | if_ifwithaf(af) |
128 | register int af; | |
8a13b737 | 129 | { |
ee787340 | 130 | register struct ifnet *ifp; |
8a13b737 | 131 | |
ee787340 SL |
132 | for (ifp = ifnet; ifp; ifp = ifp->if_next) |
133 | if (ifp->if_addr.sa_family == af) | |
134 | break; | |
135 | return (ifp); | |
8a13b737 | 136 | } |
f1b2fa5b | 137 | |
72e4f44e SL |
138 | /* |
139 | * Mark an interface down and notify protocols of | |
140 | * the transition. | |
141 | */ | |
142 | if_down(ifp) | |
143 | register struct ifnet *ifp; | |
144 | { | |
145 | ifp->if_flags &= ~IFF_UP; | |
146 | pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); | |
147 | } | |
148 | ||
ee787340 SL |
149 | /* |
150 | * Formulate an Internet address from network + host. Used in | |
151 | * building addresses stored in the ifnet structure. | |
152 | */ | |
f1b2fa5b BJ |
153 | struct in_addr |
154 | if_makeaddr(net, host) | |
155 | int net, host; | |
156 | { | |
157 | u_long addr; | |
158 | ||
159 | if (net < 128) | |
85ce71f2 | 160 | addr = (net << 24) | host; |
f1b2fa5b | 161 | else if (net < 65536) |
85ce71f2 | 162 | addr = (net << 16) | host; |
f1b2fa5b | 163 | else |
85ce71f2 | 164 | addr = (net << 8) | host; |
72c68388 | 165 | #ifdef vax |
f1b2fa5b | 166 | addr = htonl(addr); |
72c68388 | 167 | #endif |
f1b2fa5b BJ |
168 | return (*(struct in_addr *)&addr); |
169 | } | |
f6311fb6 SL |
170 | |
171 | /* | |
172 | * Initialize an interface's routing | |
173 | * table entry according to the network. | |
174 | * INTERNET SPECIFIC. | |
175 | */ | |
176 | if_rtinit(ifp, flags) | |
177 | register struct ifnet *ifp; | |
178 | int flags; | |
179 | { | |
180 | struct sockaddr_in sin; | |
181 | ||
182 | if (ifp->if_flags & IFF_ROUTE) | |
183 | return; | |
184 | bzero((caddr_t)&sin, sizeof (sin)); | |
185 | sin.sin_family = AF_INET; | |
186 | sin.sin_addr = if_makeaddr(ifp->if_net, 0); | |
fc74f0c9 | 187 | rtinit(&sin, &ifp->if_addr, flags); |
f6311fb6 | 188 | } |