Commit | Line | Data |
---|---|---|
1a3bd5f3 KS |
1 | /*********************************************************** |
2 | Copyright IBM Corporation 1987 | |
3 | ||
4 | All Rights Reserved | |
5 | ||
6 | Permission to use, copy, modify, and distribute this software and its | |
7 | documentation for any purpose and without fee is hereby granted, | |
8 | provided that the above copyright notice appear in all copies and that | |
9 | both that copyright notice and this permission notice appear in | |
10 | supporting documentation, and that the name of IBM not be | |
11 | used in advertising or publicity pertaining to distribution of the | |
12 | software without specific, written prior permission. | |
13 | ||
14 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
15 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
16 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
17 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
18 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
19 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
20 | SOFTWARE. | |
21 | ||
22 | ******************************************************************/ | |
23 | ||
24 | /* | |
25 | * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison | |
26 | */ | |
27 | /* $Header: clnp_arp.c,v 4.2 88/06/29 14:58:32 hagens Exp $ */ | |
28 | /* $Source: /usr/argo/sys/netiso/RCS/clnp_arp.c,v $ */ | |
29 | ||
30 | #ifndef lint | |
31 | static char *rcsid = "$Header: clnp_arp.c,v 4.2 88/06/29 14:58:32 hagens Exp $"; | |
32 | #endif lint | |
33 | ||
34 | #ifdef ISO | |
35 | ||
e663c139 KM |
36 | #include "types.h" |
37 | #include "param.h" | |
38 | #include "mbuf.h" | |
39 | #include "domain.h" | |
40 | #include "protosw.h" | |
41 | #include "socket.h" | |
42 | #include "socketvar.h" | |
43 | #include "errno.h" | |
44 | #include "ioctl.h" | |
1a3bd5f3 KS |
45 | |
46 | #include "../net/if.h" | |
47 | #include "../net/route.h" | |
48 | ||
46f932e4 KS |
49 | #include "iso.h" |
50 | #include "iso_var.h" | |
51 | #include "iso_map.h" | |
52 | #include "iso_snpac.h" | |
53 | #include "clnp.h" | |
54 | #include "clnp_stat.h" | |
55 | #include "argo_debug.h" | |
1a3bd5f3 KS |
56 | |
57 | #define MAPTAB_BSIZ 20 /* bucket size */ | |
58 | #define MAPTAB_NB 13 /* number of buckets */ | |
59 | #define MAPTAB_SIZE (MAPTAB_BSIZ * MAPTAB_NB) | |
60 | struct maptab iso_maptab[MAPTAB_SIZE]; | |
61 | int iso_maptab_size = MAPTAB_SIZE; /* for isomap command */ | |
62 | ||
63 | #define MAPTAB_HASH(addr) \ | |
64 | (((u_long) iso_hashchar(addr, addr->isoa_len)) % MAPTAB_NB) | |
65 | ||
66 | #define MAPTAB_LOOK(at,addr) { \ | |
67 | register n; \ | |
68 | at = &iso_maptab[MAPTAB_HASH(addr) * MAPTAB_BSIZ]; \ | |
69 | for (n = 0 ; n < MAPTAB_BSIZ ; n++,at++) \ | |
70 | if ((at->map_valid) && (iso_addrmatch1(&at->map_isoa, addr))) \ | |
71 | break; \ | |
72 | if (n >= MAPTAB_BSIZ) \ | |
73 | at = 0; \ | |
74 | } | |
75 | ||
76 | /* | |
77 | * FUNCTION: clnp_arpresolve | |
78 | * | |
79 | * PURPOSE: Resolve a clnp address into hardware ethernet addr. | |
80 | * | |
81 | * RETURNS: 1 if addr is resolved | |
82 | * 0 if addr is unknown | |
83 | * | |
84 | * SIDE EFFECTS: | |
85 | * | |
86 | * NOTES: This is a hack. If the address is local, then | |
87 | * the packet is put on the loopback driver. Otherwise, | |
88 | * if a translation is found, that ethernet address is | |
89 | * returned. Otherwise, the packet is dropped. Thus, | |
90 | * each translation must be placed (by hand) in the | |
91 | * tables (see isomap(8)). | |
92 | * TODO: should this map stuff be a critical section? | |
93 | */ | |
94 | clnp_arpresolve(ifp, m, dst, edst) | |
95 | struct ifnet *ifp; /* outgoing interface */ | |
96 | struct mbuf *m; /* pkt */ | |
97 | struct sockaddr_iso *dst; /* destination */ | |
98 | char *edst; /* RESULT: ethernet address */ | |
99 | { | |
100 | extern struct ifnet loif; /* loopback interface */ | |
101 | struct maptab *at; /* ptr to map table entry */ | |
102 | struct iso_addr *destiso; /* destination iso addr */ | |
103 | ||
104 | destiso = &dst->siso_addr; | |
105 | ||
46f932e4 | 106 | if (destiso->isoa_genaddr[0] == AFI_SNA) { |
1a3bd5f3 KS |
107 | /* |
108 | * This is a subnetwork address. Return it immediately | |
109 | */ | |
110 | int sna_len; | |
111 | ||
112 | IFDEBUG(D_ESISOUTPUT) | |
113 | printf("clnp_arpresolve: return SN address\n"); | |
114 | ENDDEBUG | |
115 | ||
116 | sna_len = destiso->isoa_len - 1; /* subtract size of AFI */ | |
117 | if (sna_len != 6) { | |
118 | IFDEBUG(D_ESISOUTPUT) | |
119 | printf("clnp_arpresolve: SN len is bad (%d)\n", sna_len); | |
120 | ENDDEBUG | |
121 | return(-1); | |
122 | } | |
46f932e4 | 123 | bcopy((caddr_t)&destiso->isoa_genaddr[1], (caddr_t)edst, sna_len); |
1a3bd5f3 KS |
124 | return (1); |
125 | } | |
126 | ||
127 | IFDEBUG(D_ETHER) | |
128 | printf("clnp_arpresolve: resolving %s\n", clnp_iso_addrp(destiso)); | |
129 | ENDDEBUG | |
130 | ||
131 | /* if for us, use software loopback driver if up */ | |
132 | if (clnp_ours(destiso)) { | |
133 | IFDEBUG(D_ETHER) | |
134 | printf("clnp_arpresolve: local destination\n"); | |
135 | ENDDEBUG | |
136 | if (loif.if_flags & IFF_UP) { | |
137 | IFDEBUG(D_ETHER) | |
138 | printf("clnp_arpresolve: calling looutput\n"); | |
139 | ENDDEBUG | |
140 | (void) looutput(&loif, m, (struct sockaddr *)dst); | |
141 | /* | |
142 | * The packet has already been sent and freed. | |
143 | */ | |
144 | return (0); | |
145 | } | |
146 | } | |
147 | ||
148 | IFDEBUG(D_ETHER) | |
149 | printf("clnp_arpresolve: NON-local destination\n"); | |
150 | ENDDEBUG | |
151 | ||
152 | /* | |
153 | * packet is not for us, check static map table for an entry | |
154 | * This does not need to be a critical section because the | |
155 | * table is not dynamically updated, except by a call to | |
156 | * isomap(8) | |
157 | */ | |
158 | MAPTAB_LOOK(at, destiso); | |
159 | if (at == 0) { /* not found */ | |
160 | m_freem(m); | |
161 | return (-1); | |
162 | } else { | |
163 | bcopy((caddr_t)at->map_enaddr, (caddr_t)edst, sizeof(at->map_enaddr)); | |
164 | return (1); | |
165 | } | |
166 | } | |
167 | ||
168 | /* | |
169 | * FUNCTION: isomap_new | |
170 | * | |
171 | * PURPOSE: create a new entry in the iso address to ethernet | |
172 | * address table | |
173 | * | |
174 | * RETURNS: pointer to newest entry, or NULL if none can be found | |
175 | * | |
176 | * SIDE EFFECTS: | |
177 | * | |
178 | * NOTES: TODO: timeout old entries | |
179 | */ | |
180 | struct maptab * | |
181 | isomap_new(isoa) | |
182 | struct iso_addr *isoa; /* iso address to enter into table */ | |
183 | { | |
184 | register struct maptab *at; | |
185 | register int n; | |
186 | ||
187 | at = &iso_maptab[MAPTAB_HASH(isoa) * MAPTAB_BSIZ]; | |
188 | for (n = 0 ; n < MAPTAB_BSIZ ; n++,at++) { | |
189 | ||
190 | IFDEBUG (D_IOCTL) | |
191 | printf("isomap_new: at x%x ", at); | |
192 | ||
193 | if (at->map_valid) { | |
194 | int i; | |
195 | ||
196 | printf("(valid) %s ", clnp_iso_addrp(&at->map_isoa)); | |
197 | for (i=0; i<6; i++) | |
198 | printf("%x%c", at->map_enaddr[i], i < 5 ? ':' : '\n'); | |
199 | } else { | |
200 | printf("invalid\n"); | |
201 | } | |
202 | ENDDEBUG | |
203 | ||
204 | if (!at->map_valid) /* found unused slot */ | |
205 | return at; | |
206 | } | |
207 | return NULL; | |
208 | } | |
209 | ||
210 | /* | |
211 | * FUNCTION: isomap_free | |
212 | * | |
213 | * PURPOSE: free an entry in the iso address map table | |
214 | * | |
215 | * RETURNS: nothing | |
216 | * | |
217 | * SIDE EFFECTS: | |
218 | * | |
219 | * NOTES: | |
220 | */ | |
221 | isomap_free(at) | |
222 | register struct maptab *at; /* entry to free */ | |
223 | { | |
224 | at->map_valid = 0; | |
225 | } | |
226 | ||
227 | /* | |
228 | * FUNCTION: isomap_ioctl | |
229 | * | |
230 | * PURPOSE: handle ioctls to change the iso address map | |
231 | * | |
232 | * RETURNS: unix error code | |
233 | * | |
234 | * SIDE EFFECTS: changes the maptab table declared above. | |
235 | * | |
236 | * NOTES: | |
237 | */ | |
238 | isomap_ioctl(cmd, data) | |
239 | int cmd; /* ioctl to process */ | |
240 | caddr_t data; /* data for the cmd */ | |
241 | { | |
46f932e4 | 242 | register struct arpreq_iso *ar = (struct arpreq_iso *)data; |
1a3bd5f3 KS |
243 | register struct maptab *at; |
244 | register struct sockaddr_iso *siso; | |
245 | register struct iso_addr *isoa; | |
246 | ||
247 | /* | |
248 | * only process commands for the ISO address family | |
249 | */ | |
46f932e4 | 250 | if (ar->arp_pa.siso_family != AF_ISO) |
1a3bd5f3 KS |
251 | return(EAFNOSUPPORT); |
252 | ||
253 | /* look up this address in table */ | |
254 | siso = (struct sockaddr_iso *)&ar->arp_pa; | |
255 | isoa = &siso->siso_addr; | |
256 | ||
257 | IFDEBUG (D_IOCTL) | |
258 | int i; | |
259 | ||
260 | printf("isomap_ioctl: "); | |
261 | switch(cmd) { | |
262 | case SIOCSISOMAP: printf("set"); break; | |
263 | case SIOCDISOMAP: printf("delete"); break; | |
264 | case SIOCGISOMAP: printf("get"); break; | |
265 | } | |
266 | printf(" %s to ", clnp_iso_addrp(isoa)); | |
267 | for (i=0; i<6; i++) | |
268 | printf("%x%c", ar->arp_ha.sa_data[i], i < 5 ? ':' : '\n'); | |
269 | ENDDEBUG | |
270 | ||
271 | MAPTAB_LOOK(at, isoa); | |
272 | if (at == NULL) { /* not found */ | |
273 | if (cmd != SIOCSISOMAP) | |
274 | return(ENXIO); | |
275 | ||
276 | /* TODO: what if setting and net is not directly attached */ | |
277 | } | |
278 | ||
279 | switch(cmd) { | |
280 | case SIOCSISOMAP: /* set entry */ | |
281 | if (at == NULL) { | |
282 | at = isomap_new(isoa); | |
283 | if (at == NULL) | |
284 | return(ENOBUFS); | |
285 | } | |
286 | bcopy((caddr_t)isoa, (caddr_t)&at->map_isoa, | |
287 | sizeof (struct iso_addr)); | |
288 | bcopy((caddr_t)ar->arp_ha.sa_data, (caddr_t)at->map_enaddr, | |
289 | sizeof(at->map_enaddr)); | |
290 | at->map_valid++; | |
291 | break; | |
292 | ||
293 | case SIOCDISOMAP: /* delete entry */ | |
294 | isomap_free(at); | |
295 | break; | |
296 | ||
297 | case SIOCGISOMAP: /* get entry */ | |
298 | bcopy((caddr_t)at->map_enaddr, (caddr_t)ar->arp_ha.sa_data, | |
299 | sizeof(at->map_enaddr)); | |
300 | } | |
301 | return(0); | |
302 | } | |
303 | #endif ISO |