#if ISO
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <net/raw_cb.h>
#include <netiso/iso.h>
#include <netiso/iso_pcb.h>
#include <netiso/iso_var.h>
#include <netiso/iso_snpac.h>
#include <netiso/clnl.h>
#include <netiso/clnp.h>
#include <netiso/clnp_stat.h>
#include <netiso/esis.h>
#include <netiso/argo_debug.h>
struct rawcb esis_pcb;
void esis_config(), snpac_age();
int esis_sendspace = 2048;
int esis_recvspace = 2048;
short esis_holding_time = ESIS_HT;
short esis_config_time = ESIS_CONFIG;
short esis_esconfig_time = ESIS_CONFIG;
extern int iso_systype;
struct sockaddr_dl esis_dl = { sizeof(esis_dl), AF_LINK };
extern char all_es_snpa[], all_is_snpa[];
#define EXTEND_PACKET(m, mhdr, cp)\
if (((m)->m_next = m_getclr(M_DONTWAIT, MT_HEADER)) == NULL) {\
esis_stat.es_nomem++;\
m_freem(mhdr);\
return;\
} else {\
(m) = (m)->m_next;\
(cp) = mtod((m), caddr_t);\
}
esis_init()
{
extern struct clnl_protosw clnl_protox[256];
int esis_input(), isis_input();
#ifdef ISO_X25ESIS
int x25esis_input();
#endif
esis_pcb.rcb_next = esis_pcb.rcb_prev = &esis_pcb;
llinfo_llc.lc_next = llinfo_llc.lc_prev = &llinfo_llc;
timeout(snpac_age, (caddr_t)0, hz);
timeout(esis_config, (caddr_t)0, hz);
clnl_protox[ISO9542_ESIS].clnl_input = esis_input;
clnl_protox[ISO10589_ISIS].clnl_input = isis_input;
#ifdef ISO_X25ESIS
clnl_protox[ISO9542X25_ESIS].clnl_input = x25esis_input;
#endif
}
esis_usrreq(so, req, m, nam, control)
struct socket *so;
int req;
struct mbuf *m;
struct mbuf *nam;
struct mbuf *control;
{
struct rawcb *rp = sotorawcb(so);
int error = 0;
if ((so->so_state & SS_PRIV) == 0) {
error = EACCES;
goto release;
}
if (rp == NULL && req != PRU_ATTACH) {
error = EINVAL;
goto release;
}
switch (req) {
case PRU_ATTACH:
if (rp != NULL) {
error = EINVAL;
break;
}
MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
if (so->so_pcb = (caddr_t)rp) {
bzero(so->so_pcb, sizeof(*rp));
insque(rp, &esis_pcb);
rp->rcb_socket = so;
error = soreserve(so, esis_sendspace, esis_recvspace);
} else
error = ENOBUFS;
break;
case PRU_SEND:
if (nam == NULL) {
error = EINVAL;
break;
}
error = isis_output(mtod(nam,struct sockaddr_dl *), m);
m = NULL;
break;
case PRU_DETACH:
raw_detach(rp);
break;
case PRU_SHUTDOWN:
socantsendmore(so);
break;
case PRU_ABORT:
soisdisconnected(so);
raw_detach(rp);
break;
case PRU_SENSE:
return (0);
default:
return (EOPNOTSUPP);
}
release:
if (m != NULL)
m_freem(m);
return (error);
}
esis_input(m0, shp)
struct mbuf *m0;
struct snpa_hdr *shp;
{
register struct esis_fixed *pdu = mtod(m0, struct esis_fixed *);
register int type;
if (ESIS_CKSUM_REQUIRED(pdu) && iso_check_csum(m0, (int)pdu->esis_hdr_len)) {
esis_stat.es_badcsum++;
goto bad;
}
if (pdu->esis_vers != ESIS_VERSION) {
esis_stat.es_badvers++;
goto bad;
}
type = pdu->esis_type & 0x1f;
switch (type) {
case ESIS_ESH:
esis_eshinput(m0, shp);
break;
case ESIS_ISH:
esis_ishinput(m0, shp);
break;
case ESIS_RD:
esis_rdinput(m0, shp);
break;
default:
esis_stat.es_badtype++;
}
bad:
if (esis_pcb.rcb_next != &esis_pcb)
isis_input(m0, shp);
else
m_freem(m0);
}
esis_rdoutput(inbound_shp, inbound_m, inbound_oidx, rd_dstnsap, rt)
struct snpa_hdr *inbound_shp;
struct mbuf *inbound_m;
struct clnp_optidx *inbound_oidx;
struct iso_addr *rd_dstnsap;
struct rtentry *rt;
{
struct mbuf *m, *m0;
caddr_t cp;
struct esis_fixed *pdu;
int len, total_len = 0;
struct sockaddr_iso siso;
struct ifnet *ifp = inbound_shp->snh_ifp;
struct sockaddr_dl *sdl;
struct iso_addr *rd_gwnsap;
if (rt->rt_flags & RTF_GATEWAY) {
rd_gwnsap = &((struct sockaddr_iso *)rt->rt_gateway)->siso_addr;
rt = rtalloc1(rt->rt_gateway, 0);
} else
rd_gwnsap = &((struct sockaddr_iso *)rt_key(rt))->siso_addr;
if (rt == 0 || (sdl = (struct sockaddr_dl *)rt->rt_gateway) == 0 ||
sdl->sdl_family != AF_LINK) {
esis_stat.es_badtype++;
return;
}
esis_stat.es_rdsent++;
IFDEBUG(D_ESISOUTPUT)
printf("esis_rdoutput: ifp x%x (%s%d), ht %d, m x%x, oidx x%x\n",
ifp, ifp->if_name, ifp->if_unit, esis_holding_time, inbound_m,
inbound_oidx);
printf("\tdestination: %s\n", clnp_iso_addrp(rd_dstnsap));
printf("\tredirected toward:%s\n", clnp_iso_addrp(rd_gwnsap));
ENDDEBUG
if ((m0 = m = m_gethdr(M_DONTWAIT, MT_HEADER)) == NULL) {
esis_stat.es_nomem++;
return;
}
bzero(mtod(m, caddr_t), MHLEN);
pdu = mtod(m, struct esis_fixed *);
cp = (caddr_t)(pdu + 1);
len = sizeof(struct esis_fixed);
pdu->esis_proto_id = ISO9542_ESIS;
pdu->esis_vers = ESIS_VERSION;
pdu->esis_type = ESIS_RD;
HTOC(pdu->esis_ht_msb, pdu->esis_ht_lsb, esis_holding_time);
(void) esis_insert_addr(&cp, &len, rd_dstnsap, m, 0);
*cp++ = sdl->sdl_alen;
bcopy(LLADDR(sdl), cp, sdl->sdl_alen);
cp += sdl->sdl_alen;
len += (sdl->sdl_alen + 1);
if (!iso_addrmatch1(rd_dstnsap, rd_gwnsap)) {
(void) esis_insert_addr(&cp, &len, rd_gwnsap, m, 0);
} else {
*cp++ = 0;
len++;
}
m->m_len = len;
if (inbound_oidx) {
int optlen = 0;
if (inbound_oidx->cni_qos_formatp)
optlen += (inbound_oidx->cni_qos_len + 2);
if (inbound_oidx->cni_priorp)
optlen += 3;
if (inbound_oidx->cni_securep)
optlen += (inbound_oidx->cni_secure_len + 2);
if (M_TRAILINGSPACE(m) < optlen) {
EXTEND_PACKET(m, m0, cp);
m->m_len = 0;
}
if (inbound_oidx->cni_qos_formatp) {
bcopy(mtod(inbound_m, caddr_t) + inbound_oidx->cni_qos_formatp - 2,
cp, (unsigned)(inbound_oidx->cni_qos_len + 2));
cp += inbound_oidx->cni_qos_len + 2;
}
if (inbound_oidx->cni_priorp) {
bcopy(mtod(inbound_m, caddr_t) + inbound_oidx->cni_priorp - 2,
cp, 3);
cp += 3;
}
if (inbound_oidx->cni_securep) {
bcopy(mtod(inbound_m, caddr_t) + inbound_oidx->cni_securep - 2, cp,
(unsigned)(inbound_oidx->cni_secure_len + 2));
cp += inbound_oidx->cni_secure_len + 2;
}
m->m_len += optlen;
len += optlen;
}
pdu->esis_hdr_len = m0->m_pkthdr.len = len;
iso_gen_csum(m0, ESIS_CKSUM_OFF, (int)pdu->esis_hdr_len);
bzero((caddr_t)&siso, sizeof(siso));
siso.siso_family = AF_ISO;
siso.siso_data[0] = AFI_SNA;
siso.siso_nlen = 6 + 1;
bcopy(inbound_shp->snh_shost, siso.siso_data + 1, 6);
(ifp->if_output)(ifp, m0, (struct sockaddr *)&siso, 0);
}
esis_insert_addr(buf, len, isoa, m, nsellen)
register caddr_t *buf;
int *len;
register struct iso_addr *isoa;
register struct mbuf *m;
int nsellen;
{
register int newlen, result = 0;
isoa->isoa_len -= nsellen;
newlen = isoa->isoa_len + 1;
if (newlen <= M_TRAILINGSPACE(m)) {
bcopy((caddr_t)isoa, *buf, newlen);
*len += newlen;
*buf += newlen;
m->m_len += newlen;
result = 1;
}
isoa->isoa_len += nsellen;
return (result);
}
#define ESIS_EXTRACT_ADDR(d, b) { d = (struct iso_addr *)(b); b += (1 + *b); \
if (b > buflim) {esis_stat.es_toosmall++; goto bad;}}
#define ESIS_NEXT_OPTION(b) { b += (2 + b[1]); \
if (b > buflim) {esis_stat.es_toosmall++; goto bad;}}
int ESHonly = 0;
esis_eshinput(m, shp)
struct mbuf *m;
struct snpa_hdr *shp;
{
struct esis_fixed *pdu = mtod(m, struct esis_fixed *);
u_short ht;
struct iso_addr *nsap;
int naddr;
u_char *buf = (u_char *)(pdu + 1);
u_char *buflim = pdu->esis_hdr_len + (u_char *)pdu;
int new_entry = 0;
esis_stat.es_eshrcvd++;
CTOH(pdu->esis_ht_msb, pdu->esis_ht_lsb, ht);
naddr = *buf++;
if (buf >= buflim)
goto bad;
if (naddr == 1) {
ESIS_EXTRACT_ADDR(nsap, buf);
new_entry = snpac_add(shp->snh_ifp,
nsap, shp->snh_shost, SNPA_ES, ht, 0);
} else {
int nsellength = 0, nlen = 0;
{
register struct ifaddr *ifa = shp->snh_ifp->if_addrlist;
for (; ifa; ifa = ifa->ifa_next)
if (ifa->ifa_addr->sa_family == AF_ISO) {
nsellength = ((struct iso_ifaddr *)ifa)->ia_addr.siso_tlen;
break;
}
}
IFDEBUG(D_ESISINPUT)
printf("esis_eshinput: esh: ht %d, naddr %d nsellength %d\n",
ht, naddr, nsellength);
ENDDEBUG
while (naddr-- > 0) {
struct iso_addr *nsap2; u_char *buf2;
ESIS_EXTRACT_ADDR(nsap, buf);
if (nsellength != 0) for (buf2 = buf; buf2 < buflim;) {
ESIS_EXTRACT_ADDR(nsap2, buf2);
IFDEBUG(D_ESISINPUT)
printf("esis_eshinput: comparing %s ",
clnp_iso_addrp(nsap));
printf("and %s\n", clnp_iso_addrp(nsap2));
ENDDEBUG
if (Bcmp(nsap->isoa_genaddr, nsap2->isoa_genaddr,
nsap->isoa_len - nsellength) == 0) {
nlen = nsellength;
break;
}
}
new_entry |= snpac_add(shp->snh_ifp,
nsap, shp->snh_shost, SNPA_ES, ht, nlen);
nlen = 0;
}
}
IFDEBUG(D_ESISINPUT)
printf("esis_eshinput: nsap %s is %s\n",
clnp_iso_addrp(nsap), new_entry ? "new" : "old");
ENDDEBUG
if (new_entry && (iso_systype & SNPA_IS))
esis_shoutput(shp->snh_ifp, ESIS_ISH, esis_holding_time,
shp->snh_shost, 6, (struct iso_addr *)0);
bad:
return;
}
esis_ishinput(m, shp)
struct mbuf *m;
struct snpa_hdr *shp;
{
struct esis_fixed *pdu = mtod(m, struct esis_fixed *);
u_short ht, newct;
struct iso_addr *nsap;
register u_char *buf = (u_char *) (pdu + 1);
register u_char *buflim = pdu->esis_hdr_len + (u_char *)pdu;
int new_entry;
esis_stat.es_ishrcvd++;
CTOH(pdu->esis_ht_msb, pdu->esis_ht_lsb, ht);
IFDEBUG(D_ESISINPUT)
printf("esis_ishinput: ish: ht %d\n", ht);
ENDDEBUG
if (ESHonly)
goto bad;
ESIS_EXTRACT_ADDR(nsap, buf);
while (buf < buflim) {
switch (*buf) {
case ESISOVAL_ESCT:
if (iso_systype & SNPA_IS)
break;
if (buf[1] != 2)
goto bad;
CTOH(buf[2], buf[3], newct);
if (esis_config_time != newct) {
untimeout(esis_config,0);
esis_config_time = newct;
esis_config();
}
break;
default:
printf("Unknown ISH option: %x\n", *buf);
}
ESIS_NEXT_OPTION(buf);
}
new_entry = snpac_add(shp->snh_ifp, nsap, shp->snh_shost, SNPA_IS, ht, 0);
IFDEBUG(D_ESISINPUT)
printf("esis_ishinput: nsap %s is %s\n",
clnp_iso_addrp(nsap), new_entry ? "new" : "old");
ENDDEBUG
if (new_entry)
esis_shoutput(shp->snh_ifp,
iso_systype & SNPA_ES ? ESIS_ESH : ESIS_ISH,
esis_holding_time, shp->snh_shost, 6, (struct iso_addr *)0);
bad:
return;
}
esis_rdinput(m0, shp)
struct mbuf *m0;
struct snpa_hdr *shp;
{
struct esis_fixed *pdu = mtod(m0, struct esis_fixed *);
u_short ht;
struct iso_addr *da, *net = 0, *netmask = 0, *snpamask = 0;
register struct iso_addr *bsnpa;
register u_char *buf = (u_char *)(pdu + 1);
register u_char *buflim = pdu->esis_hdr_len + (u_char *)pdu;
esis_stat.es_rdrcvd++;
if (iso_systype & SNPA_IS)
return;
if (ESHonly)
return;
CTOH(pdu->esis_ht_msb, pdu->esis_ht_lsb, ht);
if (buf >= buflim)
return;
ESIS_EXTRACT_ADDR(da, buf);
ESIS_EXTRACT_ADDR(bsnpa, buf);
if (buf < buflim) {
if (*buf == 0)
buf++;
else
ESIS_EXTRACT_ADDR(net, buf);
}
while (buf < buflim) {
switch (*buf) {
case ESISOVAL_SNPAMASK:
if (snpamask)
return;
snpamask = (struct iso_addr *)(buf + 1);
break;
case ESISOVAL_NETMASK:
if (netmask)
return;
netmask = (struct iso_addr *)(buf + 1);
break;
default:
printf("Unknown option in ESIS RD (0x%x)\n", buf[-1]);
}
ESIS_NEXT_OPTION(buf);
}
IFDEBUG(D_ESISINPUT)
printf("esis_rdinput: rd: ht %d, da %s\n", ht, clnp_iso_addrp(da));
if (net)
printf("\t: net %s\n", clnp_iso_addrp(net));
ENDDEBUG
if (net == 0 || net->isoa_len == 0 || snpamask) {
snpac_add(shp->snh_ifp, da,
bsnpa->isoa_genaddr, SNPA_ES, ht, 0);
} else {
snpac_add(shp->snh_ifp, net,
bsnpa->isoa_genaddr, SNPA_IS, ht, 0);
snpac_addrt(shp->snh_ifp, da, net, netmask);
}
bad: ;
}
void
esis_config()
{
register struct ifnet *ifp;
timeout(esis_config, (caddr_t)0, hz * esis_config_time);
for (ifp = ifnet; ifp; ifp = ifp->if_next) {
if ((ifp->if_flags & IFF_UP) &&
(ifp->if_flags & IFF_BROADCAST)) {
struct ifaddr *ia;
for (ia = ifp->if_addrlist; ia; ia = ia->ifa_next) {
if (ia->ifa_addr->sa_family == AF_ISO) {
esis_shoutput(ifp,
iso_systype & SNPA_ES ? ESIS_ESH : ESIS_ISH,
esis_holding_time,
(caddr_t)(iso_systype & SNPA_ES ? all_is_snpa :
all_es_snpa), 6, (struct iso_addr *)0);
break;
}
}
}
}
}
esis_shoutput(ifp, type, ht, sn_addr, sn_len, isoa)
struct ifnet *ifp;
int type;
short ht;
caddr_t sn_addr;
int sn_len;
struct iso_addr *isoa;
{
struct mbuf *m, *m0;
caddr_t cp, naddrp;
int naddr = 0;
struct esis_fixed *pdu;
struct iso_ifaddr *ia;
int len;
struct sockaddr_iso siso;
if (type == ESIS_ESH)
esis_stat.es_eshsent++;
else if (type == ESIS_ISH)
esis_stat.es_ishsent++;
else {
printf("esis_shoutput: bad pdu type\n");
return;
}
IFDEBUG(D_ESISOUTPUT)
int i;
printf("esis_shoutput: ifp x%x (%s%d), %s, ht %d, to: [%d] ",
ifp, ifp->if_name, ifp->if_unit, type == ESIS_ESH ? "esh" : "ish",
ht, sn_len);
for (i=0; i<sn_len; i++)
printf("%x%c", *(sn_addr+i), i < (sn_len-1) ? ':' : ' ');
printf("\n");
ENDDEBUG
if ((m0 = m = m_gethdr(M_DONTWAIT, MT_HEADER)) == NULL) {
esis_stat.es_nomem++;
return;
}
bzero(mtod(m, caddr_t), MHLEN);
pdu = mtod(m, struct esis_fixed *);
naddrp = cp = (caddr_t)(pdu + 1);
len = sizeof(struct esis_fixed);
pdu->esis_proto_id = ISO9542_ESIS;
pdu->esis_vers = ESIS_VERSION;
pdu->esis_type = type;
HTOC(pdu->esis_ht_msb, pdu->esis_ht_lsb, ht);
if (type == ESIS_ESH) {
cp++;
len++;
}
m->m_len = len;
if (isoa) {
(void) esis_insert_addr(&cp, &len, isoa, m, 0);
naddr = 1;
}
for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
int nsellen = (type == ESIS_ISH ? ia->ia_addr.siso_tlen : 0);
int n = ia->ia_addr.siso_nlen;
register struct iso_ifaddr *ia2;
if (type == ESIS_ISH && naddr > 0)
break;
for (ia2 = iso_ifaddr; ia2 != ia; ia2 = ia2->ia_next)
if (Bcmp(ia->ia_addr.siso_data, ia2->ia_addr.siso_data, n) == 0)
break;
if (ia2 != ia)
continue;
if (isoa && Bcmp(ia->ia_addr.siso_data, isoa->isoa_genaddr, n) == 0) {
isoa = 0;
continue;
}
IFDEBUG(D_ESISOUTPUT)
printf("esis_shoutput: adding NSAP %s\n",
clnp_iso_addrp(&ia->ia_addr.siso_addr));
ENDDEBUG
if (!esis_insert_addr(&cp, &len,
&ia->ia_addr.siso_addr, m, nsellen)) {
EXTEND_PACKET(m, m0, cp);
(void) esis_insert_addr(&cp, &len, &ia->ia_addr.siso_addr, m,
nsellen);
}
naddr++;
}
if (type == ESIS_ESH)
*naddrp = naddr;
else {
if (M_TRAILINGSPACE(m) < 4) {
printf("esis_shoutput: extending packet\n");
EXTEND_PACKET(m, m0, cp);
}
*cp++ = ESISOVAL_ESCT;
*cp++ = 2;
HTOC(*cp, *(cp+1), esis_esconfig_time);
len += 4;
m->m_len += 4;
IFDEBUG(D_ESISOUTPUT)
printf("m0 0x%x, m 0x%x, data 0x%x, len %d, cp 0x%x\n",
m0, m, m->m_data, m->m_len, cp);
ENDDEBUG
}
m0->m_pkthdr.len = len;
pdu->esis_hdr_len = len;
iso_gen_csum(m0, ESIS_CKSUM_OFF, (int)pdu->esis_hdr_len);
bzero((caddr_t)&siso, sizeof(siso));
siso.siso_family = AF_ISO;
siso.siso_data[0] = AFI_SNA;
siso.siso_nlen = sn_len + 1;
bcopy(sn_addr, siso.siso_data + 1, (unsigned)sn_len);
(ifp->if_output)(ifp, m0, (struct sockaddr *)&siso, 0);
}
isis_input(m0, shp)
struct mbuf *m0;
struct snpa_hdr *shp;
{
register int type;
register struct rawcb *rp, *first_rp = 0;
struct ifnet *ifp = shp->snh_ifp;
char workbuf[16];
struct mbuf *mm;
IFDEBUG(D_ISISINPUT)
int i;
printf("isis_input: pkt on ifp x%x (%s%d): from:", ifp,
ifp->if_name, ifp->if_unit);
for (i=0; i<6; i++)
printf("%x%c", shp->snh_shost[i]&0xff, (i<5) ? ':' : ' ');
printf(" to:");
for (i=0; i<6; i++)
printf("%x%c", shp->snh_dhost[i]&0xff, (i<5) ? ':' : ' ');
printf("\n");
ENDDEBUG
esis_dl.sdl_alen = ifp->if_addrlen;
esis_dl.sdl_index = ifp->if_index;
bcopy(shp->snh_shost, (caddr_t)esis_dl.sdl_data, esis_dl.sdl_alen);
for (rp = esis_pcb.rcb_next; rp != &esis_pcb; rp = rp->rcb_next) {
if (first_rp == 0) {
first_rp = rp;
continue;
}
if (mm = m_copy(m0, 0, M_COPYALL)) {
if (sbappendaddr(&rp->rcb_socket->so_rcv,
&esis_dl, mm, (struct mbuf *)0) != 0) {
sorwakeup(rp->rcb_socket);
} else {
IFDEBUG(D_ISISINPUT)
printf("Error in sbappenaddr, mm = 0x%x\n", mm);
ENDDEBUG
m_freem(mm);
}
}
}
if (first_rp && sbappendaddr(&first_rp->rcb_socket->so_rcv,
&esis_dl, m0, (struct mbuf *)0) != 0) {
sorwakeup(first_rp->rcb_socket);
return;
}
m_freem(m0);
}
isis_output(sdl, m)
register struct sockaddr_dl *sdl;
struct mbuf *m;
{
register struct ifnet *ifp;
struct ifaddr *ifa, *ifa_ifwithnet();
struct sockaddr_iso siso;
int error = 0;
unsigned sn_len;
ifa = ifa_ifwithnet((struct sockaddr *)sdl);
if (ifa == 0) {
IFDEBUG(D_ISISOUTPUT)
printf("isis_output: interface not found\n");
ENDDEBUG
error = EINVAL;
goto release;
}
ifp = ifa->ifa_ifp;
sn_len = sdl->sdl_alen;
IFDEBUG(D_ISISOUTPUT)
u_char *cp = (u_char *)LLADDR(sdl), *cplim = cp + sn_len;
printf("isis_output: ifp 0x%x (%s%d), to: ",
ifp, ifp->if_name, ifp->if_unit);
while (cp < cplim) {
printf("%x", *cp++);
printf("%c", (cp < cplim) ? ':' : ' ');
}
printf("\n");
ENDDEBUG
bzero((caddr_t)&siso, sizeof(siso));
siso.siso_family = AF_ISO;
siso.siso_data[0] = AFI_SNA;
siso.siso_nlen = sn_len + 1;
bcopy(LLADDR(sdl), siso.siso_data + 1, sn_len);
error = (ifp->if_output)(ifp, m, (struct sockaddr *)&siso, 0);
if (error) {
IFDEBUG(D_ISISOUTPUT)
printf("isis_output: error from ether_output is %d\n", error);
ENDDEBUG
}
return (error);
release:
if (m != NULL)
m_freem(m);
return(error);
}
esis_ctlinput(req, siso)
int req;
struct sockaddr_iso *siso;
{
register struct iso_ifaddr *ia;
if (req == PRC_IFDOWN)
for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
if (iso_addrmatch(IA_SIS(ia), siso))
snpac_flushifp(ia->ia_ifp);
}
}
#endif