Patch #: 28 Type: operational change Priority: none Modification: add ULTRIX packet filter/Phase 2 support Submitted: Jeffrey Mogul Submitted: David Hornsby Submitted: Tom Ivar Helbekkmo Archived: munnari.OZ.AU mac/cap.patches/cap60.patch028 Summary: add new spfiltp.c files, fix word byte order File: cap60/Configure File: cap60/support/ethertalk/aarpd.c File: cap60/support/ethertalk/aarptest.c File: cap60/support/ethertalk/abelap.c File: cap60/support/ethertalk/ethertalk.c File: cap60/support/ethertalk/rtmptest.c File: cap60/support/ethertalk/rangetest.c File: cap60/support/ethertalk/spfiltp.c File: cap60/support/ethertalk/snitp.c File: cap60/support/ethertalk/Makefile.m4 File: cap60/support/uab/spfiltp.c *** Configure.orig Thu Jun 13 21:31:37 1991 --- Configure Mon Jul 1 16:14:44 1991 *************** *** 1,7 **** #!/bin/sh ! # $Author: djh $ $Date: 1991/06/13 11:31:28 $ ! # $Header: /mac/src/cap60/RCS/Configure,v 2.11 1991/06/13 11:31:28 djh Rel djh $ ! # $Revision: 2.11 $ # 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/07/01 06:14:31 $ ! # $Header: /mac/src/cap60/RCS/Configure,v 2.12 1991/07/01 06:14:31 djh Rel djh $ ! # $Revision: 2.12 $ # 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) # *************** *** 303,311 **** uabplibs="define([uabplibs],[libuabcap.a])" lapobj="define([lapobj],[abmkip.o abddp.o abnbp.o atalkdbm.o])" case ${os} in ! "ultrix40"|"ultrix20"|"ultrix12") echo "OK, setting things up for UAB." uabpobjs="define([uabpobjs],[dlip.o])";; "pyr") echo "OK, setting things up for UAB." uabpobjs="define([uabpobjs],[senetp.o])";; --- 303,314 ---- uabplibs="define([uabplibs],[libuabcap.a])" lapobj="define([lapobj],[abmkip.o abddp.o abnbp.o atalkdbm.o])" case ${os} in ! "ultrix20"|"ultrix12") echo "OK, setting things up for UAB." uabpobjs="define([uabpobjs],[dlip.o])";; + "ultrix40") + echo "OK, setting things up for UAB." + uabpobjs="define([uabpobjs],[spfiltp.o])";; "pyr") echo "OK, setting things up for UAB." uabpobjs="define([uabpobjs],[senetp.o])";; *************** *** 355,363 **** etherprogs="define([etherprogs],[aarpd])" lapobj="define([lapobj],[abetalk.o abddp.o abnbp.o atalkdbm.o])" case ${os} in ! "ultrix40"|"ultrix20"|"ultrix12") echo "OK, setting things up for Native EtherTalk." etherpobjs="define([etherpobjs],[dlip.o])";; "pyr") echo "OK, setting things up for Native EtherTalk." etherpobjs="define([etherpobjs],[senetp.o])";; --- 358,383 ---- etherprogs="define([etherprogs],[aarpd])" lapobj="define([lapobj],[abetalk.o abddp.o abnbp.o atalkdbm.o])" case ${os} in ! "ultrix20"|"ultrix12") echo "OK, setting things up for Native EtherTalk." etherpobjs="define([etherpobjs],[dlip.o])";; + "ultrix40") + 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 "OK, setting things up for Native EtherTalk, Phase 2" + ;; + *) + echo "OK, setting things up for Native EtherTalk." + ;; + esac + etherpobjs="define([etherpobjs],[spfiltp.o])";; "pyr") echo "OK, setting things up for Native EtherTalk." etherpobjs="define([etherpobjs],[senetp.o])";; *** support/ethertalk/aarpd.c.orig Wed May 29 22:30:30 1991 --- support/ethertalk/aarpd.c Mon Jul 1 17:44:18 1991 *************** *** 16,27 **** #include #ifdef PHASE2 #include #include #include #endif PHASE2 #include #include ! #include #include #include "../uab/ethertalk.h" /* iso: level 1 */ #include "../uab/if_desc.h" --- 16,31 ---- #include #ifdef PHASE2 #include + #ifndef ultrix #include + #endif ultrix #include #endif PHASE2 #include + #include #include ! #include ! #include #include #include "../uab/ethertalk.h" /* iso: level 1 */ #include "../uab/if_desc.h" *************** *** 48,53 **** --- 52,63 ---- extern short lap_proto; /* our LAP mechanism */ + #ifdef ultrix + extern int svc_fds; + #else ultrix + extern fd_set svc_fdset; + #endif ultrix + byte pzone[INTZONESIZE+1]; /* zone (pascal string) */ char intrfc[INTFSIZE]; /* interface description */ u_char null_ether[6]; /* null ethernet address */ *************** *** 61,66 **** --- 71,77 ---- #ifdef PHASE2 struct ifreq ifreq; + u_char e_broad[6] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff}; #endif PHASE2 main(argc, argv) *************** *** 98,106 **** 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 */ --- 109,117 ---- 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 = htons(0xff00); /* the startup range */ ! net_range_start = htons(0); /* the total range */ ! net_range_end = htons(0xfffe); #endif PHASE2 baddr.node = bridge_node; /* set bridge addr hint */ *************** *** 150,159 **** --- 161,178 ---- etalkdbupdate(NULL); /* rewrite gleaned information */ bzero(null_ether, sizeof(null_ether)); + #ifdef PHASE2 + strncpy(ifreq.ifr_name, interface, sizeof(ifreq.ifr_name)); + if (pi_addmulti(-1, e_broad, (caddr_t)&ifreq) < 0) { + fprintf(stderr, "Can't add multicast address!\n"); + exit(1); + } + #endif PHASE2 /* set up aarpd RPC services */ (void)pmap_unset(AARPDPROG, AARPDVERS); + (void)svc_unregister(AARPDPROG, AARPDVERS); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { *************** *** 218,230 **** 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 --- 237,249 ---- ea = etalk_mynode(&id); this_node = nis_node = ea->node; #ifdef PHASE2 ! this_net = nis_net = htons((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, (ntohs(this_net) >> 8) & 0xff, ntohs(this_net) & 0xff); #else PHASE2 printf("acquired node number %d\n", this_node); #endif PHASE2 *************** *** 269,275 **** 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); --- 288,294 ---- 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", ntohl(*node)); #endif PHASE2 ea = etalk_resolve(&id, *node); return((ea) ? ea : null_ether); *************** *** 285,291 **** int *i; struct svc_req *rqstp; { ! logit(2, "request for bridge address: %d.%d", baddr.net, baddr.node); return((u_char *) &baddr); } --- 304,310 ---- int *i; struct svc_req *rqstp; { ! logit(2, "request for bridge address: %d.%d", ntohs(baddr.net), baddr.node); return((u_char *) &baddr); } *************** *** 329,342 **** 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; --- 348,361 ---- static struct ethertalkaddr eaddr; short new_net, new_net_start, new_net_end; ! new_net_start = ntohs((*range >> 16) & 0xffff); /* host byte order */ ! new_net_end = ntohs((*range & 0xffff)); /* host byte order */ ! new_net = new_net_start; /* host byte order */ 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] = (new_net >> 8) & 0xff; ! eaddr.dummy[2] = (new_net & 0xff); eaddr.node = this_node; /* probe a few times for the new address */ totalattempts = 0; *************** *** 358,365 **** 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; } } --- 377,384 ---- logit(5, "OOPS: no spare nodes available on net!!"); return(NULL); } ! eaddr.dummy[1] = (new_net >> 8) & 0xff; ! eaddr.dummy[2] = (new_net & 0xff); totalattempts = 0; } } *************** *** 372,380 **** 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); --- 391,399 ---- return(NULL); } logit(5, "Adopting %d/%d.%d", eaddr.node, eaddr.dummy[1], eaddr.dummy[2]); ! net_range_start = htons(new_net_start); ! net_range_end = htons(new_net_end); ! this_net = nis_net = htons(new_net); this_node = nis_node = eaddr.node; etalkdbupdate(NULL); return((u_char *) range); *************** *** 391,398 **** --- 410,422 ---- { int i, svc_listener(); + #ifdef ultrix + for(i = 0 ; i < 32 ; i++) + if (svc_fds & (1< + #include + #endif ultrix + + #ifdef pyr + #define ALT_RPC + #endif pyr + extern u_char *aarp_resolve_clnt(); extern u_short this_net, bridge_net, nis_net, async_net; *************** *** 26,38 **** CLIENT *cl; u_char *ether; struct ethertalkaddr node; ! #ifdef pyr int sock; struct timeval tv; struct sockaddr_in sin; ! #endif pyr ! #ifdef pyr sin.sin_family = AF_INET; sin.sin_port = 0; bzero(sin.sin_zero, sizeof(sin.sin_zero)); --- 36,48 ---- CLIENT *cl; u_char *ether; struct ethertalkaddr node; ! #ifdef ALT_RPC int sock; struct timeval tv; struct sockaddr_in sin; ! #endif ALT_RPC ! #ifdef ALT_RPC sin.sin_family = AF_INET; sin.sin_port = 0; bzero(sin.sin_zero, sizeof(sin.sin_zero)); *************** *** 41,51 **** tv.tv_sec = 5; tv.tv_usec = 0; cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); ! #else pyr cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); ! #endif pyr if (cl == NULL) { ! clnt_pcreateerror("localhost"); exit(1); } --- 51,61 ---- tv.tv_sec = 5; tv.tv_usec = 0; cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); ! #else ALT_RPC cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); ! #endif ALT_RPC if (cl == NULL) { ! clnt_pcreateerror("localhost/clnt_create"); exit(1); } *************** *** 53,60 **** #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; --- 63,70 ---- #ifdef PHASE2 if (argc > 2) { node.dummy[0] = 0; ! node.dummy[1] = (atoi(argv[2]) >> 8) & 0xff; ! node.dummy[2] = (atoi(argv[2]) & 0xff); } #else PHASE2 node.dummy[0] = node.dummy[1] = node.dummy[2] = 0; *************** *** 72,77 **** openetalkdb(NULL); printf("zone %s this %d.%d gw %d.%d nis %d.%d intf %s\n", ! this_zone, this_net, this_node, bridge_net, ! bridge_node, nis_net, nis_node, interface); } --- 82,87 ---- openetalkdb(NULL); printf("zone %s this %d.%d gw %d.%d nis %d.%d intf %s\n", ! this_zone, ntohs(this_net), this_node, ntohs(bridge_net), ! bridge_node, ntohs(nis_net), nis_node, interface); } *** support/ethertalk/abelap.c.orig Wed May 29 22:39:44 1991 --- support/ethertalk/abelap.c Mon Jul 1 16:25:52 1991 *************** *** 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 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1991/07/01 06:25:41 $ ! * $Header: /mac/src/cap60/support/ethertalk/RCS/abelap.c,v 2.4 1991/07/01 06:25:41 djh Rel djh $ ! * $Revision: 2.4 $ */ /* *************** *** 74,79 **** --- 74,86 ---- #include "../uab/aarp_defs.h" #include "aarpd.h" + #ifdef ultrix + #define ALT_RPC + #endif ultrix + #ifdef pyr + #define ALT_RPC + #endif pyr + /* RPC clients */ extern u_char *aarp_resolve_clnt(); *************** *** 243,252 **** { int i; static int here_before = 0; ! #ifdef pyr struct sockaddr_in sin; int sock; ! #endif pyr for (i=0; i < ddpMaxSkt+1; i++) { skt2fd[i] = -1; /* mark all these as unused */ --- 250,259 ---- { int i; static int here_before = 0; ! #ifdef ALT_RPC struct sockaddr_in sin; int sock; ! #endif ALT_RPC for (i=0; i < ddpMaxSkt+1; i++) { skt2fd[i] = -1; /* mark all these as unused */ *************** *** 278,290 **** if (disp) { printf("abInit: [ddp: %3d.%02d, %d]", ! ntohs(this_net)>>8, htons(this_net)&0xff, this_node); if (this_net != nis_net || this_node != nis_node) printf(", [NBP (atis) Server: %3d.%02d, %d]", ! ntohs(nis_net)>>8, htons(nis_net)&0xff, nis_node); if (bridge_node) printf(", [GW: %3d.%02d, %d]", ! ntohs(this_net)>>8, htons(this_net)&0xff, bridge_node); printf(" starting\n"); } --- 285,297 ---- if (disp) { printf("abInit: [ddp: %3d.%02d, %d]", ! ntohs(this_net) >> 8, ntohs(this_net) & 0xff, this_node); if (this_net != nis_net || this_node != nis_node) printf(", [NBP (atis) Server: %3d.%02d, %d]", ! ntohs(nis_net) >> 8, ntohs(nis_net) & 0xff, nis_node); if (bridge_node) printf(", [GW: %3d.%02d, %d]", ! ntohs(this_net) >> 8, ntohs(this_net) & 0xff, bridge_node); printf(" starting\n"); } *************** *** 291,301 **** DDPInit(); if (lap_proto == LAP_ETALK) { ! #ifdef pyr struct timeval tv; ! #endif pyr aih.ai_aarptab = (caddr_t)aarptab_init(); ! #ifdef pyr sin.sin_family = AF_INET; sin.sin_port = 0; bzero(sin.sin_zero, sizeof(sin.sin_zero)); --- 298,308 ---- DDPInit(); if (lap_proto == LAP_ETALK) { ! #ifdef ALT_RPC struct timeval tv; ! #endif ALT_RPC aih.ai_aarptab = (caddr_t)aarptab_init(); ! #ifdef ALT_RPC sin.sin_family = AF_INET; sin.sin_port = 0; bzero(sin.sin_zero, sizeof(sin.sin_zero)); *************** *** 304,312 **** tv.tv_sec = 5; tv.tv_usec = 0; cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); ! #else pyr cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); ! #endif pyr if (cl == NULL) { clnt_pcreateerror("localhost"); exit(1); --- 311,319 ---- tv.tv_sec = 5; tv.tv_usec = 0; cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); ! #else ALT_RPC cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); ! #endif ALT_RPC if (cl == NULL) { clnt_pcreateerror("localhost"); exit(1); *************** *** 743,750 **** 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 { --- 750,758 ---- eaddr = NULL; #ifdef PHASE2 if ((ddp->dstNet == 0 && ddp->dstNode == 0xff) /* local broadcast */ ! || (ntohs(ddp->dstNet) >= ntohs(net_range_start) ! && ntohs(ddp->dstNet) <= ntohs(net_range_end)) ! || (ntohs(ddp->dstNet) >= 0xff00 && ntohs(ddp->dstNet) <= 0xfffe)) { destnode = ddp->dstNode; destnet = ddp->dstNet; } else { *************** *** 775,782 **** 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 --- 783,790 ---- else { #ifdef PHASE2 etaddr.dummy[0] = 0; ! etaddr.dummy[1] = (ntohs(destnet) >> 8) & 0xff; ! etaddr.dummy[2] = (ntohs(destnet) & 0xff); #else PHASE2 etaddr.dummy[0] = etaddr.dummy[1] = etaddr.dummy[2] = 0; #endif PHASE2 *************** *** 892,900 **** 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"); --- 900,908 ---- long range; if (lap_proto == LAP_ETALK) { ! range = range_start & 0xffff; range <<= 16; ! range |= range_end & 0xffff; baddr = (AddrBlock *) range_set_clnt(&range, cl); if (baddr == NULL) clnt_perror(cl, "localhost"); *** support/ethertalk/ethertalk.c.orig Wed May 29 22:47:09 1991 --- support/ethertalk/ethertalk.c Mon Jul 1 16:48:31 1991 *************** *** 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 --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/07/01 06:48:16 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/ethertalk.c,v 2.4 1991/07/01 06:48:16 djh Rel djh $"; ! static char revision[] = "$Revision: 2.4 $"; /* * ethertalk.c - ethertalk interface *************** *** 200,207 **** #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 --- 200,207 ---- #ifdef PHASE2 pa.dummy[0] = 0; /* always zero */ ! pa.dummy[1] = (ntohs(this_net) >> 8) & 0xff; ! pa.dummy[2] = (ntohs(this_net) & 0xff); #else PHASE2 pa.dummy[0] = pa.dummy[1] = pa.dummy[2] = 0; #endif PHASE2 *************** *** 288,294 **** 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) { --- 288,294 ---- bcopy(&node, &tpa, ETPL); #else PHASE2 tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0; ! tpa.node = ntohl(node); #endif PHASE2 if (aarp_resolve(eh->eh_ah, &tpa, tpa.node == 0xff, &eaddr) <= 0) { *************** *** 359,366 **** #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 */ --- 359,366 ---- #ifdef PHASE2 node.n_id[0] = 0; ! node.n_id[1] = (ntohs(ddpnet) >> 8) & 0xff; ! node.n_id[2] = (ntohs(ddpnet) & 0xff); node.n_id[3] = ddpnode; #else PHASE2 node.n_id[0] = ddpnode; /* make node */ *** support/ethertalk/rtmptest.c.orig Wed May 29 22:51:28 1991 --- support/ethertalk/rtmptest.c Mon Jul 1 16:27:12 1991 *************** *** 6,17 **** */ #include #include #include #include - #include #include "aarpd.h" extern u_char *rtmp_getbaddr_clnt(); extern u_char *rtmp_setbaddr_clnt(); --- 6,26 ---- */ #include + #include #include #include #include #include "aarpd.h" + #ifdef ultrix + #define ALT_RPC + #include + #include + #endif ultrix + #ifdef pyr + #define ALT_RPC + #endif pyr + extern u_char *rtmp_getbaddr_clnt(); extern u_char *rtmp_setbaddr_clnt(); *************** *** 26,38 **** CLIENT *cl; u_char *addr; AddrBlock baddr; ! #ifdef pyr int sock; struct timeval tv; struct sockaddr_in sin; ! #endif pyr ! #ifdef pyr sin.sin_family = AF_INET; sin.sin_port = 0; bzero(sin.sin_zero, sizeof(sin.sin_zero)); --- 35,47 ---- CLIENT *cl; u_char *addr; AddrBlock baddr; ! #ifdef ALT_RPC int sock; struct timeval tv; struct sockaddr_in sin; ! #endif ALT_RPC ! #ifdef ALT_RPC sin.sin_family = AF_INET; sin.sin_port = 0; bzero(sin.sin_zero, sizeof(sin.sin_zero)); *************** *** 41,49 **** tv.tv_sec = 5; tv.tv_usec = 0; cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); ! #else pyr cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); ! #endif pyr if (cl == NULL) { clnt_pcreateerror("localhost"); exit(1); --- 50,58 ---- tv.tv_sec = 5; tv.tv_usec = 0; cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); ! #else ALT_RPC cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); ! #endif ALT_RPC if (cl == NULL) { clnt_pcreateerror("localhost"); exit(1); *************** *** 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"); --- 59,66 ---- } if (argc == 3) { ! baddr.net = htons(atoi(argv[1])); ! baddr.node = atoi(argv[2]); addr = rtmp_setbaddr_clnt(&baddr, cl); if (addr == NULL) { clnt_perror(cl, "localhost"); *************** *** 69,74 **** openetalkdb(NULL); printf("zone %s this %d.%d gw %d.%d nis %d.%d intf %s\n", ! this_zone, this_net, this_node, bridge_net, ! bridge_node, nis_net, nis_node, interface); } --- 78,83 ---- openetalkdb(NULL); printf("zone %s this %d.%d gw %d.%d nis %d.%d intf %s\n", ! this_zone, ntohs(this_net), this_node, ntohs(bridge_net), ! bridge_node, ntohs(nis_net), nis_node, interface); } *** support/ethertalk/rangetest.c.orig Mon Jul 1 16:28:12 1991 --- support/ethertalk/rangetest.c Mon Jul 1 16:31:32 1991 *************** *** 0 **** --- 1,85 ---- + /* + * simple RPC net range test + * + * Created: David Hornsby, Melbourne University + * + */ + + #include + #include + #include + #include + #include + #include "aarpd.h" + + #ifdef ultrix + #define ALT_RPC + #include + #include + #endif ultrix + #ifdef pyr + #define ALT_RPC + #endif pyr + + extern u_char *rtmp_getbaddr_clnt(); + extern u_char *rtmp_setbaddr_clnt(); + + extern u_short this_net, bridge_net, nis_net, async_net; + extern u_char this_node, bridge_node, nis_node; + extern char this_zone[34], async_zone[34], interface[50]; + + extern u_short net_range_start, net_range_end; + + main(argc, argv) + int argc; + char **argv; + { + CLIENT *cl; + u_char *addr; + u_short r_start, r_end; + unsigned long range; + #ifdef ALT_RPC + int sock; + struct timeval tv; + struct sockaddr_in sin; + #endif ALT_RPC + + #ifdef ALT_RPC + sin.sin_family = AF_INET; + sin.sin_port = 0; + bzero(sin.sin_zero, sizeof(sin.sin_zero)); + sin.sin_addr.s_addr = htonl(0x7f000001); + sock = RPC_ANYSOCK; + tv.tv_sec = 5; + tv.tv_usec = 0; + cl = clntudp_create(&sin, AARPDPROG, AARPDVERS, tv, &sock); + #else ALT_RPC + cl = clnt_create("localhost", AARPDPROG, AARPDVERS, "udp"); + #endif ALT_RPC + if (cl == NULL) { + clnt_pcreateerror("localhost"); + exit(1); + } + + if (argc == 3) { + r_start = htons(atoi(argv[1])); + r_end = htons(atoi(argv[2])); + range = r_start & 0xffff; + range <<= 16; + range |= r_end & 0xffff; + addr = (u_char *) range_set_clnt(&range, cl); + if (addr == NULL) { + clnt_perror(cl, "localhost"); + exit(1); + } + printf("set net range: %d - %d\n", ntohs(r_start), ntohs(r_end)); + } + + openetalkdb(NULL); + + printf("zone %s this %d.%d gw %d.%d nis %d.%d intf %s\n", + this_zone, ntohs(this_net), this_node, ntohs(bridge_net), + bridge_node, ntohs(nis_net), nis_node, interface); + printf("range start %d, range end %d\n", ntohs(net_range_start), + ntohs(net_range_end)); + } *** support/ethertalk/spfiltp.c.orig Mon Jul 1 16:38:27 1991 --- support/ethertalk/spfiltp.c Mon Jul 1 19:04:03 1991 *************** *** 0 **** --- 1,593 ---- + static char rcsid[] = "$Author: djh $ $Date: 1991/07/01 09:03:32 $"; + static char rcsident[] = "$Header: /local/mulga/mac/src/cap60/support/ethertalk/RCS/spfiltp.c,v 2.3 1991/07/01 09:03:32 djh Rel djh $"; + static char revision[] = "$Revision: 2.3 $"; + + /* + * spfiltp.c - Simple "protocol" level interface to Ultrix packetfilter + * + * Provides ability to read/write packets at ethernet level + * + * + * Copyright (c) 1988 by The Trustees of Columbia University + * in the City of New York. + * + * Permission is granted to any individual or institution to use, + * copy, or redistribute this software so long as it is not sold for + * profit, provided that this notice and the original copyright + * notices are retained. Columbia University nor the author make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * Edit History: + * + * April 1991 Jeffrey Mogul @ DECWRL (created from senetp.c) + * June 1991 David Hornsby, add Phase 2 support + * + */ + + static char columbia_copyright[] = "Copyright (c) 1988 by The Trustees of \ + Columbia University in the City of New York"; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifdef pyr + #include + extern int errno; + #else pyr + #include + #endif pyr + #include + #ifdef pyr + #include + #else pyr + #include + #endif pyr + #include + #include + + #include + #include "../uab/proto_intf.h" + + typedef struct ephandle { /* ethernet protocol driver handle */ + int inuse; /* true if inuse */ + int fd; /* file descriptor of socket */ + struct ifreq ifr; + int protocol; /* ethernet protocol */ + int socket; /* ddp socket */ + } EPHANDLE; + + private inited = FALSE; + + private EPHANDLE ephlist[MAXOPENPROT]; + + extern char interface[50]; + + /* + * setup for particular device devno + * all pi_open's will go this device + */ + export + pi_setup() + { + int i; + + if (!inited) { + for (i = 0 ; i < MAXOPENPROT; i++) + ephlist[i].inuse = FALSE; + (void)init_fdlistening(); + inited = TRUE; /* don't forget now */ + } + return(TRUE); + } + + /* + * Open up a protocol handle: + * user level data: + * file descriptor + * protocol + * + * returns -1 and ephandle == NULL if memory allocation problems + * returns -1 for other errors + * return edx > 0 for okay + */ + export int + pi_open(protocol, socket, dev, devno) + int protocol; + int socket; + char *dev; + int devno; + { + struct ephandle *eph; + char devnamebuf[100]; /* room for device name */ + int s; + int i; + + for (i = 0; i < MAXOPENPROT; i++) { + if (!ephlist[i].inuse) + break; + } + if (i == MAXOPENPROT) + return(0); /* nothing */ + eph = &ephlist[i]; /* find handle */ + + sprintf(devnamebuf, "%s%d",dev,devno); + strncpy(eph->ifr.ifr_name, devnamebuf, sizeof eph->ifr.ifr_name); + + if ((s = init_nit(1024, protocol, socket, &eph->ifr)) < 0) { + return(-1); + } + + eph->inuse = TRUE; + eph->fd = s; + eph->protocol = protocol; + eph->socket = socket; + return(i+1); /* skip zero */ + } + + /* returns TRUE if machine will see own broadcasts */ + export int + pi_delivers_self_broadcasts() + { + return(TRUE); + } + + export int + pi_close(edx) + int edx; + { + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + fdunlisten(ephlist[edx-1].fd); /* toss listener */ + close(ephlist[edx-1].fd); + ephlist[edx-1].inuse = 0; + return(0); + } + + /* + * Initialize nit on a particular protocol type + * + * Runs in promiscous mode for now. + * + * Return: socket if no error, < 0 o.w. + */ + private int + init_nit(chunksize, protocol, socket, ifr) + u_long chunksize; + u_short protocol; + int socket; + struct ifreq *ifr; + { + u_long if_flags; + int s; + char device[64]; + + if ((s = pfopen(interface, O_RDWR)) < 0) { + sprintf(device, "open: %s", interface); + perror(device); + return(-1); + } + + if (setup_pf(s, protocol, socket) < 0) + return(-1); + + #define NOBUF + #ifndef NOBUF + setup_buf(s, chunksize); + #endif NOBUF + + /* flush read queue */ + ioctl(s, EIOCFLUSH, 0); + return(s); + } + + #ifdef PHASE2 + /* + * add a multicast address to the interface + */ + int + pi_addmulti(s, multi, ifr) + int s; + char *multi; + struct ifreq *ifr; + { + int sock; + + if (s < 0) { + if ((s = pfopen(interface, O_RDWR)) < 0) { + perror("pfopen()"); + return(-1); + } + /* flush read queue */ + ioctl(s, EIOCFLUSH, 0); + } + + /* + * get the real interface name (interface may be generic "pf0") + * + */ + if (ioctl(s, EIOCIFNAME, ifr) < 0) { + perror("EIOCIFNAME"); + return(-1); + } + + ifr->ifr_addr.sa_family = AF_UNSPEC; + bcopy(multi, ifr->ifr_addr.sa_data, EHRD); + + /* + * open a socket, temporarily, to use for SIOC* ioctls + * + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket()"); + return(-1); + } + + if (ioctl(sock, SIOCADDMULTI, (struct ifreq *)ifr) < 0) { + perror("SIOCADDMULTI"); + close(sock); + return(-1); + } + + close(sock); + return(s); + } + #endif PHASE2 + + #ifndef NOBUF + /* + * setup buffering (not wanted) + * + */ + setup_buf(s, chunksize) + int s; + u_long chunksize; + { + struct timeval timeout; + + /* 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) { + perror("ioctl: timeout"); + return(-1); + } + + si.ic_cmd = NIOCSCHUNK; + + si.ic_len = sizeof chunksize; + si.ic_dp = (char *)&chunksize; + if (ioctl(s, I_STR, (char *)&si)) { + perror("ioctl: chunk size"); + return(-1); + } + } + #endif NOBUF + + /* + * establish protocol filter + * + */ + private int + setup_pf(s, prot, sock) + int s; + u_short prot; + int sock; + { + u_short offset; + unsigned queuelen; + struct ether_header eh; + struct enfilter pf; + register u_short *fwp = pf.enf_Filter; + extern int errno; + + + queuelen = 8; + if (ioctl(s, EIOCSETW, &queuelen) < 0) { + perror("ioctl: set recv queue length"); + return(-1); + } + + pf.enf_Priority = 128; + + #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.enf_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.enf_FilterLen += 7; + #else PHASE2 + /* short form */ + *fwp++ = ENF_PUSHWORD + offset + 2; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0xff00); /* now have lap type in LH */ + *fwp++ = ENF_PUSHWORD + offset + 3; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0x00ff); /* now have dest in RH */ + *fwp++ = ENF_NOPUSH | ENF_OR; /* now have lap,,dest */ + *fwp++ = ENF_PUSHLIT | ENF_COR; + *fwp++ = htons((1 << 8) | (sock & 0xff)); + /* long form */ + *fwp++ = ENF_PUSHWORD + offset + 2; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0xff00); /* now have lap type in LH */ + *fwp++ = ENF_PUSHWORD + offset + 7; + *fwp++ = ENF_PUSHLIT | ENF_AND; + *fwp++ = htons(0x00ff); /* now have dest in RH */ + *fwp++ = ENF_NOPUSH | ENF_OR; /* now have lap,,dest */ + *fwp++ = ENF_PUSHLIT | ENF_COR; + *fwp++ = htons((2 << 8) | (sock & 0xff)); + /* if neither, fail it */ + *fwp++ = ENF_PUSHLIT ; + *fwp++ = 0; + pf.enf_FilterLen += 20; + #endif PHASE2 + } + + if (ioctl(s, EIOCSETF, &pf) < 0) { + perror("ioctl: protocol filter"); + return(-1); + } + return(0); + } + + export int + pi_get_ethernet_address(edx,ea) + int edx; + u_char *ea; + { + struct sockaddr *sa; + struct endevp endev; + struct ephandle *eph; + + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + + eph = &ephlist[edx-1]; + if (ioctl(eph->fd, EIOCDEVP, &endev) < 0) { + perror("Ioctl: SIOCGIFADDR"); + return(-1); + } + bcopy(endev.end_addr, ea, 6); + return(0); + } + + export + pi_listener(edx, listener, arg) + int edx; + int (*listener)(); + caddr_t arg; + { + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + + fdlistener(ephlist[edx-1].fd, listener, arg, edx); + } + + export + pi_listener_2(edx, listener, arg1, arg2) + int edx; + int (*listener)(); + caddr_t arg1; + int arg2; + { + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + + fdlistener(ephlist[edx-1].fd, listener, arg1, arg2); + } + + /* + * cheat - iov[0] == struct etherheader + * + */ + export int + pi_readv(edx, iov, iovlen) + int edx; + struct iovec *iov; + int iovlen; + { + struct ephandle *eph ; + int cc; + + if (edx < 1 || edx > MAXOPENPROT) + return(-1); + eph = &ephlist[edx-1]; + if (!eph->inuse) + return(-1); + if ((cc = readv(eph->fd, iov, iovlen)) < 0) { + perror("abread"); + return(cc); + } + return(cc); + } + + export int + pi_read(edx, buf, bufsiz) + int edx; + 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) + int fd; + caddr_t buf; + 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 + pi_write(edx, buf, buflen, eaddr) + int edx; + caddr_t buf; + int buflen; + char *eaddr; + { + struct ephandle *eph; + struct ether_header eh; + struct sockaddr sa; + struct iovec iov[2]; + #ifdef PHASE2 + char *q; + #endif PHASE2 + + iov[0].iov_base = (caddr_t)&eh; + iov[0].iov_len = 14; + iov[1].iov_base = (caddr_t)buf; + iov[1].iov_len = buflen; + + if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL) + return(-1); + + eph = &ephlist[edx-1]; + if (!eph->inuse) + return(-1); + + bcopy(eaddr, eh.ether_dhost, 6); + #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++ = (eph->protocol >> 8) & 0xff; + *q++ = (eph->protocol & 0xff); + #else PHASE2 + eh.ether_type = htons(eph->protocol); + #endif PHASE2 + + if (writev(eph->fd, iov, 2) < 0) { + return(-1); + } + return(buflen); + } + + private char ebuf[2000]; /* big enough */ + + export int + pi_writev(edx, iov, iovlen, eaddr) + int edx; + struct iovec *iov; + int iovlen; + unsigned char eaddr[6]; + { + int i; + char *p; + int len; + + if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL) + return(-1); + if (!ephlist[edx-1].inuse) + return(-1); + + #ifdef PHASE2 + 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 */ + len += iov[i].iov_len; /* advance */ + } + return(pi_write(edx, ebuf, len, eaddr)); + } *** support/uab/spfiltp.c.orig Mon Jul 1 16:40:12 1991 --- support/uab/spfiltp.c Mon Jul 1 16:42:34 1991 *************** *** 0 **** --- 1,390 ---- + static char rcsid[] = "$Author: djh $ $Date: 1991/07/01 06:42:11 $"; + static char rcsident[] = "$Header: /mac/src/cap60/support/uab/RCS/spfiltp.c,v 2.1 1991/07/01 06:42:11 djh Rel djh $"; + static char revision[] = "$Revision: 2.1 $"; + + /* + * spfiltp.c - Simple "protocol" level interface to Ultrix packetfilter + * + * Provides ability to read/write packets at ethernet level + * + * + * Copyright (c) 1988 by The Trustees of Columbia University + * in the City of New York. + * + * Permission is granted to any individual or institution to use, + * copy, or redistribute this software so long as it is not sold for + * profit, provided that this notice and the original copyright + * notices are retained. Columbia University nor the author make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * Edit History: + * + * April 1991 Jeffrey Mogul @ DECWRL (created from senetp.c) + * + */ + + static char columbia_copyright[] = "Copyright (c) 1988 by The Trustees of \ + Columbia University in the City of New York"; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + /* #include */ + #include + #include + #include + #include + + #include + #include "proto_intf.h" + #include + + typedef struct ephandle { /* ethernet protocol driver handle */ + int inuse; /* true if inuse */ + int socket; /* file descriptor of socket */ + struct ifreq ifr; + int protocol; /* ethernet protocol */ + } EPHANDLE; + + private inited = FALSE; + + private EPHANDLE ephlist[MAXOPENPROT]; + + /* + * setup for particular device devno + * all pi_open's will go this device + */ + export + pi_setup() + { + int i; + + if (!inited) { + for (i = 0 ; i < MAXOPENPROT; i++) + ephlist[i].inuse = FALSE; + (void)init_fdlistening(); + inited = TRUE; /* don't forget now */ + } + return(TRUE); + } + + /* + * Open up a protocol handle: + * user level data: + * file descriptor + * protocol + * + * returns -1 and ephandle == NULL if memory allocation problems + * returns -1 for other errors + * return edx > 0 for okay + */ + export int + pi_open(protocol, dev, devno) + int protocol; + char *dev; + int devno; + { + struct ephandle *eph; + char devnamebuf[100]; /* room for device name */ + int s; + int i; + + for (i = 0; i < MAXOPENPROT; i++) { + if (!ephlist[i].inuse) + break; + } + if (i == MAXOPENPROT) + return(0); /* nothing */ + eph = &ephlist[i]; /* find handle */ + + sprintf(devnamebuf, "%s%d",dev,devno); + strncpy(eph->ifr.ifr_name, devnamebuf, sizeof eph->ifr.ifr_name); + eph->ifr.ifr_name[sizeof eph->ifr.ifr_name - 1] = ' '; + + if ((s = init_nit(1024, protocol, &eph->ifr)) < 0) { + return(-1); + } + + eph->inuse = TRUE; + eph->socket = s; + eph->protocol = protocol; + return(i+1); /* skip zero */ + } + + /* returns TRUE if machine will see own broadcasts */ + export int + pi_delivers_self_broadcasts() + { + return(TRUE); + } + + export int + pi_close(edx) + int edx; + { + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + fdunlisten(ephlist[edx-1].socket); /* toss listener */ + close(ephlist[edx-1].socket); + ephlist[edx-1].inuse = 0; + return(0); + } + + /* + * Initialize nit on a particular protocol type + * + * Runs in promiscous mode for now. + * + * Return: socket if no error, < 0 o.w. + */ + private int + init_nit(chunksize, protocol, ifr) + u_long chunksize; + u_short protocol; + struct ifreq *ifr; + { + u_long if_flags; + int s; + char device[64]; + + if ((s = pfopen(ifr->ifr_name, O_RDWR)) < 0) { + sprintf(device, "open: %s", ifr->ifr_name); + perror(device); + return(-1); + } + + if (setup_pf(s, protocol) < 0) + return(-1); + #define NOBUF + #ifndef NOBUF + setup_buf(s, chunksize); + #endif + + /* flush read queue */ + ioctl(s, EIOCFLUSH, 0); + return(s); + } + + #ifndef NOBUF + /* + * setup buffering (not wanted) + * + */ + setup_buf(s, chunksize) + int s; + u_long chunksize; + { + struct timeval timeout; + + /* 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) { + perror("ioctl: timeout"); + return(-1); + } + + si.ic_cmd = NIOCSCHUNK; + + si.ic_len = sizeof chunksize; + si.ic_dp = (char *)&chunksize; + if (ioctl(s, I_STR, (char *)&si)) { + perror("ioctl: chunk size"); + return(-1); + } + } + #endif + + /* + * establish protocol filter + * + */ + private int + setup_pf(s, prot) + int s; + u_short prot; + { + u_short offset; + unsigned queuelen; + struct ether_header eh; + struct enfilter pf; + register u_short *fwp = pf.enf_Filter; + extern int errno; + + queuelen = 8; + if (ioctl(s, EIOCSETW, &queuelen) < 0) { + perror("ioctl: set recv queue length"); + return(-1); + } + + pf.enf_Priority = 128; + + #define s_offset(structp, element) (&(((structp)0)->element)) + offset = ((int)s_offset(struct ether_header *, ether_type))/sizeof(u_short); + #ifdef undef + *fwp++ = ENF_PUSHLIT ; + *fwp++ = 1; + pf.enf_FilterLen = 2; + #endif + *fwp++ = ENF_PUSHWORD + offset; + *fwp++ = ENF_PUSHLIT | ENF_EQ; + *fwp++ = htons(prot); + pf.enf_FilterLen = 3; + + if (ioctl(s, EIOCSETF, &pf) < 0) { + perror("ioctl: protocol filter"); + return(-1); + } + return(0); + } + + export int + pi_get_ethernet_address(edx,ea) + int edx; + u_char *ea; + { + struct sockaddr *sa; + struct endevp endev; + struct ephandle *eph; + + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + + eph = &ephlist[edx-1]; + if (ioctl(eph->socket, EIOCDEVP, &endev) < 0) { + perror("Ioctl: SIOCGIFADDR"); + return(-1); + } + bcopy(endev.end_addr, ea, 6); + return(0); + } + + export + pi_listener(edx, listener, arg) + int edx; + int (*listener)(); + caddr_t arg; + { + if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse) + return(-1); + + fdlistener(ephlist[edx-1].socket, listener, arg, edx); + } + + /* + * cheat - iov[0] == struct etherheader + * + */ + export int + pi_readv(edx, iov, iovlen) + int edx; + struct iovec *iov; + int iovlen; + { + struct ephandle *eph ; + int cc; + + if (edx < 1 || edx > MAXOPENPROT) + return(-1); + eph = &ephlist[edx-1]; + if (!eph->inuse) + return(-1); + if ((cc = readv(eph->socket, iov, iovlen)) < 0) { + perror("abread"); + return(cc); + } + return(cc); + } + + export int + pi_read(edx, buf, bufsiz) + int edx; + 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)); + } + + export int + pi_write(edx, buf, buflen, eaddr) + int edx; + caddr_t buf; + int buflen; + char *eaddr; + { + struct ephandle *eph; + struct ether_header eh; + struct sockaddr sa; + struct iovec iov[2]; + + iov[0].iov_base = (caddr_t)&eh; + iov[0].iov_len = 14; + iov[1].iov_base = (caddr_t)buf; + iov[1].iov_len = buflen; + + if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL) + return(-1); + + eph = &ephlist[edx-1]; + if (!eph->inuse) + return(-1); + + bcopy(eaddr, &eh.ether_dhost, 6); + eh.ether_type = htons(eph->protocol); + + if (writev(eph->socket, iov, 2) < 0) { + return(-1); + } + return(buflen); + } + + private char ebuf[2000]; /* big enough */ + + export int + pi_writev(edx, iov, iovlen, eaddr) + int edx; + struct iovec *iov; + int iovlen; + unsigned char eaddr[6]; + { + int i; + char *p; + int len; + + if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL) + return(-1); + if (!ephlist[edx-1].inuse) + return(-1); + + for (len = 0, p = ebuf, i = 0 ; i < iovlen ; i++) + 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 */ + len += iov[i].iov_len; /* advance */ + } + return(pi_write(edx, ebuf, len, eaddr)); + } *** support/ethertalk/snitp.c.orig Mon Jul 1 17:12:24 1991 --- support/ethertalk/snitp.c Mon Jul 1 19:04:00 1991 *************** *** 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 --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1991/07/01 09:03:32 $"; ! static char rcsident[] = "$Header: /local/mulga/mac/src/cap60/support/ethertalk/RCS/snitp.c,v 2.5 1991/07/01 09:03:32 djh Rel djh $"; ! static char revision[] = "$Revision: 2.5 $"; /* * snitp.c - Simple "protocol" level interface to Streams based NIT *************** *** 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 --- 66,71 ---- *************** *** 193,206 **** 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); --- 189,194 ---- *** support/ethertalk/Makefile.m4.orig Mon Jul 1 19:07:41 1991 --- support/ethertalk/Makefile.m4 Mon Jul 1 19:08:33 1991 *************** *** 25,30 **** --- 25,33 ---- rtmptest: rtmptest.o aarpd.h cc -o rtmptest rtmptest.o ${CAPLIB} + rangetest: rangetest.o aarpd.h + cc -o rangetest rangetest.o ${CAPLIB} + aarpd.o: aarpd.c aarpd.h abelap.o: abelap.c *** README.orig Mon Jul 1 16:16:05 1991 --- README Mon Jul 1 16:16:20 1991 *************** *** 3,9 **** (For use with AppleTalk/Ethernet bridge) o RELEASE NOTES ! o CAP Distribution 6.0, Patch Level 27, June 1991 Introduction ------------ --- 3,9 ---- (For use with AppleTalk/Ethernet bridge) o RELEASE NOTES ! o CAP Distribution 6.0, Patch Level 28, July 1991 Introduction ------------