/* 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 #include 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 */