home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / unix / bsd / 10279 < prev    next >
Encoding:
Text File  |  1992-12-16  |  6.1 KB  |  182 lines

  1. Newsgroups: comp.unix.bsd
  2. Path: sparky!uunet!news.univie.ac.at!news.tu-graz.ac.at!fstgds01!chmr
  3. From: chmr@fstgds01.tu-graz.ac.at (Christoph Robitschko)
  4. Subject: [386bsd] correct handling of trailers in if_we.c (PATCH)
  5. Message-ID: <1992Dec16.100515.11198@news.tu-graz.ac.at>
  6. Sender: news@news.tu-graz.ac.at (USENET News System)
  7. Nntp-Posting-Host: fstgds01
  8. Organization: Technical University of Graz, Austria
  9. Date: Wed, 16 Dec 92 10:05:15 GMT
  10. Lines: 170
  11.  
  12.  
  13. My machine crashed with a type 12 trap when ftping to a local workstation.
  14. This problem was not easy to fix, because there were three bugs:
  15.  
  16. First, there was a calculation of the start address of the (trailing)
  17. header of a packet, without checking if this address was inside the
  18. ethernet card ring buffer. That caused the length parameter to a bcopy 
  19. call to become negative -- crash.
  20.  
  21. Second, the length of the packet was read from the ethernet card
  22. memory as a short. This did not work, but to assemble it from two
  23. bytes does work (??). I think the compiler was generating bad code.
  24. Anyway, that caused the header offset to become bigger that the length
  25. of the packet, same symptoms as above.
  26.  
  27. Third, the length of trailer packets was truncated by sizeof(ether_header),
  28. which caused the packet to be dropped.
  29.  
  30. But finally, I have fixed these problems in the if_we driver. I don't know
  31. if the peoblems exist in other ethernet drivers, if you have used 
  32. if_we.c as a porting base, you will want to check.
  33.  
  34.                             Christoph
  35.  
  36. Here's the patch:
  37. *** /sys/i386/isa/if_we.c.patchkit58    Wed Dec 16 10:26:17 1992
  38. --- /sys/i386/isa/if_we.c    Wed Dec 16 10:25:18 1992
  39. ***************
  40. *** 55,60 ****
  41. --- 55,63 ----
  42.    *          Allowed interupt handler to look at unit other than 0
  43.    *            Bdry was static, made it into an array w/ one entry per
  44.    *          interface.  nerd@percival.rain.com (Michael Galassi)
  45. +  *
  46. +  * 15.12.92 - fixed trailer handling in weread() and weget()
  47. +  *            chmr@edvz.tu-graz.ac.at (Christoph Robitschko)
  48.    */
  49.    
  50.   #include "we.h"
  51. *************** werint(unit)
  52. *** 572,578 ****
  53.           if (len > 30 && len <= ETHERMTU+100
  54.               /*&& (*(char *)wer  == 1 || *(char *) wer == 0x21)*/)
  55.               weread(sc, (caddr_t)(wer + 1), len);
  56. !         else printf("reject %d", len);
  57.   
  58.   outofbufs:
  59.           wecmd.cs_byte = inb(sc->we_io_nic_addr + WD_P0_COMMAND);
  60. --- 575,581 ----
  61.           if (len > 30 && len <= ETHERMTU+100
  62.               /*&& (*(char *)wer  == 1 || *(char *) wer == 0x21)*/)
  63.               weread(sc, (caddr_t)(wer + 1), len);
  64. !         else printf("we%d: rejected packet with bogus len %d", unit, len);
  65.   
  66.   outofbufs:
  67.           wecmd.cs_byte = inb(sc->we_io_nic_addr + WD_P0_COMMAND);
  68. *************** wesetaddr(physaddr, unit)
  69. *** 709,714 ****
  70. --- 712,718 ----
  71.           (((caddr_t)((eh)+1)+(off))) - (sc)->we_vmem_end \
  72.           + (sc)->we_vmem_ring: \
  73.           ((caddr_t)((eh)+1)+(off)))
  74.   /*
  75.    * Pass a packet to the higher levels.
  76.    * We deal with the trailer protocol here.
  77. *************** weread(sc, buf, len)
  78. *** 720,726 ****
  79.   {
  80.       register struct ether_header *eh;
  81.           struct mbuf *m, *weget();
  82. !     int off, resid;
  83.   
  84.       /*
  85.        * Deal with trailer protocol: if type is trailer type
  86. --- 724,730 ----
  87.   {
  88.       register struct ether_header *eh;
  89.           struct mbuf *m, *weget();
  90. !     int off;
  91.   
  92.       /*
  93.        * Deal with trailer protocol: if type is trailer type
  94. *************** weread(sc, buf, len)
  95. *** 731,750 ****
  96.       eh->ether_type = ntohs((u_short)eh->ether_type);
  97.       if (eh->ether_type >= ETHERTYPE_TRAIL &&
  98.           eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
  99.           off = (eh->ether_type - ETHERTYPE_TRAIL) * 512;
  100.           if (off >= ETHERMTU) return;        /* sanity */
  101. !         eh->ether_type = ntohs(*wedataaddr(sc, eh, off, u_short *));
  102. !         resid = ntohs(*(wedataaddr(sc, eh, off+2, u_short *)));
  103.           if (off + resid > len) return;        /* sanity */
  104.           len = off + resid;
  105. !     } else    off = 0;
  106. !     len -= sizeof(struct ether_header);
  107.       if (len <= 0) return;
  108.   
  109.       /*
  110.        * Pull packet off interface.  Off is nonzero if packet
  111. !      * has trailing header; neget will then force this header
  112.        * information to be at the front, but we still have to drop
  113.        * the type and length which are at the front of any trailer data.
  114.        */
  115. --- 735,761 ----
  116.       eh->ether_type = ntohs((u_short)eh->ether_type);
  117.       if (eh->ether_type >= ETHERTYPE_TRAIL &&
  118.           eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
  119. +         caddr_t trailhead;
  120. +         int    resid;
  121.           off = (eh->ether_type - ETHERTYPE_TRAIL) * 512;
  122.           if (off >= ETHERMTU) return;        /* sanity */
  123. !         /* eh->ether_type = ntohs(*wedataaddr(sc, eh, off, u_short *)); */
  124. !         /* resid = ntohs(*(wedataaddr(sc, eh, off+2, u_short *))); */
  125. !         trailhead = wedataaddr(sc, eh, off, caddr_t);
  126. !         eh->ether_type = trailhead[0] * 256 + trailhead[1];
  127. !         resid = trailhead[2] * 256 + trailhead[3];
  128.           if (off + resid > len) return;        /* sanity */
  129.           len = off + resid;
  130. !     } else {
  131. !         off = 0; 
  132. !         len -= sizeof(struct ether_header);
  133. !     }
  134.       if (len <= 0) return;
  135.   
  136.       /*
  137.        * Pull packet off interface.  Off is nonzero if packet
  138. !      * has trailing header; weget will then force this header
  139.        * information to be at the front, but we still have to drop
  140.        * the type and length which are at the front of any trailer data.
  141.        */
  142. *************** weget(buf, totlen, off0, ifp, sc)
  143. *** 828,840 ****
  144.           totlen -= len;
  145.           /* only do up to end of buffer */
  146.           if (cp+len > sc->we_vmem_end) {
  147. !             unsigned toend = sc->we_vmem_end - cp;
  148.   
  149. -             bcopy(cp, mtod(m, caddr_t), toend);
  150. -             cp = sc->we_vmem_ring;
  151.               bcopy(cp, mtod(m, caddr_t)+toend, len - toend);
  152.               cp += len - toend;
  153. -             epkt = cp + totlen;
  154.           } else {
  155.               bcopy(cp, mtod(m, caddr_t), (unsigned)len);
  156.               cp += len;
  157. --- 839,855 ----
  158.           totlen -= len;
  159.           /* only do up to end of buffer */
  160.           if (cp+len > sc->we_vmem_end) {
  161. !             long toend = sc->we_vmem_end - cp;
  162. !             if (toend > 0)
  163. !                 bcopy(cp, mtod(m, caddr_t), toend);
  164. !             else
  165. !                 toend = 0;
  166. !             cp -= (sc->we_vmem_end - sc->we_vmem_ring);
  167. !             epkt -= (sc->we_vmem_end - sc->we_vmem_ring);
  168.   
  169.               bcopy(cp, mtod(m, caddr_t)+toend, len - toend);
  170.               cp += len - toend;
  171.           } else {
  172.               bcopy(cp, mtod(m, caddr_t), (unsigned)len);
  173.               cp += len;
  174.  
  175. --- End of patch ---
  176. -- 
  177. .signature: Too many levels of symbolic links
  178.