/[lwip]/lwip/src/core/ipv4/ip_frag.c
ViewVC logotype

Diff of /lwip/src/core/ipv4/ip_frag.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by likewise, Thu May 1 13:24:01 2003 UTC revision 1.11 by likewise, Mon Jun 9 21:14:47 2003 UTC
# Line 55  Line 55 
55   */   */
56  static struct pbuf *  static struct pbuf *
57  copy_from_pbuf(struct pbuf *p, u16_t * offset,  copy_from_pbuf(struct pbuf *p, u16_t * offset,
58                                     u8_t * buffer, u16_t len)             u8_t * buffer, u16_t len)
59  {  {
60    u16_t l;    u16_t l;
61    
# Line 98  ip_reass_timer(void *arg) Line 98  ip_reass_timer(void *arg)
98      ip_reasstmr--;      ip_reasstmr--;
99      sys_timeout(IP_REASS_TMO, ip_reass_timer, NULL);      sys_timeout(IP_REASS_TMO, ip_reass_timer, NULL);
100    } else if (ip_reasstmr == 1)    } else if (ip_reasstmr == 1)
101          ip_reasstmr = 0;    ip_reasstmr = 0;
102  }  }
103    
104  struct pbuf *  struct pbuf *
# Line 147  ip_reass(struct pbuf *p) Line 147  ip_reass(struct pbuf *p)
147         reassembly buffer, we discard the entire packet. */         reassembly buffer, we discard the entire packet. */
148      if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {      if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {
149        DEBUGF(IP_REASS_DEBUG,        DEBUGF(IP_REASS_DEBUG,
150               ("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,         ("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,
151                offset + len, IP_REASS_BUFSIZE));          offset + len, IP_REASS_BUFSIZE));
152        sys_untimeout(ip_reass_timer, NULL);        sys_untimeout(ip_reass_timer, NULL);
153        ip_reasstmr = 0;        ip_reasstmr = 0;
154        goto nullreturn;        goto nullreturn;
# Line 157  ip_reass(struct pbuf *p) Line 157  ip_reass(struct pbuf *p)
157      /* Copy the fragment into the reassembly buffer, at the right      /* Copy the fragment into the reassembly buffer, at the right
158         offset. */         offset. */
159      DEBUGF(IP_REASS_DEBUG,      DEBUGF(IP_REASS_DEBUG,
160             ("ip_reass: copying with offset %d into %d:%d\n", offset,       ("ip_reass: copying with offset %d into %d:%d\n", offset,
161              IP_HLEN + offset, IP_HLEN + offset + len));        IP_HLEN + offset, IP_HLEN + offset + len));
162      i = IPH_HL(fraghdr) * 4;      i = IPH_HL(fraghdr) * 4;
163      copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);      copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);
164    
165      /* Update the bitmap. */      /* Update the bitmap. */
166      if (offset / (8 * 8) == (offset + len) / (8 * 8)) {      if (offset / (8 * 8) == (offset + len) / (8 * 8)) {
167        DEBUGF(IP_REASS_DEBUG,        DEBUGF(IP_REASS_DEBUG,
168               ("ip_reass: updating single byte in bitmap.\n"));         ("ip_reass: updating single byte in bitmap.\n"));
169        /* If the two endpoints are in the same byte, we only update        /* If the two endpoints are in the same byte, we only update
170           that byte. */           that byte. */
171        ip_reassbitmap[offset / (8 * 8)] |=        ip_reassbitmap[offset / (8 * 8)] |=
172            bitmap_bits[(offset / 8) & 7] &      bitmap_bits[(offset / 8) & 7] &
173            ~bitmap_bits[((offset + len) / 8) & 7];      ~bitmap_bits[((offset + len) / 8) & 7];
174      } else {      } else {
175        /* If the two endpoints are in different bytes, we update the        /* If the two endpoints are in different bytes, we update the
176           bytes in the endpoints and fill the stuff inbetween with           bytes in the endpoints and fill the stuff inbetween with
177           0xff. */           0xff. */
178        ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];        ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];
179        DEBUGF(IP_REASS_DEBUG,        DEBUGF(IP_REASS_DEBUG,
180               ("ip_reass: updating many bytes in bitmap (%d:%d).\n",         ("ip_reass: updating many bytes in bitmap (%d:%d).\n",
181                1 + offset / (8 * 8), (offset + len) / (8 * 8)));          1 + offset / (8 * 8), (offset + len) / (8 * 8)));
182        for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {        for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
183          ip_reassbitmap[i] = 0xff;    ip_reassbitmap[i] = 0xff;
184        }        }
185        ip_reassbitmap[(offset + len) / (8 * 8)] |=        ip_reassbitmap[(offset + len) / (8 * 8)] |=
186            ~bitmap_bits[((offset + len) / 8) & 7];      ~bitmap_bits[((offset + len) / 8) & 7];
187      }      }
188    
189      /* If this fragment has the More Fragments flag set to zero, we      /* If this fragment has the More Fragments flag set to zero, we
# Line 196  ip_reass(struct pbuf *p) Line 196  ip_reass(struct pbuf *p)
196        ip_reassflags |= IP_REASS_FLAG_LASTFRAG;        ip_reassflags |= IP_REASS_FLAG_LASTFRAG;
197        ip_reasslen = offset + len;        ip_reasslen = offset + len;
198        DEBUGF(IP_REASS_DEBUG,        DEBUGF(IP_REASS_DEBUG,
199               ("ip_reass: last fragment seen, total len %d\n",         ("ip_reass: last fragment seen, total len %d\n",
200                ip_reasslen));          ip_reasslen));
201      }      }
202    
203      /* Finally, we check if we have a full packet in the buffer. We do      /* Finally, we check if we have a full packet in the buffer. We do
# Line 207  ip_reass(struct pbuf *p) Line 207  ip_reass(struct pbuf *p)
207        /* Check all bytes up to and including all but the last byte in        /* Check all bytes up to and including all but the last byte in
208           the bitmap. */           the bitmap. */
209        for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {        for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {
210          if (ip_reassbitmap[i] != 0xff) {    if (ip_reassbitmap[i] != 0xff) {
211            DEBUGF(IP_REASS_DEBUG,      DEBUGF(IP_REASS_DEBUG,
212                   ("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n",       ("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n",
213                    i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));        i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
214            goto nullreturn;      goto nullreturn;
215          }    }
216        }        }
217        /* Check the last byte in the bitmap. It should contain just the        /* Check the last byte in the bitmap. It should contain just the
218           right amount of bits. */           right amount of bits. */
219        if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=        if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=
220            (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {      (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
221          DEBUGF(IP_REASS_DEBUG,    DEBUGF(IP_REASS_DEBUG,
222                 ("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",           ("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",
223                  ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],      ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
224                  ip_reassbitmap[ip_reasslen / (8 * 8)]));      ip_reassbitmap[ip_reasslen / (8 * 8)]));
225          goto nullreturn;    goto nullreturn;
226        }        }
227    
228        /* Pretend to be a "normal" (i.e., not fragmented) IP packet        /* Pretend to be a "normal" (i.e., not fragmented) IP packet
# Line 242  ip_reass(struct pbuf *p) Line 242  ip_reass(struct pbuf *p)
242        pbuf_free(p);        pbuf_free(p);
243        p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);        p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
244        if (p != NULL) {        if (p != NULL) {
245          i = 0;    i = 0;
246          for (q = p; q != NULL; q = q->next) {    for (q = p; q != NULL; q = q->next) {
247            /* Copy enough bytes to fill this pbuf in the chain. The      /* Copy enough bytes to fill this pbuf in the chain. The
248               available data in the pbuf is given by the q->len         available data in the pbuf is given by the q->len
249               variable. */         variable. */
250            DEBUGF(IP_REASS_DEBUG,      DEBUGF(IP_REASS_DEBUG,
251                   ("ip_reass: memcpy from %p (%d) to %p, %d bytes\n",       ("ip_reass: memcpy from %p (%d) to %p, %d bytes\n",
252                    &ip_reassbuf[i], i, q->payload,        &ip_reassbuf[i], i, q->payload,
253                    q->len > ip_reasslen - i ? ip_reasslen - i : q->len));        q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
254            memcpy(q->payload, &ip_reassbuf[i],      memcpy(q->payload, &ip_reassbuf[i],
255                  q->len > ip_reasslen - i ? ip_reasslen - i : q->len);      q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
256            i += q->len;      i += q->len;
257          }    }
258  #ifdef IP_STATS  #ifdef IP_STATS
259          ++lwip_stats.ip_frag.fw;    ++lwip_stats.ip_frag.fw;
260  #endif /* IP_STATS */  #endif /* IP_STATS */
261        } else {        } else {
262  #ifdef IP_STATS  #ifdef IP_STATS
263          ++lwip_stats.ip_frag.memerr;    ++lwip_stats.ip_frag.memerr;
264  #endif /* IP_STATS */  #endif /* IP_STATS */
265        }        }
266        DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));        DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26