/***********************************************************
Copyright IBM Corporation 1987
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
******************************************************************/
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
/* $Header: clnp_arp.c,v 4.2 88/06/29 14:58:32 hagens Exp $ */
/* $Source: /usr/argo/sys/netiso/RCS/clnp_arp.c,v $ */
static char *rcsid
= "$Header: clnp_arp.c,v 4.2 88/06/29 14:58:32 hagens Exp $";
#include "../net/route.h"
#define MAPTAB_BSIZ 20 /* bucket size */
#define MAPTAB_NB 13 /* number of buckets */
#define MAPTAB_SIZE (MAPTAB_BSIZ * MAPTAB_NB)
struct maptab iso_maptab
[MAPTAB_SIZE
];
int iso_maptab_size
= MAPTAB_SIZE
; /* for isomap command */
#define MAPTAB_HASH(addr) \
(((u_long) iso_hashchar(addr, addr->isoa_len)) % MAPTAB_NB)
#define MAPTAB_LOOK(at,addr) { \
at = &iso_maptab[MAPTAB_HASH(addr) * MAPTAB_BSIZ]; \
for (n = 0 ; n < MAPTAB_BSIZ ; n++,at++) \
if ((at->map_valid) && (iso_addrmatch1(&at->map_isoa, addr))) \
* FUNCTION: clnp_arpresolve
* PURPOSE: Resolve a clnp address into hardware ethernet addr.
* RETURNS: 1 if addr is resolved
* NOTES: This is a hack. If the address is local, then
* the packet is put on the loopback driver. Otherwise,
* if a translation is found, that ethernet address is
* returned. Otherwise, the packet is dropped. Thus,
* each translation must be placed (by hand) in the
* tables (see isomap(8)).
* TODO: should this map stuff be a critical section?
clnp_arpresolve(ifp
, m
, dst
, edst
)
struct ifnet
*ifp
; /* outgoing interface */
struct mbuf
*m
; /* pkt */
struct sockaddr_iso
*dst
; /* destination */
char *edst
; /* RESULT: ethernet address */
extern struct ifnet loif
; /* loopback interface */
struct maptab
*at
; /* ptr to map table entry */
struct iso_addr
*destiso
; /* destination iso addr */
destiso
= &dst
->siso_addr
;
if (destiso
->isoa_genaddr
[0] == AFI_SNA
) {
* This is a subnetwork address. Return it immediately
printf("clnp_arpresolve: return SN address\n");
sna_len
= destiso
->isoa_len
- 1; /* subtract size of AFI */
printf("clnp_arpresolve: SN len is bad (%d)\n", sna_len
);
bcopy((caddr_t
)&destiso
->isoa_genaddr
[1], (caddr_t
)edst
, sna_len
);
printf("clnp_arpresolve: resolving %s\n", clnp_iso_addrp(destiso
));
/* if for us, use software loopback driver if up */
if (clnp_ours(destiso
)) {
printf("clnp_arpresolve: local destination\n");
if (loif
.if_flags
& IFF_UP
) {
printf("clnp_arpresolve: calling looutput\n");
(void) looutput(&loif
, m
, (struct sockaddr
*)dst
);
* The packet has already been sent and freed.
printf("clnp_arpresolve: NON-local destination\n");
* packet is not for us, check static map table for an entry
* This does not need to be a critical section because the
* table is not dynamically updated, except by a call to
MAPTAB_LOOK(at
, destiso
);
if (at
== 0) { /* not found */
bcopy((caddr_t
)at
->map_enaddr
, (caddr_t
)edst
, sizeof(at
->map_enaddr
));
* PURPOSE: create a new entry in the iso address to ethernet
* RETURNS: pointer to newest entry, or NULL if none can be found
* NOTES: TODO: timeout old entries
struct iso_addr
*isoa
; /* iso address to enter into table */
register struct maptab
*at
;
at
= &iso_maptab
[MAPTAB_HASH(isoa
) * MAPTAB_BSIZ
];
for (n
= 0 ; n
< MAPTAB_BSIZ
; n
++,at
++) {
printf("isomap_new: at x%x ", at
);
printf("(valid) %s ", clnp_iso_addrp(&at
->map_isoa
));
printf("%x%c", at
->map_enaddr
[i
], i
< 5 ? ':' : '\n');
if (!at
->map_valid
) /* found unused slot */
* PURPOSE: free an entry in the iso address map table
register struct maptab
*at
; /* entry to free */
* PURPOSE: handle ioctls to change the iso address map
* RETURNS: unix error code
* SIDE EFFECTS: changes the maptab table declared above.
int cmd
; /* ioctl to process */
caddr_t data
; /* data for the cmd */
register struct arpreq_iso
*ar
= (struct arpreq_iso
*)data
;
register struct maptab
*at
;
register struct sockaddr_iso
*siso
;
register struct iso_addr
*isoa
;
* only process commands for the ISO address family
if (ar
->arp_pa
.siso_family
!= AF_ISO
)
/* look up this address in table */
siso
= (struct sockaddr_iso
*)&ar
->arp_pa
;
printf("isomap_ioctl: ");
case SIOCSISOMAP
: printf("set"); break;
case SIOCDISOMAP
: printf("delete"); break;
case SIOCGISOMAP
: printf("get"); break;
printf(" %s to ", clnp_iso_addrp(isoa
));
printf("%x%c", ar
->arp_ha
.sa_data
[i
], i
< 5 ? ':' : '\n');
if (at
== NULL
) { /* not found */
/* TODO: what if setting and net is not directly attached */
case SIOCSISOMAP
: /* set entry */
bcopy((caddr_t
)isoa
, (caddr_t
)&at
->map_isoa
,
sizeof (struct iso_addr
));
bcopy((caddr_t
)ar
->arp_ha
.sa_data
, (caddr_t
)at
->map_enaddr
,
case SIOCDISOMAP
: /* delete entry */
case SIOCGISOMAP
: /* get entry */
bcopy((caddr_t
)at
->map_enaddr
, (caddr_t
)ar
->arp_ha
.sa_data
,