ReactOS  0.4.15-dev-1207-g698a8e6
vj.c
Go to the documentation of this file.
1 /*
2  * Routines to compress and uncompess tcp packets (for transmission
3  * over low speed serial lines.
4  *
5  * Copyright (c) 1989 Regents of the University of California.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley. The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
21  * Initial distribution.
22  *
23  * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,
24  * so that the entire packet being decompressed doesn't have
25  * to be in contiguous memory (just the compressed header).
26  *
27  * Modified March 1998 by Guy Lancaster, glanca@gesn.com,
28  * for a 16 bit processor.
29  */
30 
31 #include "lwip/opt.h"
32 
33 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
34 
35 #include "ppp_impl.h"
36 #include "pppdebug.h"
37 
38 #include "vj.h"
39 
40 #include <string.h>
41 
42 #if VJ_SUPPORT
43 
44 #if LINK_STATS
45 #define INCR(counter) ++comp->stats.counter
46 #else
47 #define INCR(counter)
48 #endif
49 
50 void
51 vj_compress_init(struct vjcompress *comp)
52 {
53  register u_char i;
54  register struct cstate *tstate = comp->tstate;
55 
56 #if MAX_SLOTS == 0
57  memset((char *)comp, 0, sizeof(*comp));
58 #endif
59  comp->maxSlotIndex = MAX_SLOTS - 1;
60  comp->compressSlot = 0; /* Disable slot ID compression by default. */
61  for (i = MAX_SLOTS - 1; i > 0; --i) {
62  tstate[i].cs_id = i;
63  tstate[i].cs_next = &tstate[i - 1];
64  }
65  tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
66  tstate[0].cs_id = 0;
67  comp->last_cs = &tstate[0];
68  comp->last_recv = 255;
69  comp->last_xmit = 255;
70  comp->flags = VJF_TOSS;
71 }
72 
73 
74 /* ENCODE encodes a number that is known to be non-zero. ENCODEZ
75  * checks for zero (since zero has to be encoded in the long, 3 byte
76  * form).
77  */
78 #define ENCODE(n) { \
79  if ((u_short)(n) >= 256) { \
80  *cp++ = 0; \
81  cp[1] = (u_char)(n); \
82  cp[0] = (u_char)((n) >> 8); \
83  cp += 2; \
84  } else { \
85  *cp++ = (u_char)(n); \
86  } \
87 }
88 #define ENCODEZ(n) { \
89  if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
90  *cp++ = 0; \
91  cp[1] = (u_char)(n); \
92  cp[0] = (u_char)((n) >> 8); \
93  cp += 2; \
94  } else { \
95  *cp++ = (u_char)(n); \
96  } \
97 }
98 
99 #define DECODEL(f) { \
100  if (*cp == 0) {\
101  u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \
102  (f) = htonl(tmp); \
103  cp += 3; \
104  } else { \
105  u32_t tmp = ntohl(f) + (u32_t)*cp++; \
106  (f) = htonl(tmp); \
107  } \
108 }
109 
110 #define DECODES(f) { \
111  if (*cp == 0) {\
112  u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \
113  (f) = htons(tmp); \
114  cp += 3; \
115  } else { \
116  u_short tmp = ntohs(f) + (u_short)*cp++; \
117  (f) = htons(tmp); \
118  } \
119 }
120 
121 #define DECODEU(f) { \
122  if (*cp == 0) {\
123  (f) = htons(((u_short)cp[1] << 8) | cp[2]); \
124  cp += 3; \
125  } else { \
126  (f) = htons((u_short)*cp++); \
127  } \
128 }
129 
130 /*
131  * vj_compress_tcp - Attempt to do Van Jacobson header compression on a
132  * packet. This assumes that nb and comp are not null and that the first
133  * buffer of the chain contains a valid IP header.
134  * Return the VJ type code indicating whether or not the packet was
135  * compressed.
136  */
137 u_int
138 vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
139 {
140  register struct ip_hdr *ip = (struct ip_hdr *)pb->payload;
141  register struct cstate *cs = comp->last_cs->cs_next;
142  register u_short hlen = IPH_HL(ip);
143  register struct tcp_hdr *oth;
144  register struct tcp_hdr *th;
145  register u_short deltaS, deltaA;
146  register u_long deltaL;
147  register u_int changes = 0;
148  u_char new_seq[16];
149  register u_char *cp = new_seq;
150 
151  /*
152  * Check that the packet is IP proto TCP.
153  */
154  if (IPH_PROTO(ip) != IP_PROTO_TCP) {
155  return (TYPE_IP);
156  }
157 
158  /*
159  * Bail if this is an IP fragment or if the TCP packet isn't
160  * `compressible' (i.e., ACK isn't set or some other control bit is
161  * set).
162  */
163  if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) {
164  return (TYPE_IP);
165  }
166  th = (struct tcp_hdr *)&((long *)ip)[hlen];
167  if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) {
168  return (TYPE_IP);
169  }
170  /*
171  * Packet is compressible -- we're going to send either a
172  * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need
173  * to locate (or create) the connection state. Special case the
174  * most recently used connection since it's most likely to be used
175  * again & we don't have to do any reordering if it's used.
176  */
177  INCR(vjs_packets);
178  if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src)
179  || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest)
180  || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
181  /*
182  * Wasn't the first -- search for it.
183  *
184  * States are kept in a circularly linked list with
185  * last_cs pointing to the end of the list. The
186  * list is kept in lru order by moving a state to the
187  * head of the list whenever it is referenced. Since
188  * the list is short and, empirically, the connection
189  * we want is almost always near the front, we locate
190  * states via linear search. If we don't find a state
191  * for the datagram, the oldest state is (re-)used.
192  */
193  register struct cstate *lcs;
194  register struct cstate *lastcs = comp->last_cs;
195 
196  do {
197  lcs = cs; cs = cs->cs_next;
198  INCR(vjs_searches);
199  if (ip_addr_cmp(&ip->src, &cs->cs_ip.src)
200  && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest)
201  && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
202  goto found;
203  }
204  } while (cs != lastcs);
205 
206  /*
207  * Didn't find it -- re-use oldest cstate. Send an
208  * uncompressed packet that tells the other side what
209  * connection number we're using for this conversation.
210  * Note that since the state list is circular, the oldest
211  * state points to the newest and we only need to set
212  * last_cs to update the lru linkage.
213  */
214  INCR(vjs_misses);
215  comp->last_cs = lcs;
216  hlen += TCPH_HDRLEN(th);
217  hlen <<= 2;
218  /* Check that the IP/TCP headers are contained in the first buffer. */
219  if (hlen > pb->len) {
220  return (TYPE_IP);
221  }
222  goto uncompressed;
223 
224  found:
225  /*
226  * Found it -- move to the front on the connection list.
227  */
228  if (cs == lastcs) {
229  comp->last_cs = lcs;
230  } else {
231  lcs->cs_next = cs->cs_next;
232  cs->cs_next = lastcs->cs_next;
233  lastcs->cs_next = cs;
234  }
235  }
236 
237  oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen];
238  deltaS = hlen;
239  hlen += TCPH_HDRLEN(th);
240  hlen <<= 2;
241  /* Check that the IP/TCP headers are contained in the first buffer. */
242  if (hlen > pb->len) {
243  PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen));
244  return (TYPE_IP);
245  }
246 
247  /*
248  * Make sure that only what we expect to change changed. The first
249  * line of the `if' checks the IP protocol version, header length &
250  * type of service. The 2nd line checks the "Don't fragment" bit.
251  * The 3rd line checks the time-to-live and protocol (the protocol
252  * check is unnecessary but costless). The 4th line checks the TCP
253  * header length. The 5th line checks IP options, if any. The 6th
254  * line checks TCP options, if any. If any of these things are
255  * different between the previous & current datagram, we send the
256  * current datagram `uncompressed'.
257  */
258  if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0]
259  || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3]
260  || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4]
261  || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth)
262  || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2))
263  || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) {
264  goto uncompressed;
265  }
266 
267  /*
268  * Figure out which of the changing fields changed. The
269  * receiver expects changes in the order: urgent, window,
270  * ack, seq (the order minimizes the number of temporaries
271  * needed in this section of code).
272  */
273  if (TCPH_FLAGS(th) & TCP_URG) {
274  deltaS = ntohs(th->urgp);
275  ENCODEZ(deltaS);
276  changes |= NEW_U;
277  } else if (th->urgp != oth->urgp) {
278  /* argh! URG not set but urp changed -- a sensible
279  * implementation should never do this but RFC793
280  * doesn't prohibit the change so we have to deal
281  * with it. */
282  goto uncompressed;
283  }
284 
285  if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) {
286  ENCODE(deltaS);
287  changes |= NEW_W;
288  }
289 
290  if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) {
291  if (deltaL > 0xffff) {
292  goto uncompressed;
293  }
294  deltaA = (u_short)deltaL;
295  ENCODE(deltaA);
296  changes |= NEW_A;
297  }
298 
299  if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) {
300  if (deltaL > 0xffff) {
301  goto uncompressed;
302  }
303  deltaS = (u_short)deltaL;
304  ENCODE(deltaS);
305  changes |= NEW_S;
306  }
307 
308  switch(changes) {
309  case 0:
310  /*
311  * Nothing changed. If this packet contains data and the
312  * last one didn't, this is probably a data packet following
313  * an ack (normal on an interactive connection) and we send
314  * it compressed. Otherwise it's probably a retransmit,
315  * retransmitted ack or window probe. Send it uncompressed
316  * in case the other side missed the compressed version.
317  */
318  if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) &&
319  ntohs(IPH_LEN(&cs->cs_ip)) == hlen) {
320  break;
321  }
322 
323  /* (fall through) */
324 
325  case SPECIAL_I:
326  case SPECIAL_D:
327  /*
328  * actual changes match one of our special case encodings --
329  * send packet uncompressed.
330  */
331  goto uncompressed;
332 
333  case NEW_S|NEW_A:
334  if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
335  /* special case for echoed terminal traffic */
336  changes = SPECIAL_I;
337  cp = new_seq;
338  }
339  break;
340 
341  case NEW_S:
342  if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
343  /* special case for data xfer */
344  changes = SPECIAL_D;
345  cp = new_seq;
346  }
347  break;
348  }
349 
350  deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip)));
351  if (deltaS != 1) {
352  ENCODEZ(deltaS);
353  changes |= NEW_I;
354  }
355  if (TCPH_FLAGS(th) & TCP_PSH) {
357  }
358  /*
359  * Grab the cksum before we overwrite it below. Then update our
360  * state with this packet's header.
361  */
362  deltaA = ntohs(th->chksum);
363  BCOPY(ip, &cs->cs_ip, hlen);
364 
365  /*
366  * We want to use the original packet as our compressed packet.
367  * (cp - new_seq) is the number of bytes we need for compressed
368  * sequence numbers. In addition we need one byte for the change
369  * mask, one for the connection id and two for the tcp checksum.
370  * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how
371  * many bytes of the original packet to toss so subtract the two to
372  * get the new packet size.
373  */
374  deltaS = (u_short)(cp - new_seq);
375  if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
376  comp->last_xmit = cs->cs_id;
377  hlen -= deltaS + 4;
378  if(pbuf_header(pb, -hlen)){
379  /* Can we cope with this failing? Just assert for now */
380  LWIP_ASSERT("pbuf_header failed\n", 0);
381  }
382  cp = (u_char *)pb->payload;
383  *cp++ = (u_char)(changes | NEW_C);
384  *cp++ = cs->cs_id;
385  } else {
386  hlen -= deltaS + 3;
387  if(pbuf_header(pb, -hlen)) {
388  /* Can we cope with this failing? Just assert for now */
389  LWIP_ASSERT("pbuf_header failed\n", 0);
390  }
391  cp = (u_char *)pb->payload;
392  *cp++ = (u_char)changes;
393  }
394  *cp++ = (u_char)(deltaA >> 8);
395  *cp++ = (u_char)deltaA;
396  BCOPY(new_seq, cp, deltaS);
397  INCR(vjs_compressed);
398  return (TYPE_COMPRESSED_TCP);
399 
400  /*
401  * Update connection state cs & send uncompressed packet (that is,
402  * a regular ip/tcp packet but with the 'conversation id' we hope
403  * to use on future compressed packets in the protocol field).
404  */
406  BCOPY(ip, &cs->cs_ip, hlen);
407  IPH_PROTO_SET(ip, cs->cs_id);
408  comp->last_xmit = cs->cs_id;
409  return (TYPE_UNCOMPRESSED_TCP);
410 }
411 
412 /*
413  * Called when we may have missed a packet.
414  */
415 void
416 vj_uncompress_err(struct vjcompress *comp)
417 {
418  comp->flags |= VJF_TOSS;
419  INCR(vjs_errorin);
420 }
421 
422 /*
423  * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
424  * Return 0 on success, -1 on failure.
425  */
426 int
427 vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp)
428 {
429  register u_int hlen;
430  register struct cstate *cs;
431  register struct ip_hdr *ip;
432 
433  ip = (struct ip_hdr *)nb->payload;
434  hlen = IPH_HL(ip) << 2;
435  if (IPH_PROTO(ip) >= MAX_SLOTS
436  || hlen + sizeof(struct tcp_hdr) > nb->len
437  || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2)
438  > nb->len
439  || hlen > MAX_HDR) {
440  PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n",
441  IPH_PROTO(ip), hlen, nb->len));
442  comp->flags |= VJF_TOSS;
443  INCR(vjs_errorin);
444  return -1;
445  }
446  cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)];
447  comp->flags &=~ VJF_TOSS;
449  BCOPY(ip, &cs->cs_ip, hlen);
450  cs->cs_hlen = (u_short)hlen;
451  INCR(vjs_uncompressedin);
452  return 0;
453 }
454 
455 /*
456  * Uncompress a packet of type TYPE_COMPRESSED_TCP.
457  * The packet is composed of a buffer chain and the first buffer
458  * must contain an accurate chain length.
459  * The first buffer must include the entire compressed TCP/IP header.
460  * This procedure replaces the compressed header with the uncompressed
461  * header and returns the length of the VJ header.
462  */
463 int
464 vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
465 {
466  u_char *cp;
467  struct tcp_hdr *th;
468  struct cstate *cs;
469  u_short *bp;
470  struct pbuf *n0 = *nb;
471  u32_t tmp;
472  u_int vjlen, hlen, changes;
473 
474  INCR(vjs_compressedin);
475  cp = (u_char *)n0->payload;
476  changes = *cp++;
477  if (changes & NEW_C) {
478  /*
479  * Make sure the state index is in range, then grab the state.
480  * If we have a good state index, clear the 'discard' flag.
481  */
482  if (*cp >= MAX_SLOTS) {
483  PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp));
484  goto bad;
485  }
486 
487  comp->flags &=~ VJF_TOSS;
488  comp->last_recv = *cp++;
489  } else {
490  /*
491  * this packet has an implicit state index. If we've
492  * had a line error since the last time we got an
493  * explicit state index, we have to toss the packet.
494  */
495  if (comp->flags & VJF_TOSS) {
496  PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n"));
497  INCR(vjs_tossed);
498  return (-1);
499  }
500  }
501  cs = &comp->rstate[comp->last_recv];
502  hlen = IPH_HL(&cs->cs_ip) << 2;
503  th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen];
504  th->chksum = htons((*cp << 8) | cp[1]);
505  cp += 2;
506  if (changes & TCP_PUSH_BIT) {
507  TCPH_SET_FLAG(th, TCP_PSH);
508  } else {
509  TCPH_UNSET_FLAG(th, TCP_PSH);
510  }
511 
512  switch (changes & SPECIALS_MASK) {
513  case SPECIAL_I:
514  {
515  register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
516  /* some compilers can't nest inline assembler.. */
517  tmp = ntohl(th->ackno) + i;
518  th->ackno = htonl(tmp);
519  tmp = ntohl(th->seqno) + i;
520  th->seqno = htonl(tmp);
521  }
522  break;
523 
524  case SPECIAL_D:
525  /* some compilers can't nest inline assembler.. */
526  tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
527  th->seqno = htonl(tmp);
528  break;
529 
530  default:
531  if (changes & NEW_U) {
532  TCPH_SET_FLAG(th, TCP_URG);
533  DECODEU(th->urgp);
534  } else {
535  TCPH_UNSET_FLAG(th, TCP_URG);
536  }
537  if (changes & NEW_W) {
538  DECODES(th->wnd);
539  }
540  if (changes & NEW_A) {
541  DECODEL(th->ackno);
542  }
543  if (changes & NEW_S) {
544  DECODEL(th->seqno);
545  }
546  break;
547  }
548  if (changes & NEW_I) {
549  DECODES(cs->cs_ip._id);
550  } else {
551  IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1);
552  IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip)));
553  }
554 
555  /*
556  * At this point, cp points to the first byte of data in the
557  * packet. Fill in the IP total length and update the IP
558  * header checksum.
559  */
560  vjlen = (u_short)(cp - (u_char*)n0->payload);
561  if (n0->len < vjlen) {
562  /*
563  * We must have dropped some characters (crc should detect
564  * this but the old slip framing won't)
565  */
566  PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n",
567  n0->len, vjlen));
568  goto bad;
569  }
570 
571 #if BYTE_ORDER == LITTLE_ENDIAN
572  tmp = n0->tot_len - vjlen + cs->cs_hlen;
573  IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp));
574 #else
575  IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen));
576 #endif
577 
578  /* recompute the ip header checksum */
579  bp = (u_short *) &cs->cs_ip;
580  IPH_CHKSUM_SET(&cs->cs_ip, 0);
581  for (tmp = 0; hlen > 0; hlen -= 2) {
582  tmp += *bp++;
583  }
584  tmp = (tmp & 0xffff) + (tmp >> 16);
585  tmp = (tmp & 0xffff) + (tmp >> 16);
586  IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp));
587 
588  /* Remove the compressed header and prepend the uncompressed header. */
589  if(pbuf_header(n0, -((s16_t)(vjlen)))) {
590  /* Can we cope with this failing? Just assert for now */
591  LWIP_ASSERT("pbuf_header failed\n", 0);
592  goto bad;
593  }
594 
595  if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) {
596  struct pbuf *np, *q;
597  u8_t *bufptr;
598 
599  np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
600  if(!np) {
601  PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n"));
602  goto bad;
603  }
604 
605  if(pbuf_header(np, -cs->cs_hlen)) {
606  /* Can we cope with this failing? Just assert for now */
607  LWIP_ASSERT("pbuf_header failed\n", 0);
608  goto bad;
609  }
610 
611  bufptr = n0->payload;
612  for(q = np; q != NULL; q = q->next) {
613  MEMCPY(q->payload, bufptr, q->len);
614  bufptr += q->len;
615  }
616 
617  if(n0->next) {
618  pbuf_chain(np, n0->next);
619  pbuf_dechain(n0);
620  }
621  pbuf_free(n0);
622  n0 = np;
623  }
624 
625  if(pbuf_header(n0, cs->cs_hlen)) {
626  struct pbuf *np;
627 
628  LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
629  np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
630  if(!np) {
631  PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n"));
632  goto bad;
633  }
634  pbuf_cat(np, n0);
635  n0 = np;
636  }
637  LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);
638  MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen);
639 
640  *nb = n0;
641 
642  return vjlen;
643 
644 bad:
645  comp->flags |= VJF_TOSS;
646  INCR(vjs_errorin);
647  return (-1);
648 }
649 
650 #endif /* VJ_SUPPORT */
651 
652 #endif /* PPP_SUPPORT */
Definition: vj.h:105
struct cstate tstate[MAX_SLOTS]
Definition: vj.h:143
u16_t tot_len
Definition: pbuf.h:93
static CHANGE * changes
Definition: io.c:49
#define MAX_SLOTS
Definition: vj.h:31
#define PPPDEBUG(a, b)
Definition: pppdebug.h:69
unsigned long u_long
Definition: linux.h:269
#define IPH_ID(hdr)
Definition: ip.h:150
struct pbuf * next
Definition: pbuf.h:81
static unsigned int bufptr
Definition: tncon.cpp:77
u16_t len
Definition: pbuf.h:96
u_char cs_id
Definition: vj.h:108
#define LOG_WARNING
Definition: syslog.h:49
#define htonl(x)
Definition: module.h:212
#define IPH_PROTO(hdr)
Definition: ip.h:153
int vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
Definition: vj.h:133
#define IPH_OFFSET(hdr)
Definition: ip.h:151
#define TYPE_IP
Definition: vj.h:78
#define NEW_C
Definition: vj.h:84
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
void vj_compress_init(struct vjcompress *comp)
#define SPECIAL_I
Definition: vj.h:92
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define VJF_TOSS
Definition: vj.h:148
#define ntohs(x)
Definition: module.h:208
static const BYTE uncompressed[]
Definition: misc.c:392
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
#define NEW_W
Definition: vj.h:88
uint32_t cs
Definition: isohybrid.c:75
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IP_PROTO_TCP
Definition: ip.h:56
int ip[4]
Definition: rtl.c:1176
smooth NULL
Definition: ftsmooth.c:416
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
Definition: pbuf.h:54
#define PP_HTONS(x)
Definition: def.h:88
#define NEW_A
Definition: vj.h:87
#define TYPE_COMPRESSED_TCP
Definition: vj.h:80
void pbuf_chain(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:786
Definition: dhcpd.h:61
if(!(yy_init))
Definition: macro.lex.yy.c:714
Definition: pbuf.h:79
unsigned long u32_t
Definition: cc.h:25
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define NEW_S
Definition: vj.h:86
Definition: pbuf.h:61
struct cstate * cs_next
Definition: vj.h:106
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
u_int vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
unsigned short u_short
Definition: types.h:81
struct pbuf * pbuf_dechain(struct pbuf *p)
Definition: pbuf.c:803
void vj_uncompress_err(struct vjcompress *comp)
#define SPECIALS_MASK
Definition: vj.h:94
#define PBUF_POOL_BUFSIZE
Definition: opt.h:1104
GLenum GLsizei len
Definition: glext.h:6722
struct cstate * last_cs
Definition: vj.h:134
#define MAX_HDR
Definition: vj.h:32
u_char last_xmit
Definition: vj.h:136
struct cstate rstate[MAX_SLOTS]
Definition: vj.h:144
#define IPH_ID_SET(hdr, id)
Definition: ip.h:159
Definition: ip.h:116
UINT32 u_int
Definition: types.h:82
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define IPH_HL(hdr)
Definition: ip.h:147
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:745
#define TCP_PUSH_BIT
Definition: vj.h:96
unsigned char u8_t
Definition: cc.h:23
#define IPH_LEN(hdr)
Definition: ip.h:149
u_char last_recv
Definition: vj.h:135
u_char compressSlot
Definition: vj.h:139
void * payload
Definition: pbuf.h:84
#define LWIP_MEM_ALIGN(addr)
Definition: mem.h:116
POINT cp
Definition: magnifier.c:59
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip.h:163
#define IPH_PROTO_SET(hdr, proto)
Definition: ip.h:162
#define NEW_I
Definition: vj.h:85
#define htons(x)
Definition: module.h:213
#define TYPE_UNCOMPRESSED_TCP
Definition: vj.h:79
UCHAR u_char
Definition: types.h:80
u_short flags
Definition: vj.h:137
#define memset(x, y, z)
Definition: compat.h:39
#define SPECIAL_D
Definition: vj.h:93
#define IPH_LEN_SET(hdr, len)
Definition: ip.h:158
#define NEW_U
Definition: vj.h:89
#define LOG_INFO
Definition: syslog.h:51
int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp)
signed short s16_t
Definition: cc.h:29
#define ntohl(x)
Definition: module.h:203