1/* From ddp.c: 2 3 ddp_shrink_hdr() 4 ddp_extend_hdr() 5 6 Saved from xnu/bsd/bsd/netat/ddp.c on 4/14/99. 7*/ 8 9#ifdef NOT_USED 10/* This routine shrinks the ddp header from long to short, 11 * It also prepends ALAP header and fills up some of the 12 * fields as appropriate. 13 */ 14static at_ddp_short_t *ddp_shrink_hdr (mp) 15register gbuf_t *mp; 16{ 17 register at_ddp_t *ddp; 18 register at_ddp_short_t *ddp_short; 19 register at_llap_hdr_t *llap; 20 gbuf_t *newmp; 21 22 if ((newmp = (gbuf_t *)gbuf_copym((gbuf_t *) mp)) == (gbuf_t *)NULL) 23 return ((at_ddp_short_t *)NULL); 24 gbuf_freem(mp); 25 mp = newmp; 26 27 ddp = (at_ddp_t *)gbuf_rptr(mp); 28 gbuf_rinc(mp,((DDP_X_HDR_SIZE - DDP_HDR_SIZE) - LLAP_HDR_SIZE)); 29 llap = (at_llap_hdr_t *)gbuf_rptr(mp); 30 ddp_short = (at_ddp_short_t *)(gbuf_rptr(mp) + LLAP_HDR_SIZE); 31 32 llap->destination = ddp->dst_node; 33 llap->type = LLAP_TYPE_DDP; 34 ddp_short->length = ddp->length - (DDP_X_HDR_SIZE - DDP_HDR_SIZE); 35 ddp_short->unused = 0; 36 return ((at_ddp_short_t *)mp); 37} 38 39 40/* mp points to message of the form {llap, short ddp, ...}. 41 * Get rid of llap, extend ddp header to make it of the form 42 * {extended ddp, ... } 43 */ 44static gbuf_t *ddp_extend_hdr(mp) 45register gbuf_t *mp; 46{ 47 register at_llap_hdr_t *llap; 48 register at_ddp_short_t *ddp_short; 49 register at_ddp_t *ddp; 50 char buf[DDP_HDR_SIZE + LLAP_HDR_SIZE]; 51 gbuf_t *m1, *m2; 52 53 /* We need to remove the llap header from the packet and extend the 54 * short DDP header in to a long one. 5 bytes of additional space 55 * is required in effect, but we can not afford to put these 5 bytes 56 * in a separate buffer, since the ddp buffer would end up being 57 * fragmented into two pieces, which is a no-no. So, we first get 58 * rid of the llap and ddp short headers and then add the extended 59 * header. 60 */ 61 62 /* Assuming that the llap and ddp short headers are placed next 63 * to each other in the same buffer 64 */ 65 bcopy(gbuf_rptr(mp), buf, LLAP_HDR_SIZE + DDP_HDR_SIZE); 66 m1 = ddp_adjmsg(mp, LLAP_HDR_SIZE+DDP_HDR_SIZE) ? mp : 0; 67 68 /* If the message did not contain any ddp data bytes, then m would 69 * be NULL at this point... and we can't just grow a NULL message, 70 * we need to ALLOC a new one. 71 */ 72 if (m1) { 73 if ((m2 = (gbuf_t *)ddp_growmsg(m1, -DDP_X_HDR_SIZE)) == NULL) { 74 dPrintf(D_M_DDP, D_L_WARNING, 75 ("Dropping packet - no bufs to extend hdr")); 76 at_ddp_stats.rcv_dropped_nobuf++; 77 gbuf_freem(m1); 78 return(NULL); 79 } 80 } else 81 /* Original message mp has already been freed by ddp_adjmsg if we 82 * managed to arrive here... this case occurs only when the 83 * message mp did not contain any ddp data bytes, only lap and 84 * ddp headers 85 */ 86 if ((m2 = gbuf_alloc(AT_WR_OFFSET+DDP_X_HDR_SIZE, PRI_MED)) == NULL) { 87 dPrintf(D_M_DDP,D_L_WARNING, 88 ("Packet (no data) dropped - no bufs to extend hdr")); 89 at_ddp_stats.rcv_dropped_nobuf++; 90 return(NULL); 91 } else { 92 gbuf_rinc(m2,AT_WR_OFFSET); 93 gbuf_wset(m2,DDP_X_HDR_SIZE); 94 } 95 96 /* By the time we arrive here, m2 points to message of the form 97 * {Extended DDP, ... } 98 * mp and m1 are either non-existent or irrelevant. 99 */ 100 ddp = (at_ddp_t *)gbuf_rptr(m2); 101 llap = (at_llap_hdr_t *)buf; 102 ddp_short = (at_ddp_short_t *)(buf + LLAP_HDR_SIZE); 103 104 ddp->unused = ddp->hopcount = 0; 105 ddp->length = ddp_short->length + DDP_X_HDR_SIZE - DDP_HDR_SIZE; 106 UAS_ASSIGN(ddp->checksum, 0); 107 NET_NET(ddp->dst_net, ifID_home->ifThisNode.atalk_net); 108 NET_NET(ddp->src_net, ifID_home->ifThisNode.atalk_net); 109 ddp->src_node = llap->source; 110 ddp->dst_node = llap->destination; 111 ddp->dst_socket = ddp_short->dst_socket; 112 ddp->src_socket = ddp_short->src_socket; 113 ddp->type = ddp_short->type; 114 return (m2); 115} 116#endif 117 118From sys_dep.c: 119 120#ifdef _AIX /* This AIX code (to the end of this file) is no longer supported. */ 121 122int ATsocket(proto) /* AIX version */ 123 int proto; 124{ 125 int err, rc = -1; 126 127 if (sys_ATsocket) 128 rc = (*sys_ATsocket)(proto, &err, 0); 129 else 130 err = ENXIO; 131 if (err) 132 setuerror(err); 133 return rc; 134} 135 136int ATgetmsg(fd, ctlptr, datptr, flags) /* AIX version */ 137 int fd; 138 void *ctlptr; 139 void *datptr; 140 int *flags; 141{ 142 int err, rc = -1; 143 144 if (sys_ATgetmsg) 145 rc = (*sys_ATgetmsg)(fd, ctlptr, datptr, flags, &err, 0); 146 else 147 err = ENXIO; 148 if (err) 149 setuerror(err); 150 return rc; 151} 152 153int ATputmsg(fd, ctlptr, datptr, flags) /* AIX version */ 154 int fd; 155 void *ctlptr; 156 void *datptr; 157 int flags; 158{ 159 int err, rc = -1; 160 161 if (sys_ATputmsg) 162 rc = (*sys_ATputmsg)(fd, ctlptr, datptr, flags, &err, 0); 163 else 164 err = ENXIO; 165 if (err) 166 setuerror(err); 167 return rc; 168} 169 170int ATPsndreq(fd, buf, len, nowait) /* AIX version */ 171 int fd; 172 unsigned char *buf; 173 int len; 174 int nowait; 175{ 176 int err, rc = -1; 177 178 if (sys_ATPsndreq) 179 rc = (*sys_ATPsndreq)(fd, buf, len, nowait, &err, 0); 180 else 181 err = ENXIO; 182 if (err) 183 setuerror(err); 184 return rc; 185} 186 187int ATPsndrsp(fd, respbuff, resplen, datalen) /* AIX version */ 188 int fd; 189 unsigned char *respbuff; 190 int resplen; 191 int datalen; 192{ 193 int err, rc = -1; 194 195 if (sys_ATPsndrsp) 196 rc = (*sys_ATPsndrsp)(fd, respbuff, resplen, datalen, &err, 0); 197 else 198 err = ENXIO; 199 if (err) 200 setuerror(err); 201 return rc; 202} 203 204int ATPgetreq(fd, buf, buflen) /* AIX version */ 205 int fd; 206 unsigned char *buf; 207 int buflen; 208{ 209 int err, rc = -1; 210 211 if (sys_ATPgetreq) 212 rc = (*sys_ATPgetreq)(fd, buf, buflen, &err, 0); 213 else 214 err = ENXIO; 215 if (err) 216 setuerror(err); 217 return rc; 218} 219 220int ATPgetrsp(fd, bdsp) /* AIX version */ 221 int fd; 222 unsigned char *bdsp; 223{ 224 int err, rc = -1; 225 226 if (sys_ATPgetrsp) 227 rc = (*sys_ATPgetrsp)(fd, bdsp, &err, 0); 228 else 229 err = ENXIO; 230 if (err) 231 setuerror(err); 232 return rc; 233} 234 235void *atalk_kalloc(size) /* AIX version */ 236 int size; 237{ 238 return (void *)xmalloc(size, 2, pinned_heap); 239} 240 241void atalk_kfree(buf) /* AIX version */ 242 void *buf; 243{ 244 xmfree(buf, pinned_heap); 245} 246 247int atalk_closeref(fp, grefp) /* AIX version */ 248 struct file *fp; 249 gref_t **grefp; 250{ 251 *grefp = (gref_t *)fp->f_data; 252 fp->f_data = 0; 253 return 0; 254} 255 256int atalk_openref(gref, retfd, proc) /* AIX version */ 257 gref_t *gref; 258 int *retfd; 259 void *proc; 260{ 261extern int _ATrw(), _ATioctl(), _ATselect(), _ATclose(), _ATstat(); 262static struct fileops fileops = {_ATrw, _ATioctl, _ATselect, _ATclose, _ATstat}; 263 int err, fd; 264 struct file *fp; 265 void *crp; 266 267 crp = (void *)crref(); 268#ifdef _AIX 269 if ((err = ufdcreate(FREAD|FWRITE, 270 &fileops, 0, DTYPE_OTHER, &fd, crp)) != 0) 271#else 272 if ((err = ufdcreate(FREAD|FWRITE, 273 &fileops, 0, DTYPE_ATALK, &fd, crp)) != 0) 274#endif 275 return err; 276 *retfd = fd; 277 fp = U.U_ufd[fd].fp; 278 fp->f_data = (void *)gref; 279 gref->next = (void *)fp; 280 return 0; 281} 282 283int atalk_getref(fp, fd, grefp, proc) /* AIX version */ 284 struct file *fp; 285 int fd; 286 gref_t **grefp; 287 struct proc *proc; 288{ 289 if (fp == 0) { 290 if ((fd < 0) || (fd > U.U_maxofile) || ((fp = U.U_ufd[fd].fp) == 0)) { 291 *grefp = (gref_t *)0; 292 return EBADF; 293 } 294 } 295 if ((*grefp = (gref_t *)fp->f_data) == 0) 296 return EBADF; 297 return 0; 298} 299 300gbuf_t *gbuf_alloc(size, pri) /* AIX version */ 301 int size; 302 int pri; 303{ 304 gbuf_t *m; 305 306 m = (size > MHLEN) ? (gbuf_t *)m_getclustm(M_DONTWAIT, MSG_DATA, size) 307 : (gbuf_t *)m_gethdr(M_DONTWAIT, MSG_DATA); 308#ifdef APPLETALK_DEBUG 309 kprintf("gbuf_alloc: for size = %d m=%x\n", size, m); 310#endif 311 gbuf_next(m) = 0; 312 gbuf_cont(m) = 0; 313 gbuf_wset(m,0); 314 return m; 315} 316 317void gbuf_freeb(m) /* AIX version */ 318 gbuf_t *m; 319{ 320 if (m) 321 m_free(m); 322} 323 324static struct trb *trb_freehead = 0; 325static struct trb *trb_freetail = 0; 326static struct trb *trb_pendhead = 0; 327static int trb_cnt = 0; 328static atlock_t trb_lock; 329 330static void atalk_rem_timeoutcf() /* AIX version */ 331{ 332 register int s; 333 register struct trb *trb; 334 register struct trb *tmp_freehead, *tmp_pendhead; 335 336 ATDISABLE(s, trb_lock); 337 tmp_freehead = trb_freehead; 338 trb_freehead = 0; 339 tmp_pendhead = trb_pendhead; 340 trb_pendhead = 0; 341 trb_cnt = 0; 342 ATENABLE(s, trb_lock); 343 while ((trb = tmp_pendhead) != 0) { 344 tmp_pendhead = trb->to_next; 345 while (tstop(trb)); 346 tfree(trb); 347 } 348 while ((trb = tmp_freehead) != 0) { 349 tmp_freehead = trb->to_next; 350 tfree(trb); 351 } 352 dPrintf(D_M_ATP,D_L_ERROR, "atalk: timer stopped!\n",0,0,0,0,0); 353} 354 355static void atalk_timeoutcf(cnt) /* AIX version */ 356 int cnt; 357{ 358 register int i; 359 register struct trb *trb; 360 361 if (trb_freehead == 0) { 362 for (i=0; i < cnt-1; i++) { 363 trb = (struct trb *)talloc(); 364 trb->to_next = trb_freehead; 365 trb_freehead = trb; 366 if (!i) trb_freetail = trb; 367 trb_cnt++; 368 } 369 } 370 ATLOCKINIT(trb_lock); 371} 372 373static void atalk_clock(trb) /* AIX version */ 374 register struct trb *trb; 375{ 376 register int s; 377 register struct trb *next; 378 void (*tof)(); 379 void *arg; 380 381 ATDISABLE(s, trb_lock); 382 if (trb_pendhead && trb->func) { 383 /* 384 * remove the timeout from the pending queue 385 */ 386 if (trb_pendhead == trb) 387 trb_pendhead = trb->to_next; 388 else { 389 for (next=trb_pendhead; next->to_next; next=next->to_next) { 390 if (next->to_next == trb) { 391 next->to_next = trb->to_next; 392 trb->func = 0; 393 break; 394 } 395 } 396 if (trb->func) { 397 dPrintf(D_M_ATP,D_L_WARNING, 398 "atalk_clock: %d,%x,%x\n", trb_cnt,trb,trb_pendhead,0,0); 399 /* 400 * we have not found the trb in the pending list - something 401 * has gone wrong here. maybe the trb has been returned to 402 * the free list; in which case, we should simply ignore 403 * this timeout event! 404 */ 405 for (next=trb_freehead; next; next=next->to_next) { 406 if (next == trb) 407 { 408 ATENABLE(s, trb_lock); 409 return; 410 } 411 } 412 /* 413 * the trb is not in the free list either - something has 414 * really gone wacky here! all we can do now is put the 415 * trb back into the free list and hope that it will be ok. 416 */ 417 trb->to_next = 0; 418 if (trb_freehead) 419 trb_freetail->to_next = trb; 420 else 421 trb_freehead = trb; 422 trb_freetail = trb; 423 trb_cnt++; 424 ATENABLE(s, trb_lock); 425 return; 426 } 427 } 428 429 /* 430 * process the timeout 431 */ 432 trb->func = 0; 433 trb->to_next = 0; 434 tof = trb->tof; 435 trb->tof = 0; 436 arg = (void *)trb->func_data; 437 trb->func_data = 999; 438 if (trb_freehead) 439 trb_freetail->to_next = trb; 440 else 441 trb_freehead = trb; 442 trb_freetail = trb; 443 trb_cnt++; 444 ATENABLE(s, trb_lock); 445 if (tof) { 446 dPrintf(D_M_ATP,D_L_VERBOSE, "atalk_clock: func=%x, arg=%x, %d\n", 447 tof,arg,trb_cnt,0,0); 448 (*tof)(arg); 449 } else { 450 dPrintf(D_M_ATP,D_L_ERROR, "atalk_clock: func=%x, arg=%x, %d\n", 451 tof,arg,trb_cnt,0,0); 452 } 453 } else 454 ATENABLE(s, trb_lock); 455} 456 457void *atalk_timeout(func, arg, ticks) /* AIX version */ 458 void (*func)(); 459 void *arg; 460 int ticks; 461{ 462 register int s; 463 register struct trb *trb; 464 465 dPrintf(D_M_ATP,D_L_VERBOSE, 466 "atalk_timeout: func=%x,arg=%x,time=%d, %d,%x\n", func,arg,ticks,trb_cnt,trb_pendhead); 467 /* 468 * set up the timeout request 469 */ 470 ATDISABLE(s, trb_lock); 471 if ((trb = trb_freehead) == 0) { 472 ATENABLE(s, trb_lock); 473 dPrintf(D_M_ATP,D_L_WARNING, 474 "atalk_timeout: NO TRB! time=%d, %d\n", ticks,trb_cnt,0,0,0); 475 return 0; 476 } 477 trb_freehead = trb->to_next; 478 trb->to_next = trb_pendhead; 479 trb_pendhead = trb; 480 trb_cnt--; 481 trb->timeout.it_value.tv_sec = ticks / HZ; 482 trb->timeout.it_value.tv_nsec = (ticks % HZ) * (NS_PER_SEC / HZ); 483 trb->knext = 0; 484 trb->kprev = 0; 485 trb->flags = 0; 486 trb->tof = func; 487 trb->func = (void (*)())atalk_clock; 488 trb->func_data = (ulong)arg; 489 trb->ipri = PL_IMP; 490 trb->id = -1; 491 492 /* 493 * start the timeout 494 */ 495 ATENABLE(s, trb_lock); 496 tstart(trb); 497 return (void *)trb; 498} 499 500void atalk_untimeout(func, arg, trb) /* AIX version */ 501 void (*func)(); 502 void *arg; 503 register struct trb *trb; 504{ 505 register int s; 506 register struct trb *next; 507 508 dPrintf(D_M_ATP,D_L_VERBOSE, 509 "atalk_untimeout: func=%x,arg=%x, %d\n", func,arg,trb_cnt,0,0); 510 511 ATDISABLE(s, trb_lock); 512 if (trb == 0) { 513 for (trb=trb_pendhead; trb; trb=trb->to_next) { 514 if ((func == trb->tof) && (arg == (void *)trb->func_data)) 515 break; 516 } 517 } 518 if (trb && (trb->func == (void (*)())atalk_clock) 519 && (func == trb->tof) && (arg == (void *)trb->func_data)) { 520 trb->func_data = 999; 521 if (!(trb->flags & T_PENDING)) 522 { 523 trb->tof = 0; 524 ATENABLE(s, trb_lock); 525 return; 526 } 527 trb->func = 0; 528 while (tstop(trb)); 529 if (trb_pendhead == trb) 530 trb_pendhead = trb->to_next; 531 else { 532 for (next=trb_pendhead; next->to_next != trb; next=next->to_next) { 533 if (next->to_next == 0) { 534 ATENABLE(s, trb_lock); 535 dPrintf(D_M_ATP,D_L_WARNING, 536 "atalk_untimeout: UNKNOWN TRB %x...\n",trb,0,0,0,0); 537 return; 538 } 539 } 540 next->to_next = trb->to_next; 541 } 542 trb->to_next = 0; 543 trb_freetail->to_next = trb; 544 trb_freetail = trb; 545 trb_cnt++; 546 } 547 ATENABLE(s, trb_lock); 548} 549 550int config_atalk(dev, cmd, uiop) /* AIX only */ 551dev_t dev; 552int cmd; 553void *uiop; 554{ 555 static int loaded = 0; 556 int err, nest; 557 558 err = 0; 559 nest = lockl(&kernel_lock, LOCK_SHORT); 560 561 if (cmd == CFG_INIT) { 562 if (loaded) 563 goto out; 564 vm_protect(0, 4096, 3); 565 atalk_timeoutcf(256); 566 atalk_load(); 567 loaded = 1; 568 569 } else if (cmd == CFG_TERM) { 570 if (!loaded) 571 goto out; 572 atalk_rem_timeoutcf(); 573 atalk_unload(); 574 loaded = 0; 575 576 } else 577 err = EINVAL; 578 579out: 580 if (nest != LOCK_NEST) 581 unlockl(&kernel_lock); 582 return(err); 583} 584 585#endif 586 587From sys_glue.c: 588 589#ifdef _AIX /* AIX code, to the end of this file, is no longer supported. */ 590 591int _ATselect(fp, corl, reqevents, retevents, notify) /* AIX version */ 592 void *fp; 593 int corl; 594 unsigned short reqevents; 595 unsigned short *retevents; 596 void (*notify)(); 597{ 598 int s, err, rc = 0; 599 gref_t *gref; 600 unsigned short sevents = 0; 601 602 if ((err = atalk_getref(fp, 0, &gref, 0)) != 0) 603 return err; 604 605 ATDISABLE(s, gref->lock); 606 if (reqevents & POLLIN) { 607 if (gref->rdhead || (gref->readable && (*gref->readable)(gref))) 608 sevents |= POLLIN; 609 } 610 611 if (reqevents & POLLOUT) { 612 if (gref->writeable) { 613 if ((*gref->writeable)(gref)) 614 sevents |= POLLOUT; 615 } else 616 sevents |= POLLOUT; 617 } 618 619 if ((sevents == 0) && ((reqevents & POLLSYNC) == 0)) { 620 if (rc = selreg(corl, 99, gref, reqevents, notify)) { 621 ATENABLE(s, gref->lock); 622 goto l_done; 623 } 624 625 if (reqevents & POLLIN) { 626 if (gref->rdhead || (gref->readable && (*gref->readable)(gref))) 627 sevents |= POLLIN; 628 else 629 gref->sevents |= POLLIN; 630 } 631 632 if (reqevents & POLLOUT) { 633 if (gref->writeable) { 634 if ((*gref->writeable)(gref)) 635 sevents |= POLLOUT; 636 else 637 gref->sevents |= POLLOUT; 638 } else 639 sevents |= POLLOUT; 640 } 641 } 642 ATENABLE(s, gref->lock); 643 *retevents = sevents; 644 645l_done: 646 return rc; 647} 648#endif /* end AIX section */ 649 650From drv_dep.c: 651 652 653 654 655#ifdef _AIX 656/* AIX section to end of file (not supported) */ 657 658/* from beginning of file ... */ 659#include <sys/cdli.h> 660#include <sys/ndd.h> 661static struct ns_8022 elap_link; /* The SNAP header description */ 662static struct ns_user elap_user; /* The interface to the demuxer */ 663 664int 665pat_ifpresent(name) /* AIX */ 666 char *name; 667{ 668 return (int)ifunit(name); 669} 670 671int 672pat_output(pat_id, mlist, dst_addr, type) /* AIX */ 673 int pat_id; 674 gbuf_t *mlist; 675 unsigned char *dst_addr; 676 int type; 677{ 678 int len; 679 pat_unit_t *patp; 680 gbuf_t *m, *m_prev, *new_mlist, *m_temp; 681 struct ndd *nddp; 682 short size; 683 enet_header_t *enet_header; 684 llc_header_t *llc_header; 685 686 patp = (pat_unit_t *)&pat_units[pat_id]; 687 if (patp->state != PAT_ONLINE) { 688 gbuf_freel(mlist); 689 return ENOTREADY; 690 } 691 692 if (patp->xtype == IFTYPE_NULLTALK) { 693 gbuf_freel(mlist); 694 return 0; 695 } 696 697 nddp = (void *)patp->nddp; 698 new_mlist = 0; 699 700 for (m = mlist; m; m = mlist) { 701 mlist = gbuf_next(m); 702 gbuf_next(m) = 0; 703 704 gbuf_prepend(m,ENET_LLC_SIZE); 705 if (m == 0) { 706 if (mlist) 707 gbuf_freel(mlist); 708 if (new_mlist) 709 gbuf_freel(new_mlist); 710 return 0; 711 } 712 713 enet_header = (enet_header_t *)gbuf_rptr(m); 714 bcopy(dst_addr, enet_header->dst, sizeof(enet_header->dst)); 715 bcopy(patp->xaddr, enet_header->src, sizeof(enet_header->src)); 716 size = gbuf_msgsize(m); 717 enet_header->len = size - sizeof(enet_header_t); 718 llc_header = (llc_header_t *)(gbuf_rptr(m)+sizeof(enet_header_t)); 719 *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at; 720 721 m->m_pkthdr.len = size; 722 m->m_pkthdr.rcvif = 0; 723 724 if (new_mlist) 725 gbuf_next(m_prev) = m; 726 else 727 new_mlist = m; 728 m_prev = m; 729 pktsOut++; 730 } 731 732 if (new_mlist) 733 (*nddp->ndd_output)(nddp, new_mlist); 734 735 return 0; 736} 737 738int 739pat_online (ifName, ifType) /* AIX */ 740 char *ifName; 741 char *ifType; 742{ 743 void pat_input(); 744 int pat_id; 745 pat_unit_t *patp; 746 struct ndd *nddp; 747 char ns_name[8]; 748 749 if ((pat_id = pat_ID(ifName)) == -1) 750 return (-1); 751 patp = &pat_units[pat_id]; 752 753 if (patp->xtype == IFTYPE_ETHERTALK) { 754 ns_name[0] = ifName[0]; 755 ns_name[1] = 'n'; 756 strcpy(&ns_name[2], &ifName[1]); 757 } else if (patp->xtype == IFTYPE_NULLTALK) { 758 patp->xaddrlen = 6; 759 bzero(patp->xaddr, patp->xaddrlen); 760 if (ifType) 761 *ifType = patp->xtype; 762 patp->nddp = (void *)0; 763 patp->state = PAT_ONLINE; 764 at_statep->flags |= AT_ST_IF_CHANGED; 765 return (pat_id); 766 } else 767 return -1; 768 769 if (ns_alloc(ns_name, &nddp)) 770 return -1; 771 772 bzero(&elap_user, sizeof(elap_user)); 773 elap_user.isr = pat_input; 774 elap_user.pkt_format = NS_HANDLE_HEADERS|NS_INCLUDE_MAC; 775 776 elap_link.filtertype = NS_8022_LLC_DSAP_SNAP; 777 elap_link.orgcode[0] = 0; 778 elap_link.orgcode[2] = 0; 779 elap_link.dsap = DSAP_SNAP; 780 elap_link.ethertype = 0x80f3; /* AARP SNAP code */ 781 if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) 782 return -1; 783 784 elap_link.orgcode[0] = 0x08; 785 elap_link.orgcode[2] = 0x07; 786 elap_link.ethertype = 0x809b; /* DDP SNAP code */ 787 if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) { 788 elap_link.orgcode[0] = 0; 789 elap_link.orgcode[2] = 0; 790 elap_link.ethertype = 0x80f3; /* AARP SNAP code */ 791 (void)ns_del_filter(nddp, &elap_link, sizeof(elap_link)); 792 return -1; 793 } 794 795 patp->xaddrlen = nddp->ndd_addrlen; 796 bcopy(nddp->ndd_physaddr, patp->xaddr, patp->xaddrlen); 797 798 if (ifType) 799 *ifType = patp->xtype; 800 801 patp->nddp = (void *)nddp; 802 patp->state = PAT_ONLINE; 803 at_statep->flags |= AT_ST_IF_CHANGED; 804 805 return (pat_id); 806} 807 808void 809pat_offline(pat_id) /* AIX */ 810 int pat_id; 811{ 812 pat_unit_t *patp = &pat_units[pat_id]; 813 814 if (patp->state == PAT_ONLINE) { 815 if (patp->xtype != IFTYPE_NULLTALK) { 816 elap_link.filtertype = NS_8022_LLC_DSAP_SNAP; 817 elap_link.orgcode[0] = 0; 818 elap_link.orgcode[2] = 0; 819 elap_link.dsap = DSAP_SNAP; 820 elap_link.ethertype = 0x80f3; /* AARP SNAP code */ 821 (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link)); 822 elap_link.orgcode[0] = 0x08; 823 elap_link.orgcode[2] = 0x07; 824 elap_link.ethertype = 0x809b; /* DDP SNAP code */ 825 (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link)); 826 ns_free(patp->nddp); 827 } 828 at_statep->flags |= AT_ST_IF_CHANGED; 829 bzero(patp, sizeof(pat_unit_t)); 830 } 831} 832 833int 834pat_mcast(pat_id, control, data) /* AIX */ 835 int pat_id; 836 int control; 837 unsigned char *data; 838{ 839 struct ndd *nddp; 840 841 nddp = (struct ndd *)pat_units[pat_id].nddp; 842 return (*nddp->ndd_ctl)(nddp, (control == PAT_REG_MCAST) ? 843 NDD_ENABLE_ADDRESS : NDD_DISABLE_ADDRESS, 844 data, nddp->ndd_addrlen); 845} 846 847void 848pat_input(nddp, m, unused) /* AIX */ 849 struct ndd *nddp; 850 gbuf_t *m; 851 void *unused; 852{ 853 extern int ddprunning_flag; 854 llc_header_t *llc_header; 855 int pat_id; 856 pat_unit_t *patp; 857 char src[6]; 858 enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m); 859 860 for (pat_id=0, patp = &pat_units[pat_id]; 861 pat_id < xpatcnt; pat_id++, patp++) { 862 if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp)) 863 break; 864 } 865 if (pat_id == xpatcnt) { 866 gbuf_freem(m); 867 return; 868 } 869 870 /* Ignore multicast packets from local station */ 871 if (patp->xtype == IFTYPE_ETHERTALK) { 872 bcopy((char *)enet_header->src, src, sizeof(src)); 873 if ((enet_header->dst[0] & 1) && 874 (bcmp(src, patp->xaddr, sizeof(src)) == 0)) { 875 gbuf_freem(m); 876 return; 877 } 878 llc_header = (llc_header_t *)(enet_header+1); 879 } 880 881 gbuf_rinc(m,(ENET_LLC_SIZE)); 882 (void)fetch_and_add((atomic_p)&ddprunning_flag, 1); 883 pktsIn++; 884 if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) { 885 patp->aarp_func(gbuf_rptr(m), patp->context); 886 gbuf_freem(m); 887 } else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) { 888 /* if we're a router take all pkts */ 889 if (!ROUTING_MODE) { 890 if (patp->addr_check(gbuf_rptr(m), patp->context) 891 == AARP_ERR_NOT_OURS) { 892 gbuf_freem(m); 893 (void)fetch_and_add((atomic_p)&ddprunning_flag, -1); 894 return; 895 } 896 } 897 gbuf_set_type(m, MSG_DATA); 898 elap_input(m, patp->context, src); 899 } else 900 gbuf_freem(m); 901 (void)fetch_and_add((atomic_p)&ddprunning_flag, -1); 902} 903#endif /* AIX */ 904