Patch #: 8 Type: bug fix Priority: low Affects: sites running ARNS with Berkeley Packet Filter Reported: David Hornsby Summary: Handle multiple packets in single BPF read Archived: munnari.OZ.AU mac/cap.patches/arns.patch008 Application: 'cd arns; patch -p < arns.patch008' *** arns.h.orig Fri Dec 10 00:22:56 1993 --- arns.h Thu May 19 16:54:55 1994 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.9 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.10 $ * */ *************** *** 264,267 **** --- 264,279 ---- short perm; unsigned long mask; unsigned long addr; + }; + + /* + * Read Data structure + * + */ + + #define NUMRDS 32 + + struct RDS { + u_short dataLen; + u_char *dataPtr; }; *** arns.c.orig Tue Mar 8 12:49:03 1994 --- arns.c Thu May 19 16:54:52 1994 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.7 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.8 $ * */ *************** *** 63,69 **** --- 63,71 ---- extern u_char bridgeNode; /* adopted bridge node number */ extern char *thisZone; /* server zone name */ + extern struct RDS RDS[]; /* RDS for multiple packet reads*/ + main(argc, argv) int argc; char *argv[]; *************** *** 505,515 **** readdev(fd) int fd; { ! int cc; void ddp(), aarp(); if ((cc = read_eth(fd, buf, sizeof(buf))) < 0) { ! perror("readeth()"); return; } --- 507,518 ---- readdev(fd) int fd; { ! int cc, i; ! u_char *pkt; void ddp(), aarp(); if ((cc = read_eth(fd, buf, sizeof(buf))) < 0) { ! perror("read_eth()"); return; } *************** *** 516,557 **** if (cc == 0) return; ! if (phase == 1) { ! if (buf[12] == 0x80) { ! switch (buf[13]) { ! case 0xf3: ! if (debug & AARPDEBUG) ! fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! aarp(buf, cc); ! break; ! case 0x9b: if (thisNode == 0) return; /* not init'd yet */ if (debug & ETHDEBUG) fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! ddp(buf, cc); ! break; ! default: ! break; ! } ! } ! } else if (phase == 2) { ! if ((buf[12]*256+buf[13] < 1500) ! && (buf[14]==0xAA) && (buf[15]==0xAA) && (buf[16]==0x03)) { ! /* IEEE802.3 and SNAP and control = 0x03 */ ! if ((buf[17]==0x08) && (buf[18]==0x00) && (buf[19]==0x07) ! && (buf[20]==0x80) && (buf[21]==0x9B)) { ! if (thisNode == 0) ! return; /* not init'd yet */ ! if (debug & ETHDEBUG) ! fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! ddp(buf, cc); ! } else { ! if ((buf[17]==0x00) && (buf[18]==0x00) && (buf[19]==0x00) ! && (buf[20]==0x80) && (buf[21]==0xF3)) { ! if (debug & AARPDEBUG) ! fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! aarp(buf, cc); } } } --- 519,568 ---- if (cc == 0) return; ! for (i = 0; i < NUMRDS; i++) { ! if (RDS[i].dataLen == 0) ! break; ! ! pkt = RDS[i].dataPtr; ! cc = RDS[i].dataLen; ! ! if (phase == 1) { ! if (pkt[12] == 0x80) { ! switch (pkt[13]) { ! case 0xf3: ! if (debug & AARPDEBUG) ! fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! aarp(pkt, cc); ! break; ! case 0x9b: ! if (thisNode == 0) ! return; /* not init'd yet */ ! if (debug & ETHDEBUG) ! fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! ddp(pkt, cc); ! break; ! default: ! break; ! } ! } ! } else if (phase == 2) { ! if ((pkt[12]*256+pkt[13] < 1500) ! && (pkt[14]==0xAA) && (pkt[15]==0xAA) && (pkt[16]==0x03)) { ! /* IEEE802.3 and SNAP and control = 0x03 */ ! if ((pkt[17]==0x08) && (pkt[18]==0x00) && (pkt[19]==0x07) ! && (pkt[20]==0x80) && (pkt[21]==0x9B)) { if (thisNode == 0) return; /* not init'd yet */ if (debug & ETHDEBUG) fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! ddp(pkt, cc); ! } else { ! if ((pkt[17]==0x00) && (pkt[18]==0x00) && (pkt[19]==0x00) ! && (pkt[20]==0x80) && (pkt[21]==0xF3)) { ! if (debug & AARPDEBUG) ! fprintf(stderr, "DEV%d: read %d bytes\n", phase, cc); ! aarp(pkt, cc); ! } } } } *************** *** 569,579 **** readeth(fd) int fd; { ! int cc; void ddp(); if ((cc = read_eth(fd, buf, sizeof(buf))) < 0) { ! perror("readeth()"); return; } --- 580,590 ---- readeth(fd) int fd; { ! int cc, i; void ddp(); if ((cc = read_eth(fd, buf, sizeof(buf))) < 0) { ! perror("read_eth()"); return; } *************** *** 583,593 **** if (thisNode == 0) return; /* not init'd yet */ ! if (debug & ETHDEBUG) ! fprintf(stderr, "ETH%d: read %d bytes\n", phase, cc); - ddp(buf, cc); - return; } --- 594,605 ---- if (thisNode == 0) return; /* not init'd yet */ ! for (i = 0; i < NUMRDS; i++) { ! if (RDS[i].dataLen == 0) ! break; ! ddp(RDS[i].dataPtr, RDS[i].dataLen); ! } return; } *************** *** 600,610 **** readaarp(fd) int fd; { ! int cc; void aarp(); if ((cc = read_eth(fd, buf, sizeof(buf))) < 0) { ! perror("readeth()"); return; } --- 612,622 ---- readaarp(fd) int fd; { ! int cc, i; void aarp(); if ((cc = read_eth(fd, buf, sizeof(buf))) < 0) { ! perror("read_eth()"); return; } *************** *** 611,620 **** if (cc == 0) return; ! if (debug & AARPDEBUG) ! fprintf(stderr, "AARP: read %d bytes\n", cc); ! ! aarp(buf, cc); return; } --- 623,633 ---- if (cc == 0) return; ! for (i = 0; i < NUMRDS; i++) { ! if (RDS[i].dataLen == 0) ! break; ! aarp(RDS[i].dataPtr, RDS[i].dataLen); ! } return; } *** ddp.c.orig Tue Mar 8 10:55:05 1994 --- ddp.c Thu May 19 16:54:49 1994 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.7 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.8 $ * */ *************** *** 61,66 **** --- 61,69 ---- void rtmp(), nbp(), zip(), routeIP(); u_short srcNet, dstNet; int len; + + if (debug & ETHDEBUG) + fprintf(stderr, "ETH%d: read %d bytes\n", phase, pktLen); if (debug & PKTDEBUG) dumppacket(buf, pktLen); *** aarp.c.orig Tue Mar 8 11:01:34 1994 --- aarp.c Thu May 19 16:54:46 1994 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.2 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.3 $ * */ *************** *** 49,54 **** --- 49,57 ---- u_char dstNode, srcNode; u_short dstNet, srcNet, function; void aarpRespond(); + + if (debug & AARPDEBUG) + fprintf(stderr, "AARP: read %d bytes\n", len); if (debug & PKTDEBUG) dumppacket(buf, len); *** pf.c.orig Fri Dec 10 00:21:38 1993 --- pf.c Thu May 19 15:29:03 1994 *************** *** 25,31 **** * AIX Ethernet Device (AIXETH) * * $Author: djh $ ! * $Revision: 1.13 $ * */ --- 25,31 ---- * AIX Ethernet Device (AIXETH) * * $Author: djh $ ! * $Revision: 1.14 $ * */ *************** *** 67,72 **** --- 67,77 ---- #define BPFILT #endif __386BSD__ + /* + * include header files + * + */ + #include #include #include *************** *** 99,104 **** --- 104,110 ---- #ifdef BPFILT #include #include + #include #endif BPFILT #ifdef UPFILT *************** *** 213,220 **** #ifdef AIXETH #endif AIXETH ! #define READBUFSIZ 1600 /* * variables * --- 219,237 ---- #ifdef AIXETH #endif AIXETH ! /* ! * definitions ! * ! */ + #define READBUFSIZ 4096 + #define NUMRDS 32 + + struct RDS { + u_short dataLen; + u_char *dataPtr; + }; + /* * variables * *************** *** 229,242 **** long dlpibuf[MAXDLBUF]; #endif DLPIPF ! #if (defined(sgi) || defined(BPFILT)) ! char ibuf[READBUFSIZ]; ! #endif /* sgi || BPFILT */ struct ifreq ifr; extern int errno; extern int promisc; /* * Open and initialize packet filter * for a particular protocol type. --- 246,261 ---- long dlpibuf[MAXDLBUF]; #endif DLPIPF ! #ifdef BPFILT ! u_int pf_bufsize = READBUFSIZ; ! #endif BPFILT struct ifreq ifr; extern int errno; extern int promisc; + struct RDS RDS[NUMRDS]; + /* * Open and initialize packet filter * for a particular protocol type. *************** *** 448,454 **** #ifdef BPFILT { struct bpf_version vers; - u_int pf_bufsize = READBUFSIZ; /* check the version number */ if ((ioctl(s, BIOCVERSION, &vers)) < 0) { --- 467,472 ---- *************** *** 460,465 **** --- 478,484 ---- fprintf(stderr, "Incompatible BPF version\n"); return(-1); } + #ifdef __386BSD__ /* we have to read EXACTLY the buffer size */ if ((ioctl(s, BIOCSBLEN, &pf_bufsize)) < 0) { perror("BIOCSBLEN"); *************** *** 469,474 **** --- 488,504 ---- fprintf(stderr, "Can't set exact BPF buffer size\n"); return(-1); } + #else /* __386BSD__ */ + /* we have to read EXACTLY the buffer size */ + if ((ioctl(s, BIOCGBLEN, &pf_bufsize)) < 0) { + perror("BIOCGBLEN"); + return(-1); + } + if (pf_bufsize > READBUFSIZ) { + fprintf(stderr, "Large BPF buffers in use (%d bytes)\n", pf_bufsize); + return(-1); + } + #endif /* __386BSD__ */ } /* bind to interface */ if (ioctl(s, BIOCSETIF, (caddr_t)&ifr) < 0) { *************** *** 1234,1239 **** --- 1264,1270 ---- /* * read a packet + * Read Data Structure describes packet(s) received * */ *************** *** 1242,1279 **** int fd, len; u_char *buf; { #ifdef BPFILT ! int cc; struct bpf_hdr *bp; /* must read EXACTLY the buffer size */ ! if ((cc = read(fd, ibuf, sizeof(ibuf))) <= 0) return(cc); ! bp = (struct bpf_hdr *)ibuf; ! cc = bp->bh_caplen; ! if (cc > len) ! cc = len; ! ! bcopy(ibuf+bp->bh_hdrlen, (char *)buf, cc); ! ! return(cc); #endif BPFILT #ifdef sgi u_char *p; - int cc, off; struct snoopheader *sh; if (promisc) off = sizeof(struct snoopheader)+RAW_HDRPAD(sizeof(struct ether_header)); else off = RAW_HDRPAD(sizeof(struct ether_header)); ! if ((cc = read(fd, ibuf, sizeof(ibuf))) <= 0) return(cc); if ((cc = cc - off) <= 0) --- 1273,1329 ---- int fd, len; u_char *buf; { + int i, cc; #ifdef BPFILT ! u_char *p, *q; struct bpf_hdr *bp; + RDS[0].dataLen = 0; + /* must read EXACTLY the buffer size */ ! if ((cc = read(fd, buf, pf_bufsize)) <= 0) { ! #if defined(sun) && !defined(SOLARIS) ! if (errno == EINVAL ! && (long)(tell(fd)+pf_bufsize) < 0) { ! (void)lseek(fd, 0, 0); ! return(0); ! } ! #endif /* SunOS */ return(cc); + } ! /* ! * fill in the RDS ! * ! */ ! p = buf; ! q = buf+cc; ! for (i = 0; i < (NUMRDS-1) && p < q; i++) { ! bp = (struct bpf_hdr *)p; ! RDS[i].dataLen = bp->bh_caplen; ! RDS[i].dataPtr = p + bp->bh_hdrlen; ! p += BPF_WORDALIGN(bp->bh_hdrlen+bp->bh_caplen); ! } ! RDS[i].dataLen = 0; ! return(RDS[0].dataLen); #endif BPFILT #ifdef sgi + int off; u_char *p; struct snoopheader *sh; + RDS[0].dataLen = 0; + if (promisc) off = sizeof(struct snoopheader)+RAW_HDRPAD(sizeof(struct ether_header)); else off = RAW_HDRPAD(sizeof(struct ether_header)); ! if ((cc = read(fd, buf, sizeof(buf))) <= 0) return(cc); if ((cc = cc - off) <= 0) *************** *** 1282,1288 **** if (cc > len) cc = len; ! bcopy(ibuf+off, (char *)buf, cc); return(cc); #endif sgi --- 1332,1340 ---- if (cc > len) cc = len; ! RDS[0].dataLen = cc; ! RDS[0].dataPtr = buf+off; ! RDS[1].dataLen = 0; return(cc); #endif sgi *************** *** 1289,1300 **** #ifdef hpux struct fis fis; - int cc, off; off = (ethtyp == 1) ? 14 : 22; if ((cc = read(fd, buf+off, len-off)) <= 0) return(cc); fis.reqtype = FRAME_HEADER; if (ioctl(fd, NETSTAT, &fis) < 0) { perror("FRAME_HEADER"); --- 1341,1356 ---- #ifdef hpux + int off; struct fis fis; + RDS[0].dataLen = 0; + off = (ethtyp == 1) ? 14 : 22; + if ((cc = read(fd, buf+off, len-off)) <= 0) return(cc); + fis.reqtype = FRAME_HEADER; if (ioctl(fd, NETSTAT, &fis) < 0) { perror("FRAME_HEADER"); *************** *** 1302,1314 **** } if (fis.vtype != off) return(-1); bcopy(fis.value.s, (char *)buf, off); return(cc+off); #endif hpux ! #if (!(defined(sgi) || defined(BPFILT))) ! return(read(fd, (char *)buf, len)); ! #endif /* sgi || BPFILT */ } /* --- 1358,1388 ---- } if (fis.vtype != off) return(-1); + bcopy(fis.value.s, (char *)buf, off); + + RDS[0].dataLen = cc+off; + RDS[0].dataPtr = buf; + RDS[1].dataLen = 0; + return(cc+off); #endif hpux ! #if (!(defined(BPFILT) || defined(sgi) || defined(hpux))) ! RDS[0].dataLen = 0; ! ! if ((cc = read(fd, (char *)buf, len)) <= 0) ! return(cc); ! ! if (cc > len) ! cc = len; ! ! RDS[0].dataLen = cc; ! RDS[0].dataPtr = buf; ! RDS[1].dataLen = 0; ! ! return(cc); ! #endif /* BPFILT || sgi || hpux */ } /* *** README.orig Tue Apr 19 08:39:41 1994 --- README Thu May 19 16:59:52 1994 *************** *** 5,11 **** The University of Melbourne djh@munnari.OZ.AU January, 1992 ! version 1.7 ARNS is 'A Remote Network Server' package for AppleTalk that allows a --- 5,11 ---- The University of Melbourne djh@munnari.OZ.AU January, 1992 ! version 1.8 ARNS is 'A Remote Network Server' package for AppleTalk that allows a