/* From ddp.c:
ddp_shrink_hdr()
ddp_extend_hdr()
Saved from xnu/bsd/bsd/netat/ddp.c on 4/14/99.
*/
#ifdef NOT_USED
/* This routine shrinks the ddp header from long to short,
* It also prepends ALAP header and fills up some of the
* fields as appropriate.
*/
static at_ddp_short_t *ddp_shrink_hdr (mp)
register gbuf_t *mp;
{
register at_ddp_t *ddp;
register at_ddp_short_t *ddp_short;
register at_llap_hdr_t *llap;
gbuf_t *newmp;
if ((newmp = (gbuf_t *)gbuf_copym((gbuf_t *) mp)) == (gbuf_t *)NULL)
return ((at_ddp_short_t *)NULL);
gbuf_freem(mp);
mp = newmp;
ddp = (at_ddp_t *)gbuf_rptr(mp);
gbuf_rinc(mp,((DDP_X_HDR_SIZE - DDP_HDR_SIZE) - LLAP_HDR_SIZE));
llap = (at_llap_hdr_t *)gbuf_rptr(mp);
ddp_short = (at_ddp_short_t *)(gbuf_rptr(mp) + LLAP_HDR_SIZE);
llap->destination = ddp->dst_node;
llap->type = LLAP_TYPE_DDP;
ddp_short->length = ddp->length - (DDP_X_HDR_SIZE - DDP_HDR_SIZE);
ddp_short->unused = 0;
return ((at_ddp_short_t *)mp);
}
/* mp points to message of the form {llap, short ddp, ...}.
* Get rid of llap, extend ddp header to make it of the form
* {extended ddp, ... }
*/
static gbuf_t *ddp_extend_hdr(mp)
register gbuf_t *mp;
{
register at_llap_hdr_t *llap;
register at_ddp_short_t *ddp_short;
register at_ddp_t *ddp;
char buf[DDP_HDR_SIZE + LLAP_HDR_SIZE];
gbuf_t *m1, *m2;
/* We need to remove the llap header from the packet and extend the
* short DDP header in to a long one. 5 bytes of additional space
* is required in effect, but we can not afford to put these 5 bytes
* in a separate buffer, since the ddp buffer would end up being
* fragmented into two pieces, which is a no-no. So, we first get
* rid of the llap and ddp short headers and then add the extended
* header.
*/
/* Assuming that the llap and ddp short headers are placed next
* to each other in the same buffer
*/
bcopy(gbuf_rptr(mp), buf, LLAP_HDR_SIZE + DDP_HDR_SIZE);
m1 = ddp_adjmsg(mp, LLAP_HDR_SIZE+DDP_HDR_SIZE) ? mp : 0;
/* If the message did not contain any ddp data bytes, then m would
* be NULL at this point... and we can't just grow a NULL message,
* we need to ALLOC a new one.
*/
if (m1) {
if ((m2 = (gbuf_t *)ddp_growmsg(m1, -DDP_X_HDR_SIZE)) == NULL) {
dPrintf(D_M_DDP, D_L_WARNING,
("Dropping packet - no bufs to extend hdr"));
at_ddp_stats.rcv_dropped_nobuf++;
gbuf_freem(m1);
return(NULL);
}
} else
/* Original message mp has already been freed by ddp_adjmsg if we
* managed to arrive here... this case occurs only when the
* message mp did not contain any ddp data bytes, only lap and
* ddp headers
*/
if ((m2 = gbuf_alloc(AT_WR_OFFSET+DDP_X_HDR_SIZE, PRI_MED)) == NULL) {
dPrintf(D_M_DDP,D_L_WARNING,
("Packet (no data) dropped - no bufs to extend hdr"));
at_ddp_stats.rcv_dropped_nobuf++;
return(NULL);
} else {
gbuf_rinc(m2,AT_WR_OFFSET);
gbuf_wset(m2,DDP_X_HDR_SIZE);
}
/* By the time we arrive here, m2 points to message of the form
* {Extended DDP, ... }
* mp and m1 are either non-existent or irrelevant.
*/
ddp = (at_ddp_t *)gbuf_rptr(m2);
llap = (at_llap_hdr_t *)buf;
ddp_short = (at_ddp_short_t *)(buf + LLAP_HDR_SIZE);
ddp->unused = ddp->hopcount = 0;
ddp->length = ddp_short->length + DDP_X_HDR_SIZE - DDP_HDR_SIZE;
UAS_ASSIGN(ddp->checksum, 0);
NET_NET(ddp->dst_net, ifID_home->ifThisNode.atalk_net);
NET_NET(ddp->src_net, ifID_home->ifThisNode.atalk_net);
ddp->src_node = llap->source;
ddp->dst_node = llap->destination;
ddp->dst_socket = ddp_short->dst_socket;
ddp->src_socket = ddp_short->src_socket;
ddp->type = ddp_short->type;
return (m2);
}
#endif
From sys_dep.c:
#ifdef _AIX /* This AIX code (to the end of this file) is no longer supported. */
int ATsocket(proto) /* AIX version */
int proto;
{
int err, rc = -1;
if (sys_ATsocket)
rc = (*sys_ATsocket)(proto, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
int ATgetmsg(fd, ctlptr, datptr, flags) /* AIX version */
int fd;
void *ctlptr;
void *datptr;
int *flags;
{
int err, rc = -1;
if (sys_ATgetmsg)
rc = (*sys_ATgetmsg)(fd, ctlptr, datptr, flags, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
int ATputmsg(fd, ctlptr, datptr, flags) /* AIX version */
int fd;
void *ctlptr;
void *datptr;
int flags;
{
int err, rc = -1;
if (sys_ATputmsg)
rc = (*sys_ATputmsg)(fd, ctlptr, datptr, flags, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
int ATPsndreq(fd, buf, len, nowait) /* AIX version */
int fd;
unsigned char *buf;
int len;
int nowait;
{
int err, rc = -1;
if (sys_ATPsndreq)
rc = (*sys_ATPsndreq)(fd, buf, len, nowait, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
int ATPsndrsp(fd, respbuff, resplen, datalen) /* AIX version */
int fd;
unsigned char *respbuff;
int resplen;
int datalen;
{
int err, rc = -1;
if (sys_ATPsndrsp)
rc = (*sys_ATPsndrsp)(fd, respbuff, resplen, datalen, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
int ATPgetreq(fd, buf, buflen) /* AIX version */
int fd;
unsigned char *buf;
int buflen;
{
int err, rc = -1;
if (sys_ATPgetreq)
rc = (*sys_ATPgetreq)(fd, buf, buflen, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
int ATPgetrsp(fd, bdsp) /* AIX version */
int fd;
unsigned char *bdsp;
{
int err, rc = -1;
if (sys_ATPgetrsp)
rc = (*sys_ATPgetrsp)(fd, bdsp, &err, 0);
else
err = ENXIO;
if (err)
setuerror(err);
return rc;
}
void *atalk_kalloc(size) /* AIX version */
int size;
{
return (void *)xmalloc(size, 2, pinned_heap);
}
void atalk_kfree(buf) /* AIX version */
void *buf;
{
xmfree(buf, pinned_heap);
}
int atalk_closeref(fp, grefp) /* AIX version */
struct file *fp;
gref_t **grefp;
{
*grefp = (gref_t *)fp->f_data;
fp->f_data = 0;
return 0;
}
int atalk_openref(gref, retfd, proc) /* AIX version */
gref_t *gref;
int *retfd;
void *proc;
{
extern int _ATrw(), _ATioctl(), _ATselect(), _ATclose(), _ATstat();
static struct fileops fileops = {_ATrw, _ATioctl, _ATselect, _ATclose, _ATstat};
int err, fd;
struct file *fp;
void *crp;
crp = (void *)crref();
#ifdef _AIX
if ((err = ufdcreate(FREAD|FWRITE,
&fileops, 0, DTYPE_OTHER, &fd, crp)) != 0)
#else
if ((err = ufdcreate(FREAD|FWRITE,
&fileops, 0, DTYPE_ATALK, &fd, crp)) != 0)
#endif
return err;
*retfd = fd;
fp = U.U_ufd[fd].fp;
fp->f_data = (void *)gref;
gref->next = (void *)fp;
return 0;
}
int atalk_getref(fp, fd, grefp, proc) /* AIX version */
struct file *fp;
int fd;
gref_t **grefp;
struct proc *proc;
{
if (fp == 0) {
if ((fd < 0) || (fd > U.U_maxofile) || ((fp = U.U_ufd[fd].fp) == 0)) {
*grefp = (gref_t *)0;
return EBADF;
}
}
if ((*grefp = (gref_t *)fp->f_data) == 0)
return EBADF;
return 0;
}
gbuf_t *gbuf_alloc(size, pri) /* AIX version */
int size;
int pri;
{
gbuf_t *m;
m = (size > MHLEN) ? (gbuf_t *)m_getclustm(M_DONTWAIT, MSG_DATA, size)
: (gbuf_t *)m_gethdr(M_DONTWAIT, MSG_DATA);
#ifdef APPLETALK_DEBUG
kprintf("gbuf_alloc: for size = %d m=%x\n", size, m);
#endif
gbuf_next(m) = 0;
gbuf_cont(m) = 0;
gbuf_wset(m,0);
return m;
}
void gbuf_freeb(m) /* AIX version */
gbuf_t *m;
{
if (m)
m_free(m);
}
static struct trb *trb_freehead = 0;
static struct trb *trb_freetail = 0;
static struct trb *trb_pendhead = 0;
static int trb_cnt = 0;
static atlock_t trb_lock;
static void atalk_rem_timeoutcf() /* AIX version */
{
register int s;
register struct trb *trb;
register struct trb *tmp_freehead, *tmp_pendhead;
ATDISABLE(s, trb_lock);
tmp_freehead = trb_freehead;
trb_freehead = 0;
tmp_pendhead = trb_pendhead;
trb_pendhead = 0;
trb_cnt = 0;
ATENABLE(s, trb_lock);
while ((trb = tmp_pendhead) != 0) {
tmp_pendhead = trb->to_next;
while (tstop(trb));
tfree(trb);
}
while ((trb = tmp_freehead) != 0) {
tmp_freehead = trb->to_next;
tfree(trb);
}
dPrintf(D_M_ATP,D_L_ERROR, "atalk: timer stopped!\n",0,0,0,0,0);
}
static void atalk_timeoutcf(cnt) /* AIX version */
int cnt;
{
register int i;
register struct trb *trb;
if (trb_freehead == 0) {
for (i=0; i < cnt-1; i++) {
trb = (struct trb *)talloc();
trb->to_next = trb_freehead;
trb_freehead = trb;
if (!i) trb_freetail = trb;
trb_cnt++;
}
}
ATLOCKINIT(trb_lock);
}
static void atalk_clock(trb) /* AIX version */
register struct trb *trb;
{
register int s;
register struct trb *next;
void (*tof)();
void *arg;
ATDISABLE(s, trb_lock);
if (trb_pendhead && trb->func) {
/*
* remove the timeout from the pending queue
*/
if (trb_pendhead == trb)
trb_pendhead = trb->to_next;
else {
for (next=trb_pendhead; next->to_next; next=next->to_next) {
if (next->to_next == trb) {
next->to_next = trb->to_next;
trb->func = 0;
break;
}
}
if (trb->func) {
dPrintf(D_M_ATP,D_L_WARNING,
"atalk_clock: %d,%x,%x\n", trb_cnt,trb,trb_pendhead,0,0);
/*
* we have not found the trb in the pending list - something
* has gone wrong here. maybe the trb has been returned to
* the free list; in which case, we should simply ignore
* this timeout event!
*/
for (next=trb_freehead; next; next=next->to_next) {
if (next == trb)
{
ATENABLE(s, trb_lock);
return;
}
}
/*
* the trb is not in the free list either - something has
* really gone wacky here! all we can do now is put the
* trb back into the free list and hope that it will be ok.
*/
trb->to_next = 0;
if (trb_freehead)
trb_freetail->to_next = trb;
else
trb_freehead = trb;
trb_freetail = trb;
trb_cnt++;
ATENABLE(s, trb_lock);
return;
}
}
/*
* process the timeout
*/
trb->func = 0;
trb->to_next = 0;
tof = trb->tof;
trb->tof = 0;
arg = (void *)trb->func_data;
trb->func_data = 999;
if (trb_freehead)
trb_freetail->to_next = trb;
else
trb_freehead = trb;
trb_freetail = trb;
trb_cnt++;
ATENABLE(s, trb_lock);
if (tof) {
dPrintf(D_M_ATP,D_L_VERBOSE, "atalk_clock: func=%x, arg=%x, %d\n",
tof,arg,trb_cnt,0,0);
(*tof)(arg);
} else {
dPrintf(D_M_ATP,D_L_ERROR, "atalk_clock: func=%x, arg=%x, %d\n",
tof,arg,trb_cnt,0,0);
}
} else
ATENABLE(s, trb_lock);
}
void *atalk_timeout(func, arg, ticks) /* AIX version */
void (*func)();
void *arg;
int ticks;
{
register int s;
register struct trb *trb;
dPrintf(D_M_ATP,D_L_VERBOSE,
"atalk_timeout: func=%x,arg=%x,time=%d, %d,%x\n", func,arg,ticks,trb_cnt,trb_pendhead);
/*
* set up the timeout request
*/
ATDISABLE(s, trb_lock);
if ((trb = trb_freehead) == 0) {
ATENABLE(s, trb_lock);
dPrintf(D_M_ATP,D_L_WARNING,
"atalk_timeout: NO TRB! time=%d, %d\n", ticks,trb_cnt,0,0,0);
return 0;
}
trb_freehead = trb->to_next;
trb->to_next = trb_pendhead;
trb_pendhead = trb;
trb_cnt--;
trb->timeout.it_value.tv_sec = ticks / HZ;
trb->timeout.it_value.tv_nsec = (ticks % HZ) * (NS_PER_SEC / HZ);
trb->knext = 0;
trb->kprev = 0;
trb->flags = 0;
trb->tof = func;
trb->func = (void (*)())atalk_clock;
trb->func_data = (ulong)arg;
trb->ipri = PL_IMP;
trb->id = -1;
/*
* start the timeout
*/
ATENABLE(s, trb_lock);
tstart(trb);
return (void *)trb;
}
void atalk_untimeout(func, arg, trb) /* AIX version */
void (*func)();
void *arg;
register struct trb *trb;
{
register int s;
register struct trb *next;
dPrintf(D_M_ATP,D_L_VERBOSE,
"atalk_untimeout: func=%x,arg=%x, %d\n", func,arg,trb_cnt,0,0);
ATDISABLE(s, trb_lock);
if (trb == 0) {
for (trb=trb_pendhead; trb; trb=trb->to_next) {
if ((func == trb->tof) && (arg == (void *)trb->func_data))
break;
}
}
if (trb && (trb->func == (void (*)())atalk_clock)
&& (func == trb->tof) && (arg == (void *)trb->func_data)) {
trb->func_data = 999;
if (!(trb->flags & T_PENDING))
{
trb->tof = 0;
ATENABLE(s, trb_lock);
return;
}
trb->func = 0;
while (tstop(trb));
if (trb_pendhead == trb)
trb_pendhead = trb->to_next;
else {
for (next=trb_pendhead; next->to_next != trb; next=next->to_next) {
if (next->to_next == 0) {
ATENABLE(s, trb_lock);
dPrintf(D_M_ATP,D_L_WARNING,
"atalk_untimeout: UNKNOWN TRB %x...\n",trb,0,0,0,0);
return;
}
}
next->to_next = trb->to_next;
}
trb->to_next = 0;
trb_freetail->to_next = trb;
trb_freetail = trb;
trb_cnt++;
}
ATENABLE(s, trb_lock);
}
int config_atalk(dev, cmd, uiop) /* AIX only */
dev_t dev;
int cmd;
void *uiop;
{
static int loaded = 0;
int err, nest;
err = 0;
nest = lockl(&kernel_lock, LOCK_SHORT);
if (cmd == CFG_INIT) {
if (loaded)
goto out;
vm_protect(0, 4096, 3);
atalk_timeoutcf(256);
atalk_load();
loaded = 1;
} else if (cmd == CFG_TERM) {
if (!loaded)
goto out;
atalk_rem_timeoutcf();
atalk_unload();
loaded = 0;
} else
err = EINVAL;
out:
if (nest != LOCK_NEST)
unlockl(&kernel_lock);
return(err);
}
#endif
From sys_glue.c:
#ifdef _AIX /* AIX code, to the end of this file, is no longer supported. */
int _ATselect(fp, corl, reqevents, retevents, notify) /* AIX version */
void *fp;
int corl;
unsigned short reqevents;
unsigned short *retevents;
void (*notify)();
{
int s, err, rc = 0;
gref_t *gref;
unsigned short sevents = 0;
if ((err = atalk_getref(fp, 0, &gref, 0)) != 0)
return err;
ATDISABLE(s, gref->lock);
if (reqevents & POLLIN) {
if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
sevents |= POLLIN;
}
if (reqevents & POLLOUT) {
if (gref->writeable) {
if ((*gref->writeable)(gref))
sevents |= POLLOUT;
} else
sevents |= POLLOUT;
}
if ((sevents == 0) && ((reqevents & POLLSYNC) == 0)) {
if (rc = selreg(corl, 99, gref, reqevents, notify)) {
ATENABLE(s, gref->lock);
goto l_done;
}
if (reqevents & POLLIN) {
if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
sevents |= POLLIN;
else
gref->sevents |= POLLIN;
}
if (reqevents & POLLOUT) {
if (gref->writeable) {
if ((*gref->writeable)(gref))
sevents |= POLLOUT;
else
gref->sevents |= POLLOUT;
} else
sevents |= POLLOUT;
}
}
ATENABLE(s, gref->lock);
*retevents = sevents;
l_done:
return rc;
}
#endif /* end AIX section */
From drv_dep.c:
#ifdef _AIX
/* AIX section to end of file (not supported) */
/* from beginning of file ... */
#include <sys/cdli.h>
#include <sys/ndd.h>
static struct ns_8022 elap_link; /* The SNAP header description */
static struct ns_user elap_user; /* The interface to the demuxer */
int
pat_ifpresent(name) /* AIX */
char *name;
{
return (int)ifunit(name);
}
int
pat_output(pat_id, mlist, dst_addr, type) /* AIX */
int pat_id;
gbuf_t *mlist;
unsigned char *dst_addr;
int type;
{
int len;
pat_unit_t *patp;
gbuf_t *m, *m_prev, *new_mlist, *m_temp;
struct ndd *nddp;
short size;
enet_header_t *enet_header;
llc_header_t *llc_header;
patp = (pat_unit_t *)&pat_units[pat_id];
if (patp->state != PAT_ONLINE) {
gbuf_freel(mlist);
return ENOTREADY;
}
if (patp->xtype == IFTYPE_NULLTALK) {
gbuf_freel(mlist);
return 0;
}
nddp = (void *)patp->nddp;
new_mlist = 0;
for (m = mlist; m; m = mlist) {
mlist = gbuf_next(m);
gbuf_next(m) = 0;
gbuf_prepend(m,ENET_LLC_SIZE);
if (m == 0) {
if (mlist)
gbuf_freel(mlist);
if (new_mlist)
gbuf_freel(new_mlist);
return 0;
}
enet_header = (enet_header_t *)gbuf_rptr(m);
bcopy(dst_addr, enet_header->dst, sizeof(enet_header->dst));
bcopy(patp->xaddr, enet_header->src, sizeof(enet_header->src));
size = gbuf_msgsize(m);
enet_header->len = size - sizeof(enet_header_t);
llc_header = (llc_header_t *)(gbuf_rptr(m)+sizeof(enet_header_t));
*llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
m->m_pkthdr.len = size;
m->m_pkthdr.rcvif = 0;
if (new_mlist)
gbuf_next(m_prev) = m;
else
new_mlist = m;
m_prev = m;
pktsOut++;
}
if (new_mlist)
(*nddp->ndd_output)(nddp, new_mlist);
return 0;
}
int
pat_online (ifName, ifType) /* AIX */
char *ifName;
char *ifType;
{
void pat_input();
int pat_id;
pat_unit_t *patp;
struct ndd *nddp;
char ns_name[8];
if ((pat_id = pat_ID(ifName)) == -1)
return (-1);
patp = &pat_units[pat_id];
if (patp->xtype == IFTYPE_ETHERTALK) {
ns_name[0] = ifName[0];
ns_name[1] = 'n';
strcpy(&ns_name[2], &ifName[1]);
} else if (patp->xtype == IFTYPE_NULLTALK) {
patp->xaddrlen = 6;
bzero(patp->xaddr, patp->xaddrlen);
if (ifType)
*ifType = patp->xtype;
patp->nddp = (void *)0;
patp->state = PAT_ONLINE;
at_statep->flags |= AT_ST_IF_CHANGED;
return (pat_id);
} else
return -1;
if (ns_alloc(ns_name, &nddp))
return -1;
bzero(&elap_user, sizeof(elap_user));
elap_user.isr = pat_input;
elap_user.pkt_format = NS_HANDLE_HEADERS|NS_INCLUDE_MAC;
elap_link.filtertype = NS_8022_LLC_DSAP_SNAP;
elap_link.orgcode[0] = 0;
elap_link.orgcode[2] = 0;
elap_link.dsap = DSAP_SNAP;
elap_link.ethertype = 0x80f3; /* AARP SNAP code */
if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user))
return -1;
elap_link.orgcode[0] = 0x08;
elap_link.orgcode[2] = 0x07;
elap_link.ethertype = 0x809b; /* DDP SNAP code */
if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) {
elap_link.orgcode[0] = 0;
elap_link.orgcode[2] = 0;
elap_link.ethertype = 0x80f3; /* AARP SNAP code */
(void)ns_del_filter(nddp, &elap_link, sizeof(elap_link));
return -1;
}
patp->xaddrlen = nddp->ndd_addrlen;
bcopy(nddp->ndd_physaddr, patp->xaddr, patp->xaddrlen);
if (ifType)
*ifType = patp->xtype;
patp->nddp = (void *)nddp;
patp->state = PAT_ONLINE;
at_statep->flags |= AT_ST_IF_CHANGED;
return (pat_id);
}
void
pat_offline(pat_id) /* AIX */
int pat_id;
{
pat_unit_t *patp = &pat_units[pat_id];
if (patp->state == PAT_ONLINE) {
if (patp->xtype != IFTYPE_NULLTALK) {
elap_link.filtertype = NS_8022_LLC_DSAP_SNAP;
elap_link.orgcode[0] = 0;
elap_link.orgcode[2] = 0;
elap_link.dsap = DSAP_SNAP;
elap_link.ethertype = 0x80f3; /* AARP SNAP code */
(void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link));
elap_link.orgcode[0] = 0x08;
elap_link.orgcode[2] = 0x07;
elap_link.ethertype = 0x809b; /* DDP SNAP code */
(void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link));
ns_free(patp->nddp);
}
at_statep->flags |= AT_ST_IF_CHANGED;
bzero(patp, sizeof(pat_unit_t));
}
}
int
pat_mcast(pat_id, control, data) /* AIX */
int pat_id;
int control;
unsigned char *data;
{
struct ndd *nddp;
nddp = (struct ndd *)pat_units[pat_id].nddp;
return (*nddp->ndd_ctl)(nddp, (control == PAT_REG_MCAST) ?
NDD_ENABLE_ADDRESS : NDD_DISABLE_ADDRESS,
data, nddp->ndd_addrlen);
}
void
pat_input(nddp, m, unused) /* AIX */
struct ndd *nddp;
gbuf_t *m;
void *unused;
{
extern int ddprunning_flag;
llc_header_t *llc_header;
int pat_id;
pat_unit_t *patp;
char src[6];
enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m);
for (pat_id=0, patp = &pat_units[pat_id];
pat_id < xpatcnt; pat_id++, patp++) {
if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp))
break;
}
if (pat_id == xpatcnt) {
gbuf_freem(m);
return;
}
/* Ignore multicast packets from local station */
if (patp->xtype == IFTYPE_ETHERTALK) {
bcopy((char *)enet_header->src, src, sizeof(src));
if ((enet_header->dst[0] & 1) &&
(bcmp(src, patp->xaddr, sizeof(src)) == 0)) {
gbuf_freem(m);
return;
}
llc_header = (llc_header_t *)(enet_header+1);
}
gbuf_rinc(m,(ENET_LLC_SIZE));
(void)fetch_and_add((atomic_p)&ddprunning_flag, 1);
pktsIn++;
if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
patp->aarp_func(gbuf_rptr(m), patp->context);
gbuf_freem(m);
} else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) {
/* if we're a router take all pkts */
if (!ROUTING_MODE) {
if (patp->addr_check(gbuf_rptr(m), patp->context)
== AARP_ERR_NOT_OURS) {
gbuf_freem(m);
(void)fetch_and_add((atomic_p)&ddprunning_flag, -1);
return;
}
}
gbuf_set_type(m, MSG_DATA);
elap_input(m, patp->context, src);
} else
gbuf_freem(m);
(void)fetch_and_add((atomic_p)&ddprunning_flag, -1);
}
#endif /* AIX */