32 #if PPP_SUPPORT && VJ_SUPPORT && LWIP_TCP 42 #define INCR(counter) ++comp->stats.counter 48 vj_compress_init(
struct vjcompress *comp)
51 struct cstate *tstate = comp->tstate;
54 memset((
char *)comp, 0,
sizeof(*comp));
56 comp->maxSlotIndex = MAX_SLOTS - 1;
57 comp->compressSlot = 0;
58 for (i = MAX_SLOTS - 1; i > 0; --i) {
60 tstate[i].cs_next = &tstate[i - 1];
62 tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
64 comp->last_cs = &tstate[0];
65 comp->last_recv = 255;
66 comp->last_xmit = 255;
67 comp->flags = VJF_TOSS;
76 if ((u16_t)(n) >= 256) { \ 79 cp[0] = (u8_t)((n) >> 8); \ 85 #define ENCODEZ(n) { \ 86 if ((u16_t)(n) >= 256 || (u16_t)(n) == 0) { \ 89 cp[0] = (u8_t)((n) >> 8); \ 96 #define DECODEL(f) { \ 98 u32_t tmp_ = ntohl(f) + ((cp[1] << 8) | cp[2]); \ 102 u32_t tmp_ = ntohl(f) + (u32_t)*cp++; \ 107 #define DECODES(f) { \ 109 u16_t tmp_ = ntohs(f) + (((u16_t)cp[1] << 8) | cp[2]); \ 113 u16_t tmp_ = ntohs(f) + (u16_t)*cp++; \ 118 #define DECODEU(f) { \ 120 (f) = htons(((u16_t)cp[1] << 8) | cp[2]); \ 123 (f) = htons((u16_t)*cp++); \ 135 vj_compress_tcp(
struct vjcompress *comp,
struct pbuf **pb)
137 struct pbuf *np = *pb;
138 struct ip_hdr *ip = (
struct ip_hdr *)np->
payload;
139 struct cstate *cs = comp->last_cs->cs_next;
140 u16_t ilen = IPH_HL(ip);
144 u16_t deltaS, deltaA = 0;
165 th = (
struct tcp_hdr *)&((
u32_t*)ip)[ilen];
166 if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) {
171 hlen = ilen + TCPH_HDRLEN(th);
173 if (np->
len < hlen) {
174 PPPDEBUG(LOG_INFO, (
"vj_compress_tcp: header len %d spans buffers\n", hlen));
191 ip = (
struct ip_hdr *)np->
payload;
201 if (!ip4_addr_cmp(&ip->src, &cs->cs_ip.src)
202 || !ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest)
203 || *(
u32_t*)th != ((
u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
217 struct cstate *lastcs = comp->last_cs;
220 lcs = cs; cs = cs->cs_next;
222 if (ip4_addr_cmp(&ip->src, &cs->cs_ip.src)
223 && ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest)
224 && *(
u32_t*)th == ((
u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
227 }
while (cs != lastcs);
248 lcs->cs_next = cs->cs_next;
249 cs->cs_next = lastcs->cs_next;
250 lastcs->cs_next = cs;
254 oth = (
struct tcp_hdr *)&((
u32_t*)&cs->cs_ip)[ilen];
268 if (((
u16_t*)ip)[0] != ((
u16_t*)&cs->cs_ip)[0]
271 || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth)
272 || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2))
273 || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) {
283 if (TCPH_FLAGS(th) & TCP_URG) {
284 deltaS =
ntohs(th->urgp);
287 }
else if (th->urgp != oth->urgp) {
300 if ((deltaL =
ntohl(th->ackno) -
ntohl(oth->ackno)) != 0) {
301 if (deltaL > 0xffff) {
304 deltaA = (
u16_t)deltaL;
309 if ((deltaL =
ntohl(th->seqno) -
ntohl(oth->seqno)) != 0) {
310 if (deltaL > 0xffff) {
313 deltaS = (
u16_t)deltaL;
328 if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) &&
329 ntohs(IPH_LEN(&cs->cs_ip)) == hlen) {
344 if (deltaS == deltaA && deltaS ==
ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
352 if (deltaS ==
ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
367 if (TCPH_FLAGS(th) & TCP_PSH) {
368 changes |= TCP_PUSH_BIT;
374 deltaA =
ntohs(th->chksum);
375 MEMCPY(&cs->cs_ip, ip, hlen);
386 deltaS = (
u16_t)(cp - new_seq);
387 if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
388 comp->last_xmit = cs->cs_id;
395 *cp++ = (
u8_t)(changes | NEW_C);
404 *cp++ = (
u8_t)changes;
406 *cp++ = (
u8_t)(deltaA >> 8);
407 *cp++ = (
u8_t)deltaA;
408 MEMCPY(cp, new_seq, deltaS);
409 INCR(vjs_compressed);
410 return (TYPE_COMPRESSED_TCP);
418 MEMCPY(&cs->cs_ip, ip, hlen);
419 IPH_PROTO_SET(ip, cs->cs_id);
420 comp->last_xmit = cs->cs_id;
421 return (TYPE_UNCOMPRESSED_TCP);
428 vj_uncompress_err(
struct vjcompress *comp)
430 comp->flags |= VJF_TOSS;
439 vj_uncompress_uncomp(
struct pbuf *nb,
struct vjcompress *comp)
445 ip = (
struct ip_hdr *)nb->
payload;
446 hlen = IPH_HL(ip) << 2;
447 if (IPH_PROTO(ip) >= MAX_SLOTS
448 || hlen +
sizeof(
struct tcp_hdr) > nb->len
449 || (hlen += TCPH_HDRLEN(((
struct tcp_hdr *)&((
char *)ip)[hlen])) << 2)
452 PPPDEBUG(LOG_INFO, (
"vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n",
453 IPH_PROTO(ip), hlen, nb->
len));
454 comp->flags |= VJF_TOSS;
458 cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)];
459 comp->flags &=~ VJF_TOSS;
461 MEMCPY(&cs->cs_ip, ip, hlen);
462 cs->cs_hlen = (
u16_t)hlen;
463 INCR(vjs_uncompressedin);
476 vj_uncompress_tcp(
struct pbuf **nb,
struct vjcompress *comp)
482 struct pbuf *n0 = *nb;
484 u32_t vjlen, hlen, changes;
486 INCR(vjs_compressedin);
489 if (changes & NEW_C) {
494 if (*cp >= MAX_SLOTS) {
495 PPPDEBUG(LOG_INFO, (
"vj_uncompress_tcp: bad cid=%d\n", *cp));
499 comp->flags &=~ VJF_TOSS;
500 comp->last_recv = *cp++;
507 if (comp->flags & VJF_TOSS) {
508 PPPDEBUG(LOG_INFO, (
"vj_uncompress_tcp: tossing\n"));
513 cs = &comp->rstate[comp->last_recv];
514 hlen = IPH_HL(&cs->cs_ip) << 2;
515 th = (
struct tcp_hdr *)&((
u8_t*)&cs->cs_ip)[hlen];
516 th->chksum =
htons((*cp << 8) | cp[1]);
518 if (changes & TCP_PUSH_BIT) {
519 TCPH_SET_FLAG(th, TCP_PSH);
521 TCPH_UNSET_FLAG(th, TCP_PSH);
524 switch (changes & SPECIALS_MASK) {
527 u32_t i =
ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
529 tmp =
ntohl(th->ackno) + i;
530 th->ackno =
htonl(tmp);
531 tmp =
ntohl(th->seqno) + i;
532 th->seqno =
htonl(tmp);
538 tmp =
ntohl(th->seqno) +
ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
539 th->seqno =
htonl(tmp);
543 if (changes & NEW_U) {
544 TCPH_SET_FLAG(th, TCP_URG);
547 TCPH_UNSET_FLAG(th, TCP_URG);
549 if (changes & NEW_W) {
552 if (changes & NEW_A) {
555 if (changes & NEW_S) {
560 if (changes & NEW_I) {
561 DECODES(cs->cs_ip._id);
563 IPH_ID_SET(&cs->cs_ip,
ntohs(IPH_ID(&cs->cs_ip)) + 1);
564 IPH_ID_SET(&cs->cs_ip,
htons(IPH_ID(&cs->cs_ip)));
573 if (n0->
len < vjlen) {
578 PPPDEBUG(LOG_INFO, (
"vj_uncompress_tcp: head buffer %d too short %d\n",
583 #if BYTE_ORDER == LITTLE_ENDIAN 584 tmp = n0->
tot_len - vjlen + cs->cs_hlen;
587 IPH_LEN_SET(&cs->cs_ip,
htons(n0->
tot_len - vjlen + cs->cs_hlen));
591 bp = (
u16_t*) &cs->cs_ip;
592 IPH_CHKSUM_SET(&cs->cs_ip, 0);
593 for (tmp = 0; hlen > 0; hlen -= 2) {
596 tmp = (tmp & 0xffff) + (tmp >> 16);
597 tmp = (tmp & 0xffff) + (tmp >> 16);
598 IPH_CHKSUM_SET(&cs->cs_ip, (
u16_t)(~tmp));
621 PPPDEBUG(LOG_WARNING, (
"vj_uncompress_tcp: realign failed\n"));
632 for(q = np; q !=
NULL; q = q->
next) {
651 PPPDEBUG(LOG_WARNING, (
"vj_uncompress_tcp: prepend failed\n"));
665 comp->
flags |= VJF_TOSS;
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
#define MEMCPY(dst, src, len)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define PBUF_POOL_BUFSIZE
u8_t pbuf_free(struct pbuf *p)
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
void pbuf_chain(struct pbuf *h, struct pbuf *t)
#define LWIP_ASSERT(message, assertion)
struct pbuf * pbuf_dechain(struct pbuf *p)
void pbuf_cat(struct pbuf *h, struct pbuf *t)
#define LWIP_MEM_ALIGN(addr)