make kernel includes standard
[unix-history] / usr / src / sys / netiso / clnp_arp.c
CommitLineData
1a3bd5f3
KS
1/***********************************************************
2 Copyright IBM Corporation 1987
3
4 All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of IBM not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
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
31static 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)
60struct maptab iso_maptab[MAPTAB_SIZE];
61int 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 */
94clnp_arpresolve(ifp, m, dst, edst)
95struct ifnet *ifp; /* outgoing interface */
96struct mbuf *m; /* pkt */
97struct sockaddr_iso *dst; /* destination */
98char *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 */
180struct maptab *
181isomap_new(isoa)
182struct 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 */
221isomap_free(at)
222register 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 */
238isomap_ioctl(cmd, data)
239int cmd; /* ioctl to process */
240caddr_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