Patch #: 6 Type: bugfix Priority: sites Affects: sites running UAR with Berkeley Packet Filter Reported: David Hornsby Summary: Handle multiple packets in single BPF read Archived: munnari.OZ.AU mac/cap.patches/uar.1.0.patch06 Application: 'cd uar; patch -p < uar.1.0.patch06' *** ddp.c.orig Wed May 18 13:30:05 1994 --- ddp.c Thu May 19 17:26:24 1994 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.1 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.2 $ * */ *************** *** 28,33 **** --- 28,34 ---- extern u_long uar_stats[]; extern u_long pkts_dropped; extern struct iflist iflist[]; + extern struct RDS RDS[]; extern char *stats_msg[]; extern u_char buf[]; *************** *** 40,46 **** readeth(ifn, fd) int ifn, fd; { ! int cc; void ddp(); if ((cc = read_eth(fd, buf+HDRSIZ, BUFSIZE-HDRSIZ)) < 0) { --- 41,47 ---- readeth(ifn, fd) int ifn, fd; { ! int cc, i; void ddp(); if ((cc = read_eth(fd, buf+HDRSIZ, BUFSIZE-HDRSIZ)) < 0) { *************** *** 54,60 **** if (iflist[ifn].state == ADDR_PENDING) return; /* not init'd yet */ ! ddp(ifn, buf+HDRSIZ, cc); return; } --- 55,65 ---- if (iflist[ifn].state == ADDR_PENDING) return; /* not init'd yet */ ! for (i = 0; i < NUMRDS; i++) { ! if (RDS[i].dataLen == 0) ! break; ! ddp(ifn, RDS[i].dataPtr, RDS[i].dataLen); ! } return; } *************** *** 68,74 **** readaarp(ifn, fd) int ifn, fd; { ! int cc; void aarp(); if ((cc = read_eth(fd, buf+HDRSIZ, BUFSIZE-HDRSIZ)) < 0) { --- 73,79 ---- readaarp(ifn, fd) int ifn, fd; { ! int cc, i; void aarp(); if ((cc = read_eth(fd, buf+HDRSIZ, BUFSIZE-HDRSIZ)) < 0) { *************** *** 79,85 **** if (cc == 0) return; ! aarp(ifn, buf+HDRSIZ, cc); return; } --- 84,94 ---- if (cc == 0) return; ! for (i = 0; i < NUMRDS; i++) { ! if (RDS[i].dataLen == 0) ! break; ! aarp(ifn, RDS[i].dataPtr, RDS[i].dataLen); ! } return; } *************** *** 96,102 **** readdev(ifn, fd) int ifn, fd; { ! int cc; u_char *pkt; void ddp(), aarp(); --- 105,111 ---- readdev(ifn, fd) int ifn, fd; { ! int cc, i; u_char *pkt; void ddp(), aarp(); *************** *** 108,143 **** if (cc == 0) return; ! pkt = buf+HDRSIZ; ! if (iflist[ifn].phase == PHASE1) { ! if (pkt[12] == 0x80) { ! switch (pkt[13]) { ! case 0xf3: ! aarp(ifn, pkt, cc); ! break; ! case 0x9b: if (iflist[ifn].state == ADDR_PENDING) return; /* not init'd yet */ ddp(ifn, pkt, cc); ! break; ! default: ! break; ! } ! } ! } else if (iflist[ifn].phase == PHASE2) { ! 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 (iflist[ifn].state == ADDR_PENDING) ! return; /* not init'd yet */ ! ddp(ifn, pkt, cc); ! } else { ! if ((pkt[17]==0x00) && (pkt[18]==0x00) && (pkt[19]==0x00) ! && (pkt[20]==0x80) && (pkt[21]==0xF3)) { ! aarp(ifn, pkt, cc); } } } --- 117,158 ---- 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 (iflist[ifn].phase == PHASE1) { ! if (pkt[12] == 0x80) { ! switch (pkt[13]) { ! case 0xf3: ! aarp(ifn, pkt, cc); ! break; ! case 0x9b: ! if (iflist[ifn].state == ADDR_PENDING) ! return; /* not init'd yet */ ! ddp(ifn, pkt, cc); ! break; ! default: ! break; ! } ! } ! } else if (iflist[ifn].phase == PHASE2) { ! 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 (iflist[ifn].state == ADDR_PENDING) return; /* not init'd yet */ ddp(ifn, pkt, cc); ! } else { ! if ((pkt[17]==0x00) && (pkt[18]==0x00) && (pkt[19]==0x00) ! && (pkt[20]==0x80) && (pkt[21]==0xF3)) { ! aarp(ifn, pkt, cc); ! } } } } *** uar.h.orig Fri Dec 10 01:17:26 1993 --- uar.h Thu May 19 17:25:54 1994 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.2 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.3 $ * */ *************** *** 62,69 **** #define MAXNODES 256 /* maxm. nodes per interface */ #define SKTBUFSIZ 32768 /* SO_RCVBUF buffer size */ ! #define BUFSIZE 1600 /* main receive buffer size */ ! #define HDRSIZ 22 /* room for Phase 2 header */ #define INFOTimer 5 /* server ZIP/Info proc (1 sec) */ #define RTMPTimer 50 /* RTMP sendRTMP timer (10 sec) */ --- 62,69 ---- #define MAXNODES 256 /* maxm. nodes per interface */ #define SKTBUFSIZ 32768 /* SO_RCVBUF buffer size */ ! #define HDRSIZ 24 /* room for Phase 2 header */ ! #define BUFSIZE 4096+HDRSIZ /* main receive buffer size */ #define INFOTimer 5 /* server ZIP/Info proc (1 sec) */ #define RTMPTimer 50 /* RTMP sendRTMP timer (10 sec) */ *************** *** 327,332 **** --- 327,344 ---- u_char *data; u_char *addr; short hop; + }; + + /* + * Read Data Structure + * + */ + + #define NUMRDS 32 + + struct RDS { + u_short dataLen; + u_char *dataPtr; }; /* *** pf.c.orig Fri Dec 10 00:21:38 1993 --- pf.c Thu May 19 15:29:28 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 Wed May 18 13:30:52 1994 --- README Thu May 19 17:28:54 1994 *************** *** 4,10 **** The University of Melbourne djh@munnari.OZ.AU October, 1993 ! version 1.0.5 --- 4,10 ---- The University of Melbourne djh@munnari.OZ.AU October, 1993 ! version 1.0.6