if_ed.c "NIC memory corrupt - invalid packet length" error

Juan Rodriguez juan.fco.rodriguez at gmail.com
Thu Oct 21 16:38:51 PDT 2004


On Thu, 21 Oct 2004 16:27:47 -0700, Luigi Rizzo <rizzo at icir.org> wrote:
> On Fri, Oct 22, 2004 at 12:17:29AM +0100, Juan Rodriguez wrote:
> > Hello,
> >
> > I'm getting this error now and then, so I've tried to look at the
> > file "if_ed.c" where the message is printed to sort it out...
> 
> most of the time the message is because of a runt packet, or
> a residue of some collision, or the like. I'd probably just
> comment out the printf() if it bothers you.
> 
> > I'd be glad if somebody could tell me what's the reason of this line
> > inside "ed_rint()" function:
> >
> >          /*
> >           * because buffers are aligned on 256-byte boundary,
> >           * the length computed above is off by 256 in almost
> >           * all cases. Fix it...
> >           */
> >           if (len & 0xff)
> >                  len -= 256 ;
> >
> > I wonder what can happen here if we've got a length value
> 
> well because the comment refers to the code above, you should
> supply that as well or there is nothing we can comment about.
> Apart from that, i vaguely remember having touched this part
> of the code and it was taking care of bugs in the NIC which
> at times would compute a wrong length. In any case it is mostly
> unrelated to the above which has an easier explaination
> 
> cheers
> luigi
> 

Ok, I was expecting that you all would look at the source file, it's a
pain for me to copy/paste souce code here:

      if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring)) ||
                    len < (ETHER_MIN_LEN - ETHER_CRC_LEN +
sizeof(struct ed_ring))) {
                        /*
                         * Length is a wild value. There's a good chance that
                         * this was caused by the NIC being old and buggy.
                         * The bug is that the length low byte is duplicated in
                         * the high byte. Try to recalculate the length based on
                         * the pointer to the next packet.
                         */
                        /*
                         * NOTE: sc->next_packet is pointing at the
current packet.
                         */
                        len &= ED_PAGE_SIZE - 1;        /* preserve
offset into page */
                        if (packet_hdr.next_packet >= sc->next_packet) {
                                len += (packet_hdr.next_packet -
sc->next_packet) * ED_PAGE_SIZE;
                        } else {
                                len += ((packet_hdr.next_packet -
sc->rec_page_start) +
                                        (sc->rec_page_stop -
sc->next_packet)) * ED_PAGE_SIZE;
                        }
                        /*
                         * because buffers are aligned on 256-byte boundary,
                         * the length computed above is off by 256 in almost
                         * all cases. Fix it...
                         */
                        if (len & 0xff)
                                len -= 256 ;


I hope it's clearer now, but Im still got the doubt about what
would happen if we've got, e.g., len = 120 and we do
len -= 256, isn't this a possible bug ? 

Thanks


More information about the freebsd-net mailing list