Patch #: 25 Type: operational change Priority: none Modification: Add EtherTalk Phase 2 support Submitted: David Hornsby Archived: munnari.OZ.AU mac/cap.patches/cap60.patch025 Summary: many changes ! File: cap60/CAP60.README File: cap60/Configure File: cap60/README File: cap60/support/uab/aarp.c File: cap60/support/ethertalk/aarpd.c File: cap60/support/ethertalk/aarpd.h File: cap60/support/ethertalk/aarpd_clnt.c File: cap60/support/ethertalk/aarpd_svc.c File: cap60/support/ethertalk/aarptest.c File: cap60/support/ethertalk/abelap.c File: cap60/lib/cap/abnbp.c File: cap60/lib/cap/atalkdbm.c File: cap60/lib/cap/atalkdbm.h File: cap60/etc/atis.c File: cap60/samples/atlook.c File: cap60/support/ethertalk/ethertalk.c File: cap60/support/uab/ethertalk.h File: cap60/etc/nisaux.c File: cap60/support/ethertalk/rtmptest.c File: cap60/support/ethertalk/snitp.c *** CAP60.README.orig Fri Mar 15 00:57:25 1991 --- CAP60.README Wed May 29 22:19:23 1991 *************** *** 51,58 **** CAP and AppleTalk Phase 2 ------------------------- ! CAP does not currently support EtherTalk Phase 2. However, it is possible ! to use CAP in a Phase 2 environment. Traditionally, the CAP transport mechanism uses UDP/IP packets. This is called IPTalk (also known as KIP) and is a "non-extended" (1 net number --- 51,60 ---- CAP and AppleTalk Phase 2 ------------------------- ! CAP 6.0 (to patch level 25 or greater) supports EtherTalk Phase 2 using ! the SunOS NIT interface [soon also on the enet interface and ULTRIX packet ! filter interface]. It also is possible to use CAP in a Phase 2 environment ! with IPTalk as indicated below. Traditionally, the CAP transport mechanism uses UDP/IP packets. This is called IPTalk (also known as KIP) and is a "non-extended" (1 net number *************** *** 98,106 **** earlier versions of the gateway code will happily translate from IPTalk to either Phase 1 or LocalTalk. - If you don't have a hardware gateway at all, you can currently only use CAP - with UAB or Native EtherTalk (both Phase 1) and other *Phase 1 ONLY* nodes. - Bug Fixes --------- --- 100,105 ---- *************** *** 197,203 **** XENIX: (-Dxenix5 (handled by Configure)) ! file.1,file.2,file.3 Chip Salzenberg Support for CAP on SCO XENIX System V. --- 196,202 ---- XENIX: (-Dxenix5 (handled by Configure)) ! file.1,file.2,file.3 Chip Salzenberg Support for CAP on SCO XENIX System V. *** Configure.orig Wed May 29 19:31:31 1991 --- Configure Wed May 29 22:24:11 1991 *************** *** 1,7 **** #!/bin/sh ! # $Author: djh $ $Date: 1991/05/29 09:31:20 $ ! # $Header: /mac/src/cap60/RCS/Configure,v 2.9 1991/05/29 09:31:20 djh Exp djh $ ! # $Revision: 2.9 $ # CAP configuration shell script. This ain't perfect, but it's a start. # Execute with /bin/sh Configure if your system won't run it (ksh is okay too) # --- 1,7 ---- #!/bin/sh ! # $Author: djh $ $Date: 1991/05/29 12:23:59 $ ! # $Header: /mac/src/cap60/RCS/Configure,v 2.10 1991/05/29 12:23:59 djh Rel djh $ ! # $Revision: 2.10 $ # CAP configuration shell script. This ain't perfect, but it's a start. # Execute with /bin/sh Configure if your system won't run it (ksh is okay too) # *************** *** 257,263 **** --- 257,265 ---- etherprogs="define([etherprogs],[])" etherpobjs="define([etherpobjs],[])" lapobj="define([lapobj],[abkip.o abddp.o abnbp.o atalkdbm.o])" + usingphase2="# define([usephase2],1)" result=0 + usephase2=0 uabsupport=0 ethersupport=0 case ${os} in *************** *** 360,374 **** echo "OK, setting things up for Native EtherTalk." etherpobjs="define([etherpobjs],[senetp.o])";; "sunos") ! echo $newl "Have you installed the 'enet' driver (no) ? " ! read ans ! if [ -z "${ans}" ]; then ans="no" ! fi ! case ${ans} in "yes"|"y") result=1;; *) result=0;; ! esac if [ $result -eq 0 ]; then echo "OK, using the NIT ethernet interface." etherpobjs="define([etherpobjs],[snitp.o])" --- 362,390 ---- echo "OK, setting things up for Native EtherTalk." etherpobjs="define([etherpobjs],[senetp.o])";; "sunos") ! echo $newl "Do you want Phase 2 compatibility (no) ? " ! read ans ! if [ -z "${ans}" ]; then ! ans="no" ! fi ! case ${ans} in ! "yes"|"y") ! result=0 ! usephase2=1;; ! *) ! echo "Using EtherTalk Phase 1" ! echo ! echo $newl "Have you installed the 'enet' driver (no) ? " ! read ans ! if [ -z "${ans}" ]; then ans="no" ! fi ! case ${ans} in "yes"|"y") result=1;; *) result=0;; ! esac ! ;; ! esac if [ $result -eq 0 ]; then echo "OK, using the NIT ethernet interface." etherpobjs="define([etherpobjs],[snitp.o])" *************** *** 383,388 **** --- 399,407 ---- if [ $useauxappletalk -ne 0 ]; then labobj="define([lapobj],[abauxddp.o abauxnbp.o])" fi + if [ $usephase2 -ne 0 ]; then + usingphase2="define([usephase2],1)" + fi echo echo "CAP can be configured for various optional features." echo "For more information, refer to the file 'CAP60.README'." *************** *** 754,759 **** --- 773,781 ---- echo "${etherprogs}" echo "${etherpobjs}" echo + echo "# And this determines if Phase 2 packets are used" + echo "${usingphase2}" + echo echo "# The following selects byteswapping or otherwise" echo "${byteswapping}" echo *************** *** 950,955 **** --- 972,978 ---- [Unknown])) define([cflags],ifdef([selfdefinetypes],[-D_TYPES],[])) define([cflags],concat(cflags,ifdef([usebyteswap],[ -DBYTESWAPPED],[]))) + define([cflags],concat(cflags,ifdef([usephase2],[ -DPHASE2],[]))) define([bigcflags],ifelse(os,[hpux],[+Nd2000 +Ns2000])) # The encore optimiser is slightly over zealous ifelse(os,[encore],[define([cflags],concat(cflags,[ -Dencore]))],[ *** README.orig Wed May 29 19:23:06 1991 --- README Wed May 29 22:26:51 1991 *************** *** 3,9 **** (For use with AppleTalk/Ethernet bridge) o RELEASE NOTES ! o CAP Distribution 6.0, Patch Level 24, May 1991 Introduction ------------ --- 3,9 ---- (For use with AppleTalk/Ethernet bridge) o RELEASE NOTES ! o CAP Distribution 6.0, Patch Level 25, May 1991 Introduction ------------ *************** *** 85,93 **** * Cayman Gatorbox * Shiva FastPath ! o This CAP version supports native EtherTalk on certain hosts. A gateway ! as listed above is only required to access LocalTalk services. Phase 1 ! only is available at this stage. o baseline host system: Ultrix 2.0-1. Most will work under BSD 4.2, BSD 4.3, Ultrix 1.0-1.2, Sun OS 3.2 or higher, ACIS 4.2, A/UX, IBM --- 85,93 ---- * Cayman Gatorbox * Shiva FastPath ! o This CAP version supports native EtherTalk (Phase 1 or Phase 2) on ! certain hosts. A gateway as listed above is only required to access ! LocalTalk services. o baseline host system: Ultrix 2.0-1. Most will work under BSD 4.2, BSD 4.3, Ultrix 1.0-1.2, Sun OS 3.2 or higher, ACIS 4.2, A/UX, IBM *** support/uab/aarp.c.orig Wed Mar 13 21:08:31 1991 --- support/uab/aarp.c Wed May 29 22:28:53 1991 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 91/03/13 20:07:35 $"; ! static char rcsident[] = "$Header: aarp.c,v 2.2 91/03/13 20:07:35 djh Exp $"; ! static char revision[] = "$Revision: 2.2 $"; /* * aarp.c - AppleTalk Address Resolution Protocol handler --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:28:45 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/uab/RCS/aarp.c,v 2.3 1991/05/29 12:28:45 djh Rel djh $"; ! static char revision[] = "$Revision: 2.3 $"; /* * aarp.c - AppleTalk Address Resolution Protocol handler *************** *** 20,26 **** * Edit History: * * April 3, 1988 CCKim Created ! * Aug 26, 1988 Moved into seperate module from ethertalk * */ --- 20,27 ---- * Edit History: * * April 3, 1988 CCKim Created ! * Aug 26, 1988 Moved into separate module from ethertalk ! * April 28,1991 djh Added Phase 2 support * */ *************** *** 64,69 **** --- 65,73 ---- export AARP_ENTRY *aarptab_find(); export caddr_t aarp_init(); export int aarp_get_host_addr(); + #ifdef PHASE2 + export int aarp_set_host_addr(); + #endif PHASE2 export int aarp_resolve(); export int aarp_insert(); export int aarp_acquire_etalk_node(); *************** *** 76,82 **** --- 80,90 ---- private struct ai_host_node *host_node(); /* pointers to host ethernet and broadcast addresess */ + #ifdef PHASE2 + private u_char b_eaddr[EHRD] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff}; + #else PHASE2 private u_char b_eaddr[EHRD] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + #endif PHASE2 /* list of all the node ids: DUMP ONLY */ private AARP_ENTRY *aarptab_node_list; *************** *** 95,102 **** struct ethertalkaddr *k; AARP_ENTRY *node; { ! /* EtherTalk II fixup */ return(k->node - node->aae_pa.node); } /* compress an ethertalk node addresses */ --- 103,113 ---- struct ethertalkaddr *k; AARP_ENTRY *node; { ! #ifdef PHASE2 ! return(bcmp(k, &node->aae_pa, ETPL)); ! #else PHASE2 return(k->node - node->aae_pa.node); + #endif PHASE2 } /* compress an ethertalk node addresses */ *************** *** 104,110 **** aarptab_compress(k) struct ethertalkaddr *k; { ! /* EtherTalk II fixup */ return(k->node); } --- 115,123 ---- aarptab_compress(k) struct ethertalkaddr *k; { ! #ifdef PHASE2 ! /* ZZ */ ! #endif PHASE2 return(k->node); } *************** *** 201,209 **** if (r == NULL) return(NULL); if (r->aae_flags == 0) { ! /* EtherTalk II */ ! logit(LOG_LOTS, "New AARP mapping for node %d, bkt %d, dist %d\n", ! r->aae_pa.node); r->aae_aarptab = aih->ai_aarptab; /* remember */ } else { if (aih->ai_accesses++ > AI_AARPTAB_EVAL_POINT) --- 214,225 ---- if (r == NULL) return(NULL); if (r->aae_flags == 0) { ! #ifdef PHASE2 ! logit(LOG_LOTS, "New AARP mapping for node %d/%d.%d", ! r->aae_pa.node, r->aae_pa.dummy[1], r->aae_pa.dummy[2]); ! #else PHASE2 ! logit(LOG_LOTS, "New AARP mapping for node %d", r->aae_pa.node); ! #endif PHASE2 r->aae_aarptab = aih->ai_aarptab; /* remember */ } else { if (aih->ai_accesses++ > AI_AARPTAB_EVAL_POINT) *************** *** 224,231 **** { aa->aae_flags = 0; /* not okay */ ! /* EtherTalk II */ logit(LOG_LOTS, "deleting arp entry: node %d", aa->aae_pa.node); en = (AARP_ENTRY *)h_delete(aih->ai_aarptab, aa->aae_pa.node); if (en != aa) { logit(LOG_BASE, "when deleting arp entry, freed entry was %x, wanted %x", --- 240,251 ---- { aa->aae_flags = 0; /* not okay */ ! #ifdef PHASE2 ! logit(LOG_LOTS, "deleting arp entry: node %d/%d.%d", ! aa->aae_pa.node, aa->aae_pa.dummy[1], aa->aae_pa.dummy[2]); ! #else PHASE2 logit(LOG_LOTS, "deleting arp entry: node %d", aa->aae_pa.node); + #endif PHASE2 en = (AARP_ENTRY *)h_delete(aih->ai_aarptab, aa->aae_pa.node); if (en != aa) { logit(LOG_BASE, "when deleting arp entry, freed entry was %x, wanted %x", *************** *** 234,240 **** aa->aae_next = aarptab_free_list; aarptab_free_list = aa; /* mark */ } ! #endif /* scan arp table and see if anything needs going */ aarptab_scan() --- 254,260 ---- aa->aae_next = aarptab_free_list; aarptab_free_list = aa; /* mark */ } ! #endif notdef /* scan arp table and see if anything needs going */ aarptab_scan() *************** *** 245,254 **** np = NULL, n = aarptab_node_list; while (n) { if (n->aae_ttl <= 0) { logit(LOG_LOTS, "deleting arp entry: node %d", n->aae_pa.node); en = (AARP_ENTRY *)h_delete(n->aae_aarptab, &n->aae_pa); if (en != n) { ! logit(LOG_BASE, "when deleting arp entry, freed entry was %x, wanted %x", en, n); } if (np) --- 265,279 ---- np = NULL, n = aarptab_node_list; while (n) { if (n->aae_ttl <= 0) { + #ifdef PHASE2 + logit(LOG_LOTS, "deleting arp entry: node %d/%d.%d", + n->aae_pa.node, n->aae_pa.dummy[1], n->aae_pa.dummy[2]); + #else PHASE2 logit(LOG_LOTS, "deleting arp entry: node %d", n->aae_pa.node); + #endif PHASE2 en = (AARP_ENTRY *)h_delete(n->aae_aarptab, &n->aae_pa); if (en != n) { ! logit(LOG_BASE,"when deleting arp entry, freed entry was %x, wanted %x", en, n); } if (np) *************** *** 327,333 **** if ((pi_get_ethernet_address(ph, aih->ai_eaddr)) < 0) goto giveup; ! logit(LOG_BASE,"Ethernet address for %s%d is %02x:%02x:%02x:%02x:%02x:%02x\n", dev, devno, aih->ai_eaddr[0], aih->ai_eaddr[1], aih->ai_eaddr[2], aih->ai_eaddr[3], aih->ai_eaddr[4], aih->ai_eaddr[5]); --- 352,358 ---- if ((pi_get_ethernet_address(ph, aih->ai_eaddr)) < 0) goto giveup; ! logit(LOG_BASE,"Ethernet address for %s%d is %02x:%02x:%02x:%02x:%02x:%02x", dev, devno, aih->ai_eaddr[0], aih->ai_eaddr[1], aih->ai_eaddr[2], aih->ai_eaddr[3], aih->ai_eaddr[4], aih->ai_eaddr[5]); *************** *** 365,376 **** aih->ai_nodes[which].aihn_state == AI_NODE_OKAY) { *pa = aih->ai_nodes[which].aihn_pa; /* copy it */ /* should we count pa node address? */ ! return(1); /* one byte handled for now */ } return(-1); } /* * returns -1: can't be resolved * 0: resolving, come back later * 1: resolved --- 390,429 ---- aih->ai_nodes[which].aihn_state == AI_NODE_OKAY) { *pa = aih->ai_nodes[which].aihn_pa; /* copy it */ /* should we count pa node address? */ ! #ifdef PHASE2 ! return(4); ! #else PHASE2 ! return(1); ! #endif PHASE2 } return(-1); } + #ifdef PHASE2 /* + * set a host node address + * + */ + export int + aarp_set_host_addr(aih, pa) + AI_HANDLE *aih; + struct ethertalkaddr *pa; + { + int i = aih->ai_numnode; + struct ai_host_node *an = aih->ai_nodes; + + for ( ; i ; an++, i--) + if (an->aihn_state == AI_NODE_OKAY) + an->aihn_pa = *pa; + + if (i == 0) + return(0); + + return(-1); + } + #endif PHASE2 + + /* * returns -1: can't be resolved * 0: resolving, come back later * 1: resolved *************** *** 446,453 **** struct timeval *tv; /* check to make sure ha isn't broadcast (or multicast)! */ ! /* EtherTalk II fixup */ logit(LOG_LOTS, "Got mapping for %d", pa->node); dumpether(LOG_LOTS, " Address", ha); aa = aarptab_get(aih, pa); /* find it or get a new one */ --- 499,514 ---- struct timeval *tv; /* check to make sure ha isn't broadcast (or multicast)! */ ! if (bcmp(ha, b_eaddr) == 0) ! return(FALSE); ! #ifdef PHASE2 ! if (ha[0] == 0x09 && ha[1] == 0x00 && ha[2] == 0x07 && ha[3] == 0x00) ! return(FALSE); /* zone multicast address */ ! logit(LOG_LOTS,"Got mapping for %d/%d.%d", ! pa->node, pa->dummy[1], pa->dummy[2]); ! #else PHASE2 logit(LOG_LOTS, "Got mapping for %d", pa->node); + #endif PHASE2 dumpether(LOG_LOTS, " Address", ha); aa = aarptab_get(aih, pa); /* find it or get a new one */ *************** *** 455,462 **** if (aa->aae_flags & (AARP_PERM)) /* don't reset these */ return(FALSE); if (hard) ! /* EtherTalk II fixup */ logit(LOG_LOTS, "Resetting an old mapping for node %d", pa->node); } /* if arp entry is in cache and we aren't doing a hard update */ /* and the hardware addresses don't match, don't do an update */ --- 516,527 ---- if (aa->aae_flags & (AARP_PERM)) /* don't reset these */ return(FALSE); if (hard) ! #ifdef PHASE2 ! logit(LOG_LOTS, "Resetting an old mapping for node %d/%d.%d", ! pa->node, pa->dummy[1], pa->dummy[2]); ! #else PHASE2 logit(LOG_LOTS, "Resetting an old mapping for node %d", pa->node); + #endif PHASE2 } /* if arp entry is in cache and we aren't doing a hard update */ /* and the hardware addresses don't match, don't do an update */ *************** *** 463,470 **** if ((aa->aae_flags & AARP_OKAY) && !hard) { if (bcmp((caddr_t)aa->aae_eaddr, (caddr_t)ha, EHRD) != 0) { logit(LOG_BASE, "AARP RESET - ethernet address mismatch"); ! /* EtherTalk II fixup */ logit(LOG_BASE,"node number is %d", pa->node); dumpether(LOG_BASE, "incoming address", ha); dumpether(LOG_BASE, "cached address",aa->aae_eaddr); aa->aae_flags &= ~AARP_OKAY; /* there we go */ --- 528,539 ---- if ((aa->aae_flags & AARP_OKAY) && !hard) { if (bcmp((caddr_t)aa->aae_eaddr, (caddr_t)ha, EHRD) != 0) { logit(LOG_BASE, "AARP RESET - ethernet address mismatch"); ! #ifdef PHASE2 ! logit(LOG_BASE,"node number is %d/%d.%d", ! pa->node, pa->dummy[1], pa->dummy[2]); ! #else PHASE2 logit(LOG_BASE,"node number is %d", pa->node); + #endif PHASE2 dumpether(LOG_BASE, "incoming address", ha); dumpether(LOG_BASE, "cached address",aa->aae_eaddr); aa->aae_flags &= ~AARP_OKAY; /* there we go */ *************** *** 501,508 **** ntohs(arp.arp_pro) != ETHERTYPE_APPLETALK || /* not appletalk? */ arp.arp_hln != EHRD || /* wrong hrdwr length */ arp.arp_pln != ETPL) { /* wrong protocol length? */ ! /* maybe log? */ ! return; /* yes, to one, kill packet */ } dpa = (struct ethertalkaddr *)arp.arp_tpa; /* reformat */ --- 570,578 ---- ntohs(arp.arp_pro) != ETHERTYPE_APPLETALK || /* not appletalk? */ arp.arp_hln != EHRD || /* wrong hrdwr length */ arp.arp_pln != ETPL) { /* wrong protocol length? */ ! logit(5, "AARP drop!: %d %d %d %d", ! arp.arp_hrd, arp.arp_pro, arp.arp_hln, arp.arp_pln); ! return; } dpa = (struct ethertalkaddr *)arp.arp_tpa; /* reformat */ *************** *** 521,528 **** return; } if (host_node(aih, spa, AI_NODE_OKAY)) { ! /* EtherTalk II fixup */ logit(LOG_BASE, "Address conflict %d\n", spa->node); } switch (ntohs(arp.arp_op)) { --- 591,602 ---- return; } if (host_node(aih, spa, AI_NODE_OKAY)) { ! #ifdef PHASE2 ! logit(LOG_BASE, "Address conflict %d/%d.%d\n", ! spa->node, spa->dummy[1], spa->dummy[2]); ! #else PHASE2 logit(LOG_BASE, "Address conflict %d\n", spa->node); + #endif PHASE2 } switch (ntohs(arp.arp_op)) { *************** *** 613,621 **** int i; /* bad node */ - /* EtherTalk II fixup */ if (initial_node->node == 0 || initial_node->node == 255) return(1); if (aarptab_find(aih, initial_node) || host_node(aih, initial_node, 0)) { /* callback ? */ return(1); --- 687,698 ---- int i; /* bad node */ if (initial_node->node == 0 || initial_node->node == 255) return(1); + #ifdef PHASE2 + if (initial_node->node == 254) /* reserved */ + return(1); + #endif PHASE2 if (aarptab_find(aih, initial_node) || host_node(aih, initial_node, 0)) { /* callback ? */ return(1); *************** *** 679,684 **** --- 756,764 ---- struct timeval tv; struct ai_host_node *ahn; AI_HANDLE *aih = aphandle->aaph_aih; + #ifdef PHASE2 + char abuf[sizeof(struct ether_arp)+8]; + #endif PHASE2 /* either of these can be running or both - both really doesn't */ /* make much sense though */ *************** *** 723,730 **** --- 803,816 ---- tv.tv_sec = AARP_PROBE_TIMEOUT_SEC; tv.tv_usec = AARP_PROBE_TIMEOUT_USEC; } + #ifdef PHASE2 + /* make room for the rest of the ELAP header */ + bcopy(&aphandle->aaph_arp, abuf+8, sizeof(struct ether_arp)); + if (pi_write(aih->ai_ph, abuf, sizeof(abuf), b_eaddr) < 0) + #else PHASE2 if (pi_write(aih->ai_ph,&aphandle->aaph_arp, sizeof(struct ether_arp), b_eaddr) < 0) + #endif PHASE2 logit(LOG_BASE|L_UERR, "pi_write failed: aarp driver"); /* setup timeout to next (relative timeout) */ relTimeout(probe_and_request_driver, aphandle, &tv, TRUE); *************** *** 782,787 **** --- 868,876 ---- struct ether_arp *arp; { caddr_t sha, tha; + #ifdef PHASE2 + char abuf[sizeof(struct ether_arp)+8]; + #endif PHASE2 sha = (caddr_t)&arp->arp_sha; /* need & because can be struct */ tha = (caddr_t)&arp->arp_tha; *************** *** 792,798 **** --- 881,892 ---- bcopy((caddr_t)aih->ai_eaddr, sha, EHRD); /* copy in our node */ bcopy((caddr_t)pa, (caddr_t)arp->arp_spa, ETPL); + #ifdef PHASE2 + bcopy(arp, abuf+8, sizeof(struct ether_arp)); + if (pi_write(aih->ai_ph, abuf, sizeof(abuf), tha) < 0) { + #else PHASE2 if (pi_write(aih->ai_ph, arp, sizeof(*arp), tha) < 0) { + #endif PHASE2 logit(LOG_LOG|L_UERR, "etsend"); } } *************** *** 808,813 **** --- 902,912 ---- { AARP_ENTRY *aa; struct aarp_aphandle *ap; + #ifdef PHASE2 + int forcePROBE = tpa->dummy[0]; + /* can you say 'hack' */ + tpa->dummy[0] = 0; + #endif PHASE2 if ((aa = aarptab_get(aih, tpa)) == NULL) /* get new */ return; *************** *** 824,830 **** --- 923,933 ---- /* establish arp packet */ bzero(&ap->aaph_arp, sizeof(ap->aaph_arp)); + #ifdef PHASE2 + ap->aaph_arp.arp_op = htons((forcePROBE) ? ARPOP_PROBE : ARPOP_REQUEST); + #else PHASE2 ap->aaph_arp.arp_op = htons(ARPOP_REQUEST); + #endif PHASE2 ap->aaph_arp.arp_hrd = htons(ARPHRD_ETHER); ap->aaph_arp.arp_pro = htons(ETHERTYPE_APPLETALK); ap->aaph_arp.arp_hln = EHRD; *************** *** 850,855 **** --- 953,962 ---- } #endif bcopy((caddr_t)tpa, (caddr_t)ap->aaph_arp.arp_tpa, sizeof(*tpa)); + #ifdef PHASE2 + if (forcePROBE) + bcopy((caddr_t)tpa, (caddr_t)ap->aaph_arp.arp_spa, sizeof(*tpa)); + #endif PHASE2 ap->aaph_ae = aa; /* remember this for later */ ap->aaph_tries = AARP_REQUEST_TRY; *************** *** 881,889 **** if (ai_nodes->aihn_state) { if (flag && ai_nodes->aihn_state != flag) continue; ! /* EtherTalk II fixup */ if (ai_nodes->aihn_pa.node && ai_nodes->aihn_pa.node == n->node) return(ai_nodes); } return(NULL); } --- 988,1003 ---- if (ai_nodes->aihn_state) { if (flag && ai_nodes->aihn_state != flag) continue; ! #ifdef PHASE2 ! if (ai_nodes->aihn_pa.node ! && ai_nodes->aihn_pa.dummy[1] == n->dummy[1] ! && ai_nodes->aihn_pa.dummy[2] == n->dummy[2] ! && ai_nodes->aihn_pa.node == n->node) ! return(ai_nodes); ! #else PHASE2 if (ai_nodes->aihn_pa.node && ai_nodes->aihn_pa.node == n->node) return(ai_nodes); + #endif PHASE2 } return(NULL); } *** support/ethertalk/aarpd.c.orig Mon Apr 8 20:40:23 1991 --- support/ethertalk/aarpd.c Wed May 29 22:30:30 1991 *************** *** 7,12 **** --- 7,13 ---- * 16/02/91: add support for CAP 6.0 atalkdbm routines, back out * of shared memory in favour of RPC based [SG]etBridgeAddress() * Add the SVC descriptors to the low level scheduler. + * 28/04/91: Add Phase 2 support, SetNetRange() */ #include *************** *** 13,18 **** --- 14,24 ---- #include #include #include + #ifdef PHASE2 + #include + #include + #include + #endif PHASE2 #include #include #include *************** *** 34,39 **** --- 40,50 ---- extern word this_net; /* this host node */ extern byte nis_node; /* atis running here */ extern word nis_net; /* atis running here */ + #ifdef PHASE2 + extern word net_range_start; /* phase 2 network range start */ + extern word net_range_end; /* phase 2 network range end */ + extern int etalk_set_mynode(); /* update our node address */ + #endif PHASE2 extern short lap_proto; /* our LAP mechanism */ *************** *** 48,53 **** --- 59,68 ---- u_char *rtmp_getbaddr_svc(); /* get the bridge address */ u_char *rtmp_setbaddr_svc(); /* set the bridge address */ + #ifdef PHASE2 + struct ifreq ifreq; + #endif PHASE2 + main(argc, argv) int argc; char *argv[]; *************** *** 82,87 **** --- 97,107 ---- nis_net = this_net = 0; /* assume that we don't know */ bridge_addr.s_addr = inet_addr("127.0.0.1"); + #ifdef PHASE2 + this_net = 0xff00; /* the startup range */ + net_range_start = 0; /* the total range */ + net_range_end = 0xfffe; + #endif PHASE2 baddr.node = bridge_node; /* set bridge addr hint */ baddr.net = bridge_net; *************** *** 157,164 **** exit(1); } ! set_svc_listen(); /* add RPC descriptors to scheduler */ if (!dbug.db_flgs && (dlevel == 0)) disassociate(); --- 177,188 ---- exit(1); } ! set_svc_listen(); /* add RPC descriptors to scheduler */ + #ifdef PHASE2 + getNetInfo(); /* find out about our network */ + #endif PHASE2 + if (!dbug.db_flgs && (dlevel == 0)) disassociate(); *************** *** 176,181 **** --- 200,207 ---- void init_enet() { + struct ethertalkaddr *ea, *etalk_mynode(); + id.id_ld = ðertalk_lap_description; id.id_local = NULL; id.id_isabridge = 0; *************** *** 189,197 **** init_fdlistening(); /* low level scheduler */ etalk_init(&id, FALSE); /* set up EtherTalk */ ! this_node = nis_node = etalk_mynode(&id); if (dbug.db_flgs || (dlevel != 0)) printf("acquired node number %d\n", this_node); } disassociate() --- 215,233 ---- init_fdlistening(); /* low level scheduler */ etalk_init(&id, FALSE); /* set up EtherTalk */ ! ea = etalk_mynode(&id); ! this_node = nis_node = ea->node; ! #ifdef PHASE2 ! this_net = nis_net = (ea->dummy[1] << 8) | ea->dummy[2]; ! #endif PHASE2 ! if (dbug.db_flgs || (dlevel != 0)) + #ifdef PHASE2 + printf("acquired node number %d/%d.%d\n", + this_node, (this_net >> 8) & 0xff, this_net & 0xff); + #else PHASE2 printf("acquired node number %d\n", this_node); + #endif PHASE2 } disassociate() *************** *** 229,235 **** --- 265,276 ---- { u_char *ea; + #ifdef PHASE2 + struct ethertalkaddr *pa = (struct ethertalkaddr *) node; + logit(2, "request for %d/%d.%d", pa->node, pa->dummy[1], pa->dummy[2]); + #else PHASE2 logit(2, "request for %d", *node); + #endif PHASE2 ea = etalk_resolve(&id, *node); return((ea) ? ea : null_ether); } *************** *** 244,250 **** int *i; struct svc_req *rqstp; { ! logit(2, "request for bridge address"); return((u_char *) &baddr); } --- 285,291 ---- int *i; struct svc_req *rqstp; { ! logit(2, "request for bridge address: %d.%d", baddr.net, baddr.node); return((u_char *) &baddr); } *************** *** 268,274 **** --- 309,387 ---- return((u_char *) &baddr); } + #ifdef PHASE2 /* + * Set the network range (Phase 2). Check that the current + * node number is free for use in the new range by aarping + * for the new address to see if anybody responds. + * + * (could be called from atis, which is listening to + * RTMP packets or for an arriving GetNetInfo packet) + * + */ + + u_char * + range_set_svc(range, rqstp) + unsigned long *range; + struct svc_req *rqstp; + { + int attempts, totalattempts; + static struct ethertalkaddr eaddr; + short new_net, new_net_start, new_net_end; + + new_net_start = (*range >> 16) & 0xffff; + new_net_end = (*range & 0xffff); + new_net = new_net_start; + logit(5, "Changing network range: %04x-%04x -> %04x-%04x", + net_range_start, net_range_end, new_net_start, new_net_end); + eaddr.dummy[0] = 0; + eaddr.dummy[1] = (htons(new_net) >> 8) & 0xff; + eaddr.dummy[2] = (htons(new_net) & 0xff); + eaddr.node = this_node; + /* probe a few times for the new address */ + totalattempts = 0; + for (attempts = 0 ; attempts < 20 ; attempts++) { + logit(5, "Probing for %d/%d.%d", eaddr.node, + eaddr.dummy[1], eaddr.dummy[2]); + /* this is a hack, just sending aarp probes doesn't */ + /* work so we alternate them with aarp requests :-( */ + eaddr.dummy[0] = ((attempts & 0x01) == 0); + if (etalk_resolve(&id, *(long *)&eaddr) != NULL) { + logit(5, "Node number %d already in use!", eaddr.node); + /* oops, pick another */ + if (++eaddr.node >= 0xfe) /* reserved */ + eaddr.node = 1; + attempts = 0; /* same again */ + if (++totalattempts > 252) { + /* oh dear, have to try another net */ + if (++new_net > new_net_end) { + logit(5, "OOPS: no spare nodes available on net!!"); + return(NULL); + } + eaddr.dummy[1] = (htons(new_net) >> 8) & 0xff; + eaddr.dummy[2] = (htons(new_net) & 0xff); + totalattempts = 0; + } + } + abSleep(1, FALSE); /* allow protocols to run */ + } + eaddr.dummy[0] = 0; + /* adopt it by updating our internal tables */ + if (etalk_set_mynode(&id, &eaddr) < 0) { + logit(5, "Couldn't update net and node numbers"); + return(NULL); + } + logit(5, "Adopting %d/%d.%d", eaddr.node, eaddr.dummy[1], eaddr.dummy[2]); + net_range_start = new_net_start; + net_range_end = new_net_end; + this_net = nis_net = new_net; + this_node = nis_node = eaddr.node; + etalkdbupdate(NULL); + return((u_char *) range); + } + #endif PHASE2 + + /* * add the RPC descriptors to the low level scheduler * */ *************** *** 312,314 **** --- 425,580 ---- for (;;) abSleep(sectotick(30), TRUE); } + + #ifdef PHASE2 + + #define ZIPQuery 1 + #define ZIPReply 2 + #define ZIPEReply 8 + #define ZIPGetInfoReq 5 + #define ZIPGetInfoRepl 6 + + #define ZIPATTEMPTS 4 + + #define ZIPZoneBad 0x80 + #define ZIPNoMultiCast 0x40 + #define ZIPSingleZone 0x20 + + private int zisSkt; + private int heardFrom; + private char zmcaddr[6]; + private char defzone[34]; + private u_short range_start; + private u_short range_end; + + /* + * This is the ZIP ZIS listener + * (at present we are only interested + * in receiving one GetNetInfo packet + * and that only at startup) + * + */ + + void + zis_listener(skt, type, zis, len, addr) + u_char skt; + u_char type; + u_char *zis; + int len; + AddrBlock *addr; + { + int x; + unsigned long range; + u_char *range_set_svc(); + + if (heardFrom) + return; /* drop it */ + + if (type == ddpATP) + return; /* drop it */ + + if (type != ddpZIP) { + logit(3, "ZIS listener - bad packet"); + return; /* drop it */ + } + + defzone[0] = '\0'; + + switch (*zis) { + case ZIPQuery: + case ZIPReply: + case ZIPEReply: + case ZIPGetInfoReq: + break; /* drop it */ + case ZIPGetInfoRepl: + heardFrom = 1; + range_start = (zis[2] << 8) | zis[3]; + range_end = (zis[4] << 8) | zis[5]; + if ((x = zis[6]) < sizeof(defzone)) { + bcopy(&zis[7], defzone, x); + defzone[x] = '\0'; + } + x += 7; /* multicast address */ + if (zis[x] != sizeof(zmcaddr)) { + fprintf(stderr, "Bogus Multicast Address length %d\n", zis[x]); + exit(1); + } + bcopy(&zis[x+1], zmcaddr, sizeof(zmcaddr)); + logit(3, "GetNetInfo reply packet arrived:"); + logit(3, "%sFlags 0x%02x, rangeStart %04x, rangeEnd %04x", + " ", zis[1], range_start, range_end); + logit(3, "%sZone %s (len %d), MCZAddr %x:%x:%x:%x:%x:%x", + " ", defzone, zis[6], (u_char) zmcaddr[0], + (u_char) zmcaddr[1], (u_char) zmcaddr[2], + (u_char) zmcaddr[3], (u_char) zmcaddr[4], + (u_char) zmcaddr[5]); + if (zis[1] & ZIPZoneBad) { + x += 7; + if (zis[x] < sizeof(defzone)) { + bcopy(&zis[x+1], defzone, zis[x]); + defzone[zis[x]] = '\0'; + } + fprintf(stderr, "Zone \"%s\" unknown, network default is \"%s\"\n", + GetMyZone(), defzone); + exit(1); + } + range = ((range_start << 16) | (range_end & 0xffff)); + if (range_set_svc(&range, 0L) == NULL) { + fprintf(stderr, "Can't change network range!\n"); + exit(1); + } + strncpy(ifreq.ifr_name, interface, sizeof(ifreq.ifr_name)); + if (pi_addmulti(-1, zmcaddr, (caddr_t)&ifreq) < 0) { + fprintf(stderr, "Can't add zone multicast address!\n"); + exit(1); + } + break; + } + } + + /* + * open the ZIS socket, start the listener, probe for netinfo + * + */ + + int + getNetInfo() + { + void zis_listener(); + ABusRecord ddpr; + u_char zipbuf[48]; + char *GetMyZone(); + int count; + + abInit(FALSE); + heardFrom = 0; + zisSkt = ddpZIP; + if (DDPOpenSocket(&zisSkt, zis_listener) != noErr) { + logit(0, "Failed to start ZIS listener!"); + exit(1); + } + zipbuf[0] = ZIPGetInfoReq; zipbuf[1] = 0x0; + zipbuf[2] = 0x0; zipbuf[3] = 0x0; + zipbuf[4] = 0x0; zipbuf[5] = 0x0; + strncpy(&zipbuf[7], GetMyZone(), sizeof(zipbuf)-8); + zipbuf[6] = strlen(&zipbuf[7]); + ddpr.abResult = 0; + ddpr.proto.ddp.ddpAddress.net = 0x0000; /* local net */ + ddpr.proto.ddp.ddpAddress.node = 0xff; /* broadcast */ + ddpr.proto.ddp.ddpAddress.skt = zisSkt; /* to ZIS at GW */ + ddpr.proto.ddp.ddpSocket = zisSkt; /* from our ZIS */ + ddpr.proto.ddp.ddpType = ddpZIP; + ddpr.proto.ddp.ddpDataPtr = (u_char *) zipbuf; + ddpr.proto.ddp.ddpReqCount = zipbuf[6] + 7; + for (count = 0 ; count < ZIPATTEMPTS ; count++) { + logit(3, "sending GetNetInfo request ..."); + DDPWrite(&ddpr, FALSE); /* send it to GW */ + abSleep(sectotick(4), FALSE); /* wait for a reply */ + if (heardFrom) break; /* don't ask again */ + } + /* abSleep(sectotick(10), FALSE); /* time to re-init */ + if (!heardFrom) + heardFrom = 1; /* ignore it later */ + logit(3, "AARPD .... Running"); + } + #endif PHASE2 *** support/ethertalk/aarpd.h.orig Thu Feb 28 23:46:12 1991 --- support/ethertalk/aarpd.h Wed May 29 22:31:28 1991 *************** *** 6,11 **** --- 6,12 ---- #define AARP_RESOLVE ((u_long)1) #define RTMP_GETBADDR ((u_long)2) #define RTMP_SETBADDR ((u_long)3) + #define NET_RANGE_SET ((u_long)4) #define INTFSIZE 50 #define INTZONESIZE 40 *** support/ethertalk/aarpd_clnt.c.orig Thu Mar 14 15:32:00 1991 --- support/ethertalk/aarpd_clnt.c Wed May 29 22:33:07 1991 *************** *** 4,9 **** --- 4,10 ---- * Created: Charles Hedrick, Rutgers University * Modified: David Hornsby, Melbourne University * 16/02/91: add rtmp_[sg]etbaddr_clnt() + * 28/04/91: add range_set_clnt() */ #include *************** *** 69,71 **** --- 70,92 ---- } return (res); } + + #ifdef PHASE2 + /* + * Set the network range + */ + + u_char * + range_set_clnt(argp, clnt) + int *argp; + CLIENT *clnt; + { + static bridgeaddr res; /* convenient size */ + bzero((char *)res, sizeof(res)); + if (clnt_call(clnt, NET_RANGE_SET, xdr_int, argp, xdr_bridgeaddr, + res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (res); + } + #endif PHASE2 *** support/ethertalk/aarpd_svc.c.orig Thu Mar 14 15:32:58 1991 --- support/ethertalk/aarpd_svc.c Wed May 29 22:36:29 1991 *************** *** 4,9 **** --- 4,10 ---- * Created: Charles Hedrick, Rutgers University * Modified: David Hornsby, Melbourne University * 16/02/91: add RTMP_[SG]ETBADDR + * 28/04/91: add NET_RANGE_SET * */ *************** *** 17,22 **** --- 18,26 ---- extern char *aarp_resolve_svc(); extern char *rtmp_getbaddr_svc(); extern char *rtmp_setbaddr_svc(); + #ifdef PHASE2 + extern char *range_set_svc(); + #endif PHASE2 void aarpdprog(rqstp, transp) *************** *** 52,57 **** --- 56,69 ---- xdr_result = xdr_bridgeaddr; local = (char *(*)()) rtmp_setbaddr_svc; break; + + #ifdef PHASE2 + case NET_RANGE_SET: + xdr_argument = xdr_int; + xdr_result = xdr_bridgeaddr; + local = (char *(*)()) range_set_svc; + break; + #endif PHASE2 default: svcerr_noproc(transp); *** support/ethertalk/aarptest.c.orig Wed Mar 13 21:12:20 1991 --- support/ethertalk/aarptest.c Wed May 29 22:38:32 1991 *************** *** 9,14 **** --- 9,16 ---- #include #include #include + #include + #include "../uab/ethertalk.h" #include "aarpd.h" extern u_char *aarp_resolve_clnt(); *************** *** 23,29 **** { CLIENT *cl; u_char *ether; ! int node; #ifdef pyr int sock; struct timeval tv; --- 25,31 ---- { CLIENT *cl; u_char *ether; ! struct ethertalkaddr node; #ifdef pyr int sock; struct timeval tv; *************** *** 48,54 **** } if (argc > 1) { ! node = atoi(argv[1]); ether = aarp_resolve_clnt(&node, cl); if (ether == NULL) { clnt_perror(cl, "localhost"); --- 50,65 ---- } if (argc > 1) { ! #ifdef PHASE2 ! if (argc > 2) { ! node.dummy[0] = 0; ! node.dummy[1] = (htons(atoi(argv[2])) >> 8) & 0xff; ! node.dummy[2] = (htons(atoi(argv[2])) & 0xff); ! } ! #else PHASE2 ! node.dummy[0] = node.dummy[1] = node.dummy[2] = 0; ! #endif PHASE2 ! node.node = atoi(argv[1]) & 0xff; ether = aarp_resolve_clnt(&node, cl); if (ether == NULL) { clnt_perror(cl, "localhost"); *** support/ethertalk/abelap.c.orig Wed Mar 13 21:10:47 1991 --- support/ethertalk/abelap.c Wed May 29 22:39:44 1991 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 91/03/13 20:09:38 $ ! * $Header: abelap.c,v 2.2 91/03/13 20:09:38 djh Exp $ ! * $Revision: 2.2 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1991/05/29 12:39:38 $ ! * $Header: /mac/src/cap60/support/ethertalk/RCS/abelap.c,v 2.3 1991/05/29 12:39:38 djh Rel djh $ ! * $Revision: 2.3 $ */ /* *************** *** 17,22 **** --- 17,23 ---- * * June 14, 1986 Schilit Created. * June 18, 1986 CCKim Chuck's handler runs protocol + * April 28,1991 djh Add Phase 2 support * */ /* *************** *** 31,36 **** --- 32,39 ---- * Return bridge addresses * OSErr SetBridgeAddress(AddrBlock *addr) * Set bridge addresses + * OSErr SetNetRange(u_short range_start, u_short range_end) + * Set Network Range (Phase 2) * int abInit(boolean dispay_message) * Initialize AppleTalk * int abOpen(int *returnsocket, int wantsocket, struct iovec iov[], iovlen) *************** *** 83,91 **** --- 86,102 ---- extern byte this_node, bridge_node, nis_node; extern char this_zone[34], async_zone[34], interface[50]; + #ifdef PHASE2 + extern word net_range_start, net_range_end; + #endif PHASE2 + extern struct in_addr bridge_addr; + #ifdef PHASE2 /* not a dynamic choice yet ... */ + short lap_proto = LAP_ETALK; /* default to EtherTalk Phase 2 */ + #else PHASE2 short lap_proto = LAP_ETALK; /* default to EtherTalk Phase 1 */ + #endif PHASE2 /* * Configuration defines *************** *** 117,123 **** --- 128,138 ---- private u_char *lasteaddr; private u_char eaddrbuf[16]; + #ifdef PHASE2 + u_char etherbroad[6] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff}; + #else PHASE2 u_char etherbroad[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + #endif PHASE2 private struct sockaddr_in from_sin; /* network struct of last packet rec. */ private struct sockaddr_in abfsin; /* apple bus foreign socketaddr/internet */ *************** *** 538,550 **** lastnet = -1; lastnode = -1; ! if ((cc = pi_reada(fd, pack, packsize, eaddrbuf)) < 0) { return(-1); ! } lasteaddr = eaddrbuf + 6; if (cc <= lapSize) /* not much use if only lap */ return(-1); pos = lapSize; cc -= pos; iov++; --- 553,566 ---- lastnet = -1; lastnode = -1; ! if ((cc = pi_reada(fd, pack, packsize, eaddrbuf)) <= 0) return(-1); ! lasteaddr = eaddrbuf + 6; if (cc <= lapSize) /* not much use if only lap */ return(-1); + pos = lapSize; cc -= pos; iov++; *************** *** 552,566 **** bcopy(pack, &laph, lapSize); ! if (laph.src == 0xff) { /* bad, bad, bad */ return(-1); ! } /* lap dest isn't right */ /* fixup point */ ! if (laph.dst != 0xff && laph.dst != this_node) { return(-1); - } #ifdef undef /* pick out source for aarp table management if not self */ --- 568,581 ---- bcopy(pack, &laph, lapSize); ! if (laph.src == 0xff) /* bad, bad, bad */ return(-1); ! /* lap dest isn't right */ /* fixup point */ ! if (laph.dst != 0xff && laph.dst != this_node) return(-1); #ifdef undef /* pick out source for aarp table management if not self */ *************** *** 673,678 **** --- 688,694 ---- int fd; unsigned char *eaddr; int destnode; + int destnet; AARP_ENTRY *ae; struct ethertalkaddr etaddr; AddrBlock baddr; *************** *** 718,736 **** perror("abwrite"); return(err); } if ((lap_proto == LAP_ETALK) && (ddp->dstNet != this_net || ddp->dstNode != this_node)) { eaddr = NULL; if (ddp->dstNet == this_net) { destnode = ddp->dstNode; } else { if (ddp->dstNet == lastnet && ddp->dstNode == lastnode) { destnode = lastlnode; eaddr = lasteaddr; } else { ! if (GetBridgeAddress(&baddr) == noErr && baddr.node) destnode = baddr.node; ! else return(-1); } } --- 734,768 ---- perror("abwrite"); return(err); } + #ifdef PHASE2 + /* delete the unwanted LAP header */ + iov[IOV_LAP_LVL].iov_len = 0; + #endif PHASE2 if ((lap_proto == LAP_ETALK) && (ddp->dstNet != this_net || ddp->dstNode != this_node)) { eaddr = NULL; + #ifdef PHASE2 + if ((ddp->dstNet == 0 && ddp->dstNode == 0xff) /* local broadcast */ + || (ddp->dstNet >= net_range_start && ddp->dstNet <= net_range_end) + || (ddp->dstNet >= 0xff00 && ddp->dstNet <= 0xfffe)) { /* startup */ + destnode = ddp->dstNode; + destnet = ddp->dstNet; + } else { + #else PHASE2 if (ddp->dstNet == this_net) { destnode = ddp->dstNode; + destnet = ddp->dstNet; } else { + #endif PHASE2 if (ddp->dstNet == lastnet && ddp->dstNode == lastnode) { destnode = lastlnode; + destnet = lastnet; eaddr = lasteaddr; } else { ! if (GetBridgeAddress(&baddr) == noErr && baddr.node) { destnode = baddr.node; ! destnet = baddr.net; ! } else return(-1); } } *************** *** 741,747 **** --- 773,785 ---- if (destnode == 0xff) eaddr = etherbroad; else { + #ifdef PHASE2 + etaddr.dummy[0] = 0; + etaddr.dummy[1] = (htons(destnet) >> 8) & 0xff; + etaddr.dummy[2] = (htons(destnet) & 0xff); + #else PHASE2 etaddr.dummy[0] = etaddr.dummy[1] = etaddr.dummy[2] = 0; + #endif PHASE2 etaddr.node = destnode; if ((ae = aarptab_find(&aih, &etaddr)) != NULL && ae->aae_flags & AARP_OKAY) { *************** *** 754,760 **** } if (! eaddr) { ! eaddr = aarp_resolve_clnt(&destnode, cl); if (eaddr == NULL) { clnt_perror(cl, "localhost"); return(-1); --- 792,798 ---- } if (! eaddr) { ! eaddr = aarp_resolve_clnt(&etaddr, cl); if (eaddr == NULL) { clnt_perror(cl, "localhost"); return(-1); *************** *** 839,841 **** --- 877,906 ---- bridge_node = addr->node; return(noErr); } + + #ifdef PHASE2 + /* + * Set Network Range (via RPC for Native EtherTalk) + * + */ + + OSErr + SetNetRange(range_start, range_end) + u_short range_start, range_end; + { + AddrBlock *baddr; + long range; + + if (lap_proto == LAP_ETALK) { + range = range_start & 0xffff; /* host byte order */ + range <<= 16; + range |= range_end & 0xffff; /* host byte order */ + baddr = (AddrBlock *) range_set_clnt(&range, cl); + if (baddr == NULL) + clnt_perror(cl, "localhost"); + } + this_net = nis_net = net_range_start = range_start; + net_range_end = range_end; + return(noErr); + } + #endif PHASE2 *** lib/cap/abnbp.c.orig Wed Mar 13 21:00:37 1991 --- lib/cap/abnbp.c Wed May 29 22:41:01 1991 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 91/03/13 20:00:06 $ ! * $Header: abnbp.c,v 2.2 91/03/13 20:00:06 djh Exp $ ! * $Revision: 2.2 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1991/05/29 12:40:53 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abnbp.c,v 2.3 1991/05/29 12:40:53 djh Rel djh $ ! * $Revision: 2.3 $ */ /* *************** *** 20,25 **** --- 20,26 ---- * July 1, 1986 Schilit rewrite with async and NBPConfirm * July 9, 1986 CCKim Clean up and rewrite create_entity * July 15, 1986 CCKim Add nbpregister, nbpdelete + * April 28,1991 djh Added Phase 2 support * */ *************** *** 370,375 **** --- 371,395 ---- break; } nsize = c2pkt_ename(nbpr->nbpEntityPtr,nbp.tuple[0].name); + #ifdef PHASE2 + { char *q, *GetMyZone(); + /* add the zone name for outgoing NBP lookups */ + if (nbpr->abOpcode == tNBPLookUp && nsize >= 2) { + q = (char *) &nbp.tuple[0].name[nsize-2]; + if (*q == 0x01 && *(q+1) == '*') { /* zone "*" */ + strcpy(q+1, GetMyZone()); + *q = strlen(q+1); + nsize += (*q - 1); + } else { + if (*(q+1) == '\0') { /* null zone */ + strcpy(q+2, GetMyZone()); + *(q+1) = strlen(q+2); + nsize += *(q+1); + } + } + } + } + #endif PHASE2 ddpr->ddpReqCount = nbpBaseSize+nsize; DDPWrite(&ddp); /* write it out... */ } *** lib/cap/atalkdbm.c.orig Thu Apr 11 22:00:56 1991 --- lib/cap/atalkdbm.c Wed May 29 22:42:09 1991 *************** *** 1,10 **** /* ! * $Date: 91/04/11 22:00:15 $ ! * $Header: atalkdbm.c,v 2.5 91/04/11 22:00:15 djh Exp $ ! * $Revision: 2.5 $ * * mods for async appletalk support, /etc/etalk.local for EtherTalk and * changes for quoted zone names: djh@munnari.OZ.AU, 27/11/90 * */ --- 1,11 ---- /* ! * $Date: 1991/05/29 12:42:02 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/atalkdbm.c,v 2.6 1991/05/29 12:42:02 djh Rel djh $ ! * $Revision: 2.6 $ * * mods for async appletalk support, /etc/etalk.local for EtherTalk and * changes for quoted zone names: djh@munnari.OZ.AU, 27/11/90 + * Phase 2 support: djh@munnari.OZ.AU, 28/04/91 * */ *************** *** 52,57 **** --- 53,62 ---- u_char this_node=0, bridge_node=0, nis_node=0; char this_zone[34], async_zone[34], interface[50]; + #ifdef PHASE2 + u_short net_range_start = 0, net_range_end = 0xfffe; + #endif PHASE2 + struct in_addr bridge_addr; char enet_device[50]; *************** *** 338,346 **** --- 343,361 ---- if (lap_proto == LAP_MKIP) fprintf(fp, "# Generated by UAB\n#\n"); if (lap_proto == LAP_ETALK) + #ifdef PHASE2 + fprintf(fp, "# Generated by native EtherTalk (Phase 2)\n#\n"); + #else PHASE2 fprintf(fp, "# Generated by native EtherTalk (Phase 1)\n#\n"); + #endif PHASE2 if (*interface != '\0') fprintf(fp, "%-12s\t\"%s\"\n", ETH_INTERFACE, interface); + #ifdef PHASE2 + fprintf(fp, "%-12s\t%2d.%02d\n", ETH_NET_START, + ((ntohs(net_range_start) >> 8) & 0xff), (ntohs(net_range_start) & 0xff)); + fprintf(fp, "%-12s\t%2d.%02d\n", ETH_NET_END, + ((ntohs(net_range_end) >> 8) & 0xff), (ntohs(net_range_end) & 0xff)); + #endif PHASE2 fprintf(fp, "%-12s\t%2d.%02d\n", ETH_THIS_NET, ((ntohs(this_net) >> 8) & 0xff), (ntohs(this_net) & 0xff)); fprintf(fp, "%-12s\t%d\n", ETH_THIS_NODE, (this_node & 0xff)); *************** *** 378,383 **** --- 393,404 ---- if (strcmp(name, ETH_INTERFACE) == 0) strncpy(interface, value, sizeof(interface)); + #ifdef PHASE2 + else if (strcmp(name, ETH_NET_START) == 0) + net_range_start = htons(atnetshort(value)); + else if (strcmp(name, ETH_NET_END) == 0) + net_range_end = htons(atnetshort(value)); + #endif PHASE2 else if (strcmp(name, ETH_THIS_NET) == 0) this_net = htons(atnetshort(value)); else if (strcmp(name, ETH_THIS_NODE) == 0) *** lib/cap/atalkdbm.h.orig Thu Feb 28 23:43:18 1991 --- lib/cap/atalkdbm.h Wed May 29 22:43:17 1991 *************** *** 18,20 **** --- 18,24 ---- #define ETH_ASYNC_NET "asyncNet" #define ETH_ASYNC_ZONE "asyncZone" #define ETH_INTERFACE "interface" + #ifdef PHASE2 + #define ETH_NET_START "netRangeStart" + #define ETH_NET_END "netRangeEnd" + #endif PHASE2 *** etc/atis.c.orig Wed Mar 13 20:48:53 1991 --- etc/atis.c Wed May 29 22:44:18 1991 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 91/03/13 19:47:20 $"; ! static char rcsident[] = "$Header: atis.c,v 2.2 91/03/13 19:47:20 djh Exp $"; ! static char revision[] = "$Revision: 2.2 $"; /* * atis.c - a simple appletalk information server --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:44:11 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/etc/RCS/atis.c,v 2.3 1991/05/29 12:44:11 djh Rel djh $"; ! static char revision[] = "$Revision: 2.3 $"; /* * atis.c - a simple appletalk information server *************** *** 24,29 **** --- 24,30 ---- * July 10, 1986 CCKim Created * August 2, 1986 CCKim Add dump and load functionality * December 17, 1986 CCKim Revise to rev1086 of UDP code + * April 28, 1991 djh Add Phase 2 support * */ *************** *** 82,87 **** --- 83,92 ---- extern short lap_proto; /* identifies the "LAP" level */ + #ifdef PHASE2 + extern u_short this_net, nis_net, net_range_start, net_range_end; + #endif PHASE2 + #ifndef ETCDIR # define ETCDIR "/etc" #endif *************** *** 719,725 **** rtmp_listener(skt, type, pkt, len, addr) u_char skt; u_char type; ! char *pkt; int len; AddrBlock *addr; { --- 724,730 ---- rtmp_listener(skt, type, pkt, len, addr) u_char skt; u_char type; ! u_char *pkt; int len; AddrBlock *addr; { *************** *** 731,736 **** --- 736,744 ---- static time_t current_time; static u_short current_node; static int current_goodness = -1; + #ifdef PHASE2 + u_short new_net_range_start, new_net_range_end, increment; + #endif PHASE2 if (type != ddpRTMP) { logit(1, "Got non-rtmp pkt in rtmplistener"); *************** *** 737,743 **** return; /* drop packet */ } ! net = *(u_short *)pkt; logit(5, "Got RTMP pkt net %d from %d.%d", net, addr->net, addr->node); if (addr->net == 0 && net != 0) { --- 745,751 ---- return; /* drop packet */ } ! net = (pkt[0] << 8) | pkt[1]; logit(5, "Got RTMP pkt net %d from %d.%d", net, addr->net, addr->node); if (addr->net == 0 && net != 0) { *************** *** 746,752 **** --- 754,764 ---- logit(1, "Gleaned network number %d from bridge %d", net, addr->node); } + #ifdef PHASE2 + if (net >= net_range_start && net <= net_range_end) { + #else PHASE2 if (net == addr->net) { + #endif PHASE2 /* * Compute the goodness of this router. We prefer routers that do * split horizon, and among them, those that have the most routes. *************** *** 772,779 **** --- 784,823 ---- /* * go to beginning of routing triples */ + #ifdef PHASE2 + pkt += 4; + len -= 4; + if (pkt[0] == 0 && pkt[1] == 0 && pkt[2] == 0x82) { /* non-extended net */ + new_net_range_start = net; + new_net_range_end = net; + increment = 0; + } else if (pkt[5] == 0x82) { /* extended network */ + new_net_range_start = (pkt[0] << 8) | pkt[1]; + new_net_range_end = (pkt[3] << 8) | pkt[4]; + pkt += 3; len -= 3; + increment = 3; + } else { + logit(2, "RTMP: unknown format packet, dropped!"); + return; + } + pkt += 3; len -= 3; + #ifdef notdef + /* ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ */ + /* we should be doing this, in case the router was down when */ + /* we started up. However, doing so will proably confuse our */ + /* clients too much. We should also do it to ensure that the */ + /* correct zone multicast address gets enabled on the intrfc */ + /* ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ */ + if (net_range_start == 0x00 && net_range_end == 0xfffe) { + this_net = nis_net = net_range_start = new_net_range_start; + net_range_end = new_net_range_end; + SetNetRange(net_range_start, net_range_end); + } + #endif notdef + #else PHASE2 pkt += 7; len -= 7; + #endif PHASE2 /* * loop over routing triples, counting them. * If we find our own network, this router isn't doing split horizon. *************** *** 789,794 **** --- 833,842 ---- goodness++; len -= 3; pkt += 3; + #ifdef PHASE2 + len -= increment; + pkt += increment; + #endif PHASE2 } logit (8, "Router %d.%d has goodness %d", addr->net, addr->node, goodness); now = time(NULL); *** samples/atlook.c.orig Thu Mar 14 14:59:27 1991 --- samples/atlook.c Wed May 29 22:45:55 1991 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 91/03/14 13:58:44 $"; ! static char rcsident[] = "$Header: atlook.c,v 2.2 91/03/14 13:58:44 djh Exp $"; ! static char revision[] = "$Revision: 2.2 $"; /* * atlook - UNIX AppleTalk test program: lookup entities --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:45:49 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/samples/RCS/atlook.c,v 2.3 1991/05/29 12:45:49 djh Rel djh $"; ! static char revision[] = "$Revision: 2.3 $"; /* * atlook - UNIX AppleTalk test program: lookup entities *************** *** 280,285 **** --- 280,288 ---- { int i; EntityName en; /* network entity name */ + #ifdef PHASE2 + char *GetMyZone(); + #endif PHASE2 abInit(TRUE); /* initialize appletalk driver */ nbpInit(); /* initialize nbp */ *************** *** 292,298 **** --- 295,305 ---- deftype = "LaserWriter"; strcpy(en.objStr.s,"="); /* create default entity */ strcpy(en.typeStr.s,deftype); /* to lookup... */ + #ifdef PHASE2 + strcpy(en.zoneStr.s,GetMyZone()); + #else PHASE2 strcpy(en.zoneStr.s,"*"); + #endif PHASE2 if (i == argc) { *** support/ethertalk/ethertalk.c.orig Thu Mar 14 21:06:29 1991 --- support/ethertalk/ethertalk.c Wed May 29 22:47:09 1991 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 91/03/14 20:06:11 $"; ! static char rcsident[] = "$Header: ethertalk.c,v 2.2 91/03/14 20:06:11 djh Exp $"; ! static char revision[] = "$Revision: 2.2 $"; /* * ethertalk.c - ethertalk interface --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:47:04 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/ethertalk.c,v 2.3 1991/05/29 12:47:04 djh Rel djh $"; ! static char revision[] = "$Revision: 2.3 $"; /* * ethertalk.c - ethertalk interface *************** *** 21,26 **** --- 21,27 ---- * Edit History: * * April 3, 1988 CCKim Created + * April 28, '91 djh Added Phase 2 support * */ *************** *** 62,67 **** --- 63,71 ---- private int etalk_tables(); extern byte this_node; + #ifdef PHASE2 + extern u_short this_net; + #endif PHASE2 /* describe our interface to the world */ private char *ethertalk_lap_keywords[] = { *************** *** 158,164 **** --- 162,172 ---- eh->eh_state = ELAP_WAITING; /* mark waiting */ /* acquire node address */ + #ifdef PHASE2 + if ( this_node <= 0 || this_node >= 254) + #else PHASE2 if ( this_node <= 0 || this_node >= 255) + #endif PHASE2 hostid = 0xff & gethostid(); /* use last byte of hostid as hint */ else hostid = this_node; *************** *** 190,198 **** struct ethertalkaddr pa; int n; pa.dummy[0] = pa.dummy[1] = pa.dummy[2] = 0; ! /* EtherTalk II fixup */ ! pa.node = hint; /* use fourth byte of eaddr as guess */ while ((n=aarp_acquire_etalk_node(eh->eh_ah, &pa, who, eh)) != 0) { if (n < 0) { /* error */ --- 198,211 ---- struct ethertalkaddr pa; int n; + #ifdef PHASE2 + pa.dummy[0] = 0; /* always zero */ + pa.dummy[1] = (htons(this_net) >> 8) & 0xff; + pa.dummy[2] = (htons(this_net) & 0xff); + #else PHASE2 pa.dummy[0] = pa.dummy[1] = pa.dummy[2] = 0; ! #endif PHASE2 ! pa.node = hint; while ((n=aarp_acquire_etalk_node(eh->eh_ah, &pa, who, eh)) != 0) { if (n < 0) { /* error */ *************** *** 220,226 **** --- 233,243 ---- IDESC_TYPE *id = eh->eh_id; /* get interface description */ if (result < 0) { + #ifdef PHASE2 + if ((result = etalk_getnode(eh,(rand()%253)+1, etalk_initfinish)) < 0) { + #else PHASE2 if ((result = etalk_getnode(eh,(rand()%254)+1, etalk_initfinish)) < 0) { + #endif PHASE2 logit(LOG_LOG, "could not acquire node on interface %s%d", id->id_intf, id->id_intfno); eh->eh_state = ELAP_BAD; *************** *** 235,244 **** eh->eh_state = ELAP_BAD; /* mark bad */ return; } ! eh->eh_enode.n_size = 8*nodesize; /* 8 bits */ ! eh->eh_enode.n_bytes = nodesize; /* 1 byte */ ! /* EtherTalk II fixup */ eh->eh_enode.n_id[0] = pa.node; /* this is it */ flags = PORT_WANTSLONGDDP; if (!pi_delivers_self_broadcasts()) --- 252,267 ---- eh->eh_state = ELAP_BAD; /* mark bad */ return; } ! eh->eh_enode.n_size = 8*nodesize; /* 8 or 32 bits */ ! eh->eh_enode.n_bytes = nodesize; /* 1 or 4 bytes */ ! #ifdef PHASE2 ! eh->eh_enode.n_id[0] = pa.dummy[0]; ! eh->eh_enode.n_id[1] = pa.dummy[1]; ! eh->eh_enode.n_id[2] = pa.dummy[2]; ! eh->eh_enode.n_id[3] = pa.node; ! #else PHASE2 eh->eh_enode.n_id[0] = pa.node; /* this is it */ + #endif PHASE2 flags = PORT_WANTSLONGDDP; if (!pi_delivers_self_broadcasts()) *************** *** 246,252 **** if (id->id_isabridge) flags |= PORT_FULLRTMP; ! eh->eh_state = ELAP_BAD; logit(LOG_PRIMARY,"acquired node %d on interface %s%d", pa.node, id->id_intf, id->id_intfno); } --- 269,275 ---- if (id->id_isabridge) flags |= PORT_FULLRTMP; ! eh->eh_state = ELAP_READY; logit(LOG_PRIMARY,"acquired node %d on interface %s%d", pa.node, id->id_intf, id->id_intfno); } *************** *** 261,285 **** eh = (E_HANDLE *)id->id_ifuse; ! /* EtherTalk II fixup */ tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0; tpa.node = node; ! if (aarp_resolve(eh->eh_ah, &tpa, node == 0xff, &eaddr) <= 0) { ! logit (2, "etalk_resolve: node %d try again later", node); return(NULL); } return(eaddr); } ! export etalk_mynode(id) IDESC_TYPE *id; { E_HANDLE *eh; eh = (E_HANDLE *)id->id_ifuse; ! return (eh->eh_enode.n_id[0]); } /* --- 284,340 ---- eh = (E_HANDLE *)id->id_ifuse; ! #ifdef PHASE2 ! bcopy(&node, &tpa, ETPL); ! #else PHASE2 tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0; tpa.node = node; + #endif PHASE2 ! if (aarp_resolve(eh->eh_ah, &tpa, tpa.node == 0xff, &eaddr) <= 0) { ! #ifdef PHASE2 ! logit (2, "etalk_resolve: node %d/%d.%d try again later", ! tpa.node, tpa.dummy[1], tpa.dummy[2]); ! #else PHASE2 ! logit (2, "etalk_resolve: node %d try again later", tpa.node); ! #endif PHASE2 return(NULL); } return(eaddr); } ! #ifdef PHASE2 ! export int etalk_set_mynode(id, eaddr) IDESC_TYPE *id; + struct ethertalkaddr *eaddr; { E_HANDLE *eh; + int hostid = eaddr->node; eh = (E_HANDLE *)id->id_ifuse; + return(aarp_set_host_addr(eh->eh_ah, eaddr)); + } + #endif PHASE2 ! export struct ethertalkaddr *etalk_mynode(id) ! IDESC_TYPE *id; ! { ! E_HANDLE *eh; ! static struct ethertalkaddr ea; ! ! eh = (E_HANDLE *)id->id_ifuse; ! #ifdef PHASE2 ! ea.dummy[0] = eh->eh_enode.n_id[0]; ! ea.dummy[1] = eh->eh_enode.n_id[1]; ! ea.dummy[2] = eh->eh_enode.n_id[2]; ! ea.node = eh->eh_enode.n_id[3]; ! #else PHASE2 ! ea.dummy[0] = 0; ! ea.dummy[1] = 0; ! ea.dummy[2] = 0; ! ea.node = eh->eh_enode.n_id[0]; ! #endif PHASE2 ! return (&ea); } /* *************** *** 292,305 **** word ddpnet; byte ddpnode; { ! /* EtherTalk II fixup */ ! /* think this is okay */ static NODE node = { 1, 8 }; /* initialize */ int myddpnet = PORT_DDPNET(port); if (ddpnet != 0 && myddpnet != ddpnet) /* only allow this net! */ return(NULL); node.n_id[0] = ddpnode; /* make node */ return(&node); } --- 347,371 ---- word ddpnet; byte ddpnode; { ! #ifdef PHASE2 ! static NODE node = { 4, 32}; /* initialize */ ! #else PHASE2 static NODE node = { 1, 8 }; /* initialize */ + #endif PHASE2 int myddpnet = PORT_DDPNET(port); if (ddpnet != 0 && myddpnet != ddpnet) /* only allow this net! */ return(NULL); + + #ifdef PHASE2 + node.n_id[0] = 0; + node.n_id[1] = (htons(ddpnet) >> 8) & 0xff; + node.n_id[2] = (htons(ddpnet) & 0xff); + node.n_id[3] = ddpnode; + #else PHASE2 node.n_id[0] = ddpnode; /* make node */ + #endif PHASE2 + return(&node); } *************** *** 310,318 **** PORT_T port; NODE *node; { - /* EtherTalk II fixup */ if (node->n_size == 8) /* 8 bits? */ return(node->n_id[0]); return(0); } --- 376,387 ---- PORT_T port; NODE *node; { if (node->n_size == 8) /* 8 bits? */ return(node->n_id[0]); + #ifdef PHASE2 + if (node->n_size == 32) /* 32 bits? */ + return(node->n_id[3]); + #endif PHASE2 return(0); } *************** *** 361,379 **** stats[ES_ERR_OUTPUT]++; /* can't */ return(-1); } - /* source is always us! */ - lap.src = eh->eh_enode.n_id[0]; /* get source node */ - lap.dst = dstnode->n_id[0]; /* get dest node */ lap.type = laptype; ! /* EtherTalk II fixup */ tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0; tpa.node = dstnode->n_id[0]; if (aarp_resolve(eh->eh_ah, &tpa, lap.dst == 0xff, &eaddr) <= 0) { stats[ES_RESOLVE_ERR_OUTPUT]++; return(-1); } iov[0].iov_len = lapSize; iov[0].iov_base = (caddr_t)⪅ iov[1].iov_len = hsize; iov[1].iov_base = (caddr_t)header; --- 430,462 ---- stats[ES_ERR_OUTPUT]++; /* can't */ return(-1); } lap.type = laptype; ! #ifdef PHASE2 ! tpa.dummy[0] = dstnode->n_id[0]; ! tpa.dummy[1] = dstnode->n_id[1]; ! tpa.dummy[2] = dstnode->n_id[2]; ! tpa.node = dstnode->n_id[3]; ! lap.dst = dstnode->n_id[3]; /* get dest node */ ! /* source is always us! */ ! lap.src = eh->eh_enode.n_id[3]; /* get source node */ ! #else PHASE2 tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0; tpa.node = dstnode->n_id[0]; + lap.dst = dstnode->n_id[0]; /* get dest node */ + /* source is always us! */ + lap.src = eh->eh_enode.n_id[0]; /* get source node */ + #endif PHASE2 if (aarp_resolve(eh->eh_ah, &tpa, lap.dst == 0xff, &eaddr) <= 0) { stats[ES_RESOLVE_ERR_OUTPUT]++; return(-1); } + #ifdef PHASE2 + /* delete LAP hdr */ + iov[0].iov_len = 0; + #else PHASE2 iov[0].iov_len = lapSize; + #endif PHASE2 iov[0].iov_base = (caddr_t)⪅ iov[1].iov_len = hsize; iov[1].iov_base = (caddr_t)header; *** support/uab/ethertalk.h.orig Thu Feb 28 23:45:54 1991 --- support/uab/ethertalk.h Wed May 29 22:48:28 1991 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 91/02/15 23:07:30 $ ! * $Header: ethertalk.h,v 2.1 91/02/15 23:07:30 djh Rel $ ! * $Revision: 2.1 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1991/05/29 12:48:21 $ ! * $Header: /mac/src/cap60/support/uab/RCS/ethertalk.h,v 2.2 1991/05/29 12:48:21 djh Rel djh $ ! * $Revision: 2.2 $ */ /* *************** *** 21,26 **** --- 21,27 ---- * Edit History: * * August 1988 CCKim Created + * April 1991 djh Added Phase 2 support * */ *** etc/nisaux.c.orig Wed Mar 13 20:50:27 1991 --- etc/nisaux.c Wed May 29 22:50:28 1991 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 91/03/13 19:50:02 $ ! * $Header: nisaux.c,v 2.2 91/03/13 19:50:02 djh Exp $ ! * $Revision: 2.2 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1991/05/29 12:50:14 $ ! * $Header: /mac/src/cap60/etc/RCS/nisaux.c,v 2.3 1991/05/29 12:50:14 djh Rel djh $ ! * $Revision: 2.3 $ */ /* *************** *** 89,95 **** --- 89,99 ---- return(nbpSR_access); } + #ifdef PHASE2 + strcpy((char *)en->zoneStr.s, GetMyZone()); /* keep our name in table */ + #else PHASE2 strcpy((char *)en->zoneStr.s, "*"); /* replace zone name with * in records */ + #endif PHASE2 /* scan the list - see if we should be in the list at all. */ for (newenum = 0, i = 0; i < numnve; i++) { *** support/ethertalk/rtmptest.c.orig Wed Mar 13 21:13:25 1991 --- support/ethertalk/rtmptest.c Wed May 29 22:51:28 1991 *************** *** 50,57 **** } if (argc == 3) { ! baddr.net = atoi(argv[1]); ! baddr.node = atoi(argv[2]); addr = rtmp_setbaddr_clnt(&baddr, cl); if (addr == NULL) { clnt_perror(cl, "localhost"); --- 50,57 ---- } if (argc == 3) { ! baddr.node = atoi(argv[1]); ! baddr.net = atoi(argv[2]); addr = rtmp_setbaddr_clnt(&baddr, cl); if (addr == NULL) { clnt_perror(cl, "localhost"); *** support/ethertalk/snitp.c.orig Wed May 29 23:00:55 1991 --- support/ethertalk/snitp.c Wed May 29 23:03:27 1991 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 1991/05/18 07:51:28 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/snitp.c,v 2.2 1991/05/18 07:51:28 djh Exp djh $"; ! static char revision[] = "$Revision: 2.2 $"; /* * snitp.c - Simple "protocol" level interface to Streams based NIT --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 13:03:15 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/snitp.c,v 2.3 1991/05/29 13:03:15 djh Rel djh $"; ! static char revision[] = "$Revision: 2.3 $"; /* * snitp.c - Simple "protocol" level interface to Streams based NIT *************** *** 23,28 **** --- 23,29 ---- * Edit History: * * July 1988 CCKim Created + * April '91 djh Add Phase 2 support * */ *************** *** 65,70 **** --- 66,75 ---- extern char interface[50]; + #ifdef PHASE2 + u_char e_broad[EHRD] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff}; + #endif PHASE2 + /* * setup for particular device devno * all pi_open's will go this device *************** *** 112,122 **** eph = &ephlist[i]; /* find handle */ strncpy(eph->ifr.ifr_name, interface, sizeof eph->ifr.ifr_name); - eph->ifr.ifr_name[sizeof eph->ifr.ifr_name - 1] = ' '; ! if ((s = init_nit(1024, protocol, socket, &eph->ifr)) < 0) { return(-1); - } eph->inuse = TRUE; eph->fd = s; --- 117,125 ---- eph = &ephlist[i]; /* find handle */ strncpy(eph->ifr.ifr_name, interface, sizeof eph->ifr.ifr_name); ! if ((s = init_nit(1024, protocol, socket, &eph->ifr)) < 0) return(-1); eph->inuse = TRUE; eph->fd = s; *************** *** 172,187 **** return(-1); } ! si.ic_timout = INFTIM; ! ! if (setup_pf(s, protocol, socket) < 0) return(-1); #define NOBUF #ifndef NOBUF setup_buf(s, chunksize); ! #endif /* bind */ ! si.ic_cmd = NIOCBIND; /* bind */ si.ic_timout = 10; si.ic_len = sizeof(*ifr); si.ic_dp = (caddr_t)ifr; --- 175,190 ---- return(-1); } ! if (setup_pf(s, protocol, socket) < 0) return(-1); + #define NOBUF #ifndef NOBUF setup_buf(s, chunksize); ! #endif NOBUF ! /* bind */ ! si.ic_cmd = NIOCBIND; /* bind to underlying interface */ si.ic_timout = 10; si.ic_len = sizeof(*ifr); si.ic_dp = (caddr_t)ifr; *************** *** 190,203 **** return(-1); } /* flush read queue */ ioctl(s, I_FLUSH, (char *)FLUSHR); return(s); } ! #ifndef NOBUF /* ! * setup buffering (not wanted) * */ setup_buf(s, chunksize) --- 193,258 ---- return(-1); } + #ifdef PHASE2 + /* enable our multicast broadcast address */ + if (pi_addmulti(s, e_broad, ifr) < 0) { + perror("/dev/nit"); + return(-1); + } + #endif PHASE2 + /* flush read queue */ ioctl(s, I_FLUSH, (char *)FLUSHR); return(s); } ! #ifdef PHASE2 /* ! * add a multicast address to the interface ! */ ! int ! pi_addmulti(s, multi, ifr) ! int s; ! char *multi; ! struct ifreq *ifr; ! { ! struct strioctl si; ! ! if (s < 0) { ! /* get a new clone */ ! if ((s = open("/dev/nit", O_RDWR)) < 0) { ! perror("open: /dev/nit"); ! return(-1); ! } ! /* set up messages */ ! if (ioctl(s, I_SRDOPT, (char *)RMSGD) < 0) { /* want messages */ ! perror("ioctl: discretem"); ! return(-1); ! } ! /* bind */ ! si.ic_cmd = NIOCBIND; /* bind to underlying interface */ ! si.ic_timout = 10; ! si.ic_len = sizeof(*ifr); ! si.ic_dp = (caddr_t)ifr; ! if (ioctl(s, I_STR, (caddr_t)&si) < 0) { ! perror("/dev/nit"); ! return(-1); ! } ! /* flush read queue */ ! ioctl(s, I_FLUSH, (char *)FLUSHR); ! } ! ifr->ifr_addr.sa_family = AF_UNSPEC; ! bcopy(multi, ifr->ifr_addr.sa_data, EHRD); ! if (ioctl(s, SIOCADDMULTI, (caddr_t)ifr) < 0) { ! perror("/dev/nit"); ! return(-1); ! } ! return(s); ! } ! #endif PHASE2 ! ! /* ! * setup buffering * */ setup_buf(s, chunksize) *************** *** 210,220 **** /* Push and configure the buffering module. */ if (ioctl(s, I_PUSH, "nbuf") < 0) { perror("ioctl: nbuf"); } ! timeout.tv_sec = 0; ! timeout.tv_usec = 200; si.ic_cmd = NIOCSTIME; - si.ic_timout = 10; si.ic_len = sizeof timeout; si.ic_dp = (char *)&timeout; if (ioctl(s, I_STR, (char *)&si) < 0) { --- 265,277 ---- /* Push and configure the buffering module. */ if (ioctl(s, I_PUSH, "nbuf") < 0) { perror("ioctl: nbuf"); + return(-1); } ! si.ic_timout = INFTIM; ! ! timeout.tv_sec = 1; ! timeout.tv_usec = 0; si.ic_cmd = NIOCSTIME; si.ic_len = sizeof timeout; si.ic_dp = (char *)&timeout; if (ioctl(s, I_STR, (char *)&si) < 0) { *************** *** 223,229 **** } si.ic_cmd = NIOCSCHUNK; - si.ic_len = sizeof chunksize; si.ic_dp = (char *)&chunksize; if (ioctl(s, I_STR, (char *)&si)) { --- 280,285 ---- *************** *** 230,237 **** perror("ioctl: chunk size"); return(-1); } } - #endif /* * establish protocol filter --- 286,293 ---- perror("ioctl: chunk size"); return(-1); } + return(0); } /* * establish protocol filter *************** *** 250,260 **** --- 306,330 ---- struct strioctl si; #define s_offset(structp, element) (&(((structp)0)->element)) offset = ((int)s_offset(struct ether_header *, ether_type))/sizeof(u_short); + #ifdef PHASE2 + offset += 4; /* shorts: 2 bytes length + 6 bytes of 802.2 and SNAP */ + #endif PHASE2 *fwp++ = ENF_PUSHWORD + offset; *fwp++ = ENF_PUSHLIT | (sock >= 0 ? ENF_CAND : ENF_EQ); *fwp++ = htons(prot); pf.Pf_FilterLen = 3; if (sock >= 0) { + #ifdef PHASE2 + *fwp++ = ENF_PUSHWORD + offset + 6; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0xff00); /* now have dest socket */ + *fwp++ = ENF_PUSHLIT | ENF_COR; + *fwp++ = htons((sock & 0xff) << 8); + /* if not wanted, fail it */ + *fwp++ = ENF_PUSHLIT ; + *fwp++ = 0; + pf.Pf_FilterLen += 7; + #else PHASE2 /* short form */ *fwp++ = ENF_PUSHWORD + offset + 2; *fwp++ = ENF_PUSHLIT | ENF_AND; *************** *** 279,285 **** *fwp++ = ENF_PUSHLIT ; *fwp++ = 0; pf.Pf_FilterLen += 20; ! } si.ic_cmd = NIOCSETF; --- 349,355 ---- *fwp++ = ENF_PUSHLIT ; *fwp++ = 0; pf.Pf_FilterLen += 20; ! #endif PHASE2 } si.ic_cmd = NIOCSETF; *************** *** 374,389 **** caddr_t buf; int bufsiz; { ! struct iovec iov[2]; struct ethernet_addresses ea; int cc; iov[0].iov_base = (caddr_t)&ea; iov[0].iov_len = sizeof(ea); iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = bufsiz; cc = pi_readv(edx, iov, 2); return(cc - sizeof(ea)); } pi_reada(fd, buf, bufsiz, eaddr) --- 444,473 ---- caddr_t buf; int bufsiz; { ! struct iovec iov[3]; struct ethernet_addresses ea; + #ifdef PHASE2 + char header[8]; + #endif PHASE2 int cc; + #ifdef PHASE2 iov[0].iov_base = (caddr_t)&ea; iov[0].iov_len = sizeof(ea); + iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP */ + iov[1].iov_len = sizeof(header); + iov[2].iov_base = (caddr_t)buf; + iov[2].iov_len = bufsiz; + cc = pi_readv(edx, iov, 3); + return(cc - sizeof(ea) - sizeof(header)); + #else PHASE2 + iov[0].iov_base = (caddr_t)&ea; + iov[0].iov_len = sizeof(ea); iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = bufsiz; cc = pi_readv(edx, iov, 2); return(cc - sizeof(ea)); + #endif PHASE2 } pi_reada(fd, buf, bufsiz, eaddr) *************** *** 392,411 **** int bufsiz; char *eaddr; { ! struct iovec iov[2]; int cc; iov[0].iov_base = (caddr_t)eaddr; iov[0].iov_len = 14; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = bufsiz; if ((cc = readv(fd, iov, 2)) < 0) { perror("abread"); return(cc); } ! return(cc - 14); } export int --- 476,518 ---- int bufsiz; char *eaddr; { ! struct iovec iov[3]; ! #ifdef PHASE2 ! char header[5]; /* must be 5! */ ! #endif PHASE2 int cc; + #ifdef PHASE2 iov[0].iov_base = (caddr_t)eaddr; iov[0].iov_len = 14; + iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP but */ + iov[1].iov_len = sizeof(header); /* make room for our fake LAP header */ + iov[2].iov_base = (caddr_t)buf; + iov[2].iov_len = bufsiz; + #else PHASE2 + iov[0].iov_base = (caddr_t)eaddr; + iov[0].iov_len = 14; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = bufsiz; + #endif PHASE2 + #ifdef PHASE2 + if ((cc = readv(fd, iov, 3)) < 0) { + #else PHASE2 if ((cc = readv(fd, iov, 2)) < 0) { + #endif PHASE2 perror("abread"); return(cc); } ! #ifdef PHASE2 ! /* make a fake LAP header to fool the higher levels */ ! buf[0] = buf[11]; /* destination node ID */ ! buf[1] = buf[12]; /* source node ID */ ! buf[2] = 0x02; /* always long DDP */ ! return(cc - 14 - sizeof(header)); ! #else PHASE2 return(cc - 14); + #endif PHASE2 } export int *************** *** 419,424 **** --- 526,534 ---- struct ether_header *eh; struct strbuf pbuf, dbuf; struct sockaddr sa; + #ifdef PHASE2 + char *q; + #endif PHASE2 if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL) return(-1); *************** *** 427,436 **** if (!eph->inuse) return(-1); ! sa.sa_family = AF_UNSPEC; /* by def. */ ! eh = (struct ether_header *)sa.sa_data; /* make pointer */ bcopy(eaddr, &eh->ether_dhost, sizeof(eh->ether_dhost)); ! eh->ether_type = htons(eph->protocol); pbuf.len = sizeof(sa); pbuf.buf = (char *)&sa; dbuf.len = buflen; --- 537,564 ---- if (!eph->inuse) return(-1); ! sa.sa_family = AF_UNSPEC; /* by definition */ ! eh = (struct ether_header *)sa.sa_data; /* make pointer */ bcopy(eaddr, &eh->ether_dhost, sizeof(eh->ether_dhost)); ! #ifdef PHASE2 ! eh->ether_type = htons(buflen); ! /* ! * Fill in the remainder of the 802.2 and SNAP header bytes. ! * Clients have to leave 8 bytes free at the start of buf as ! * NIT won't let us send any more than 14 bytes of header :-( ! */ ! q = (char *) buf; ! *q++ = 0xaa; /* destination SAP */ ! *q++ = 0xaa; /* source SAP */ ! *q++ = 0x03; /* control byte */ ! *q++ = (eph->protocol == 0x809b) ? 0x08 : 0x00; ! *q++ = 0x00; /* always zero */ ! *q++ = (eph->protocol == 0x809b) ? 0x07 : 0x00; ! *q++ = (htons(eph->protocol) >> 8) & 0xff; ! *q++ = (htons(eph->protocol) & 0xff); ! #else PHASE2 ! eh->ether_type = htons(eph->protocol); ! #endif PHASE2 pbuf.len = sizeof(sa); pbuf.buf = (char *)&sa; dbuf.len = buflen; *************** *** 460,466 **** --- 588,598 ---- if (!ephlist[edx-1].inuse) return(-1); + #ifdef PHASE2 /* leave room for rest of ELAP hdr */ + for (len = 8, p = ebuf+8, i = 0 ; i < iovlen ; i++) + #else PHASE2 for (len = 0, p = ebuf, i = 0 ; i < iovlen ; i++) + #endif PHASE2 if (iov[i].iov_base && iov[i].iov_len >= 0) { bcopy(iov[i].iov_base, p, iov[i].iov_len); p += iov[i].iov_len; /* advance */