1 /* $Id$ */
2 /****************************************************************************
3  *
4  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
5  * Copyright (C) 2005-2013 Sourcefire, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License Version 2 as
9  * published by the Free Software Foundation.  You may not use, modify or
10  * distribute this program under any other version of the GNU General
11  * Public License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  *
22  ****************************************************************************/
23 
24 // @file    encode.c
25 // @author  Russ Combs <rcombs@sourcefire.com>
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include <string.h>
32 #ifdef HAVE_DUMBNET_H
33 #include <dumbnet.h>
34 #else
35 #include <dnet.h>
36 #endif
37 
38 #include "assert.h"
39 #include "encode.h"
40 #include "sfdaq.h"
41 #include "sf_iph.h"
42 #include "snort.h"
43 #include "session_api.h"
44 #include "stream_api.h"
45 #include "checksum.h"
46 
47 #ifdef MPLS
48 #include "preprocessors/Session/session_common.h"
49 #endif
50 
51 #define GET_IP_HDR_LEN(h) (((h)->ip_verhl & 0x0f) << 2)
52 #define GET_TCP_HDR_LEN(h) (((h)->th_offx2 & 0xf0) >> 2)
53 #define SET_TCP_HDR_LEN(h, n) (h)->th_offx2 = ((n << 2) & 0xF0)
54 
55 #define MIN_TTL             64
56 #define MAX_TTL            255
57 
58 #define ICMP_UNREACH_DATA    8  // (per RFC 792)
59 #define IP_ID_COUNT       8192
60 
61 static uint8_t* dst_mac = NULL;
62 Packet* encode_pkt = NULL;
63 uint64_t total_rebuilt_pkts = 0;
64 
65 //-------------------------------------------------------------------------
66 // encoders operate layer by layer:
67 // * base+off is start of packet
68 // * base+end is start of current layer
69 // * base+size-1 is last byte of packet (in) / buffer (out)
70 typedef blob_t Buffer;
71 
72 typedef enum {
73     ENC_OK, ENC_BAD_PROTO, ENC_BAD_OPT, ENC_OVERFLOW
74 } ENC_STATUS;
75 
76 typedef struct {
77     EncodeType type;
78     EncodeFlags flags;
79 
80     uint8_t layer;
81     const Packet* p;
82     uint16_t ip_len;
83     uint8_t* ip_hdr;
84 
85     const uint8_t* payLoad;
86     uint32_t payLen;
87     uint8_t proto;
88 
89 } EncState;
90 
91 #define FORWARD(e) (e->flags & ENC_FLAG_FWD)
92 #define REVERSE(f) (!(f & ENC_FLAG_FWD))
93 
94 // PKT_MAX is sized to ensure that any reassembled packet
95 // can accommodate a full datagram at innermost layer
96 #define PKT_MAX (ETHERNET_HEADER_LEN + VLAN_HEADER_LEN + ETHERNET_MTU + IP_MAXPACKET)
97 
98 // all layer encoders look like this:
99 typedef ENC_STATUS (*Encoder)(EncState*, Buffer* in, Buffer* out);
100 typedef ENC_STATUS (*Updater)(Packet*, Layer*, uint32_t* len);
101 typedef void (*Formatter)(EncodeFlags, const Packet* p, Packet* c, Layer*);
102 // TBD implement other encoder functions
103 
104 typedef struct {
105     Encoder fencode;
106     Updater fupdate;
107     Formatter fformat;
108 } EncoderFunctions;
109 
110 // forward declaration; definition at end of file
111 static EncoderFunctions encoders[PROTO_MAX];
112 
113 static void IpId_Init();
114 static void IpId_Term();
115 
116 static const uint8_t* Encode_Packet(
117     EncState* enc, const Packet* p, uint32_t* len);
118 
119 static ENC_STATUS UN6_ICMP6_Encode(EncState*, Buffer*, Buffer*);
120 static ENC_STATUS UN6_UDP_Encode(EncState*, Buffer*, Buffer*);
121 
122 
123 //-------------------------------------------------------------------------
124 
NextEncoder(EncState * enc)125 static inline PROTO_ID NextEncoder (EncState* enc)
126 {
127     if ( enc->layer < enc->p->next_layer )
128     {
129         PROTO_ID next = enc->p->layers[enc->layer++].proto;
130         if ( next < PROTO_MAX )
131         {
132             if ( encoders[next].fencode ) return next;
133         }
134     }
135     return PROTO_MAX;
136 }
137 
138 //-------------------------------------------------------------------------
139 // basic setup stuff
140 //-------------------------------------------------------------------------
141 
Encode_Init(void)142 void Encode_Init (void)
143 {
144     IpId_Init();
145 }
146 
Encode_Term(void)147 void Encode_Term (void)
148 {
149     IpId_Term();
150 }
151 
152 //-------------------------------------------------------------------------
153 // encoders:
154 // - raw pkt data only, no need for Packet stuff except to facilitate
155 //   encoding
156 // - don't include original options
157 // - inner layer differs from original (eg tcp data segment becomes rst)
158 // - must ensure proper ttl/hop limit for reverse direction
159 // - sparc twiddle must be factored in packet start for transmission
160 //
161 // iterate over decoded layers and encode the response packet.  actually
162 // make nested calls.  on the way in we setup invariant stuff and as we
163 // unwind the stack we finish up encoding in a more normal fashion (now
164 // the outer layer knows the length of the inner layer, etc.).
165 //
166 // when multiple responses are sent, both forwards and backwards directions,
167 // or multiple ICMP types (unreachable port, host, net), it may be possible
168 // to reuse the 1st encoding and just tweak it.  optimization for later
169 // consideration.
170 
171 // pci is copied from in to out
172 // * addresses / ports are swapped if !fwd
173 // * options, etc. are stripped
174 // * checksums etc. are set
175 // * if next layer is udp, it is set to icmp unreachable w/udp
176 // * if next layer is tcp, it becomes a tcp rst or tcp fin w/opt data
177 
178 //-------------------------------------------------------------------------
179 
Encode_Reject(EncodeType type,EncodeFlags flags,const Packet * p,uint32_t * len)180 const uint8_t* Encode_Reject(
181     EncodeType type, EncodeFlags flags, const Packet* p, uint32_t* len)
182 {
183     EncState enc;
184 
185     enc.type = type;
186     enc.flags = flags;
187 
188     enc.payLoad = NULL;
189     enc.payLen = 0;
190 
191     enc.ip_hdr = NULL;
192     enc.ip_len = 0;
193     enc.proto = 0;
194 
195     if ( encode_pkt )
196         p = encode_pkt;
197 
198     return Encode_Packet(&enc, p, len);
199 }
200 
Encode_Response(EncodeType type,EncodeFlags flags,const Packet * p,uint32_t * len,const uint8_t * payLoad,uint32_t payLen)201 const uint8_t* Encode_Response(
202     EncodeType type, EncodeFlags flags, const Packet* p, uint32_t* len,
203     const uint8_t* payLoad, uint32_t payLen
204 ) {
205     EncState enc;
206 
207     enc.type = type;
208     enc.flags = flags;
209 
210     enc.payLoad = payLoad;
211     enc.payLen = payLen;
212 
213     enc.ip_hdr = NULL;
214     enc.ip_len = 0;
215     enc.proto = 0;
216 
217     if ( encode_pkt )
218         p = encode_pkt;
219 
220     return Encode_Packet(&enc, p, len);
221 }
222 
223 //-------------------------------------------------------------------------
224 // formatters:
225 // - these packets undergo detection
226 // - need to set Packet stuff except for frag3 which calls grinder
227 // - include original options except for frag3 inner ip
228 // - inner layer header is very similar but payload differs
229 // - original ttl is always used
230 //-------------------------------------------------------------------------
231 #ifdef HAVE_DAQ_ADDRESS_SPACE_ID
Encode_Format_With_DAQ_Info(EncodeFlags f,const Packet * p,Packet * c,PseudoPacketType type,const DAQ_PktHdr_t * phdr,uint32_t opaque)232 int Encode_Format_With_DAQ_Info (
233     EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type,
234     const DAQ_PktHdr_t* phdr, uint32_t opaque)
235 
236 #elif defined(HAVE_DAQ_ACQUIRE_WITH_META)
237 int Encode_Format_With_DAQ_Info (
238     EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type,
239     uint32_t opaque)
240 #else
241 int Encode_Format (EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type)
242 #endif
243 {
244     DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)c->pkth;
245     uint8_t* pkt = (uint8_t*)c->pkt;
246 
247     int i, next_layer = p->next_layer;
248     Layer* lyr;
249     size_t len;
250 
251     if ( next_layer < 1 ) return -1;
252 
253     memset(c, 0, PKT_ZERO_LEN);
254     c->raw_ip6h = NULL;
255 
256     c->pkth = pkth;
257     c->pkt = pkt;
258 
259 #ifdef HAVE_DAQ_ADDRESS_SPACE_ID
260     pkth->ingress_index = phdr->ingress_index;
261     pkth->ingress_group = phdr->ingress_group;
262     pkth->egress_index = phdr->egress_index;
263     pkth->egress_group = phdr->egress_group;
264     pkth->flags = phdr->flags & (~DAQ_PKT_FLAG_HW_TCP_CS_GOOD);
265 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
266     pkth->address_space_id_src = phdr->address_space_id_src;
267     pkth->address_space_id_dst = phdr->address_space_id_dst;
268 #else
269     pkth->address_space_id = phdr->address_space_id;
270 #endif
271 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID) && defined(DAQ_VERSION) && DAQ_VERSION > 10
272     pkth->carrier_id = phdr->carrier_id;
273 #endif
274     pkth->opaque = opaque;
275     if( type == PSEUDO_PKT_TCP || type == PSEUDO_PKT_IP )
276         pkth->priv_ptr = phdr->priv_ptr;
277 #if defined(DAQ_VERSION) && DAQ_VERSION > 8
278     pkth->proto = phdr->proto;
279 #endif
280 #ifdef HAVE_DAQ_FLOW_ID
281     pkth->flow_id = phdr->flow_id;
282 #endif
283 #elif defined(HAVE_DAQ_ACQUIRE_WITH_META)
284     pkth->opaque = opaque;
285 #endif
286 #ifdef HAVE_DAQ_REAL_ADDRESSES
287     if (pkth->flags & DAQ_PKT_FLAG_REAL_ADDRESSES)
288     {
289         pkth->n_real_sPort = phdr->n_real_sPort;
290         pkth->n_real_dPort = phdr->n_real_dPort;
291         pkth->real_sIP = phdr->real_sIP;
292         pkth->real_dIP = phdr->real_dIP;
293     }
294 #endif
295 
296     if ( f & ENC_FLAG_NET )
297     {
298         for ( i = next_layer-1; i >= 0; i-- )
299             if ( p->layers[i].proto == PROTO_IP4
300               || p->layers[i].proto == PROTO_IP6
301             )
302                 break;
303          if ( i < next_layer ) next_layer = i + 1;
304     }
305     // copy raw packet data to clone
306     lyr = (Layer*)p->layers + next_layer - 1;
307     len = lyr->start - p->pkt + lyr->length;
308 
309     memcpy((void*)c->pkt, p->pkt, len);
310 
311     // set up layers
312     for ( i = 0; i < next_layer; i++ )
313     {
314         const uint8_t* b = c->pkt + (p->layers[i].start - p->pkt);
315         lyr = c->layers + i;
316 
317         lyr->proto = p->layers[i].proto;
318         lyr->length = p->layers[i].length;
319         lyr->start = (uint8_t*)b;
320 
321         if ( lyr->proto < PROTO_MAX )
322             encoders[lyr->proto].fformat(f, p, c, lyr);
323 
324 #ifdef DEBUG
325         else
326             FatalError("Encode_New() => unsupported proto = %d\n",
327                 lyr->proto);
328 #endif
329     }
330     c->next_layer = next_layer;
331 
332     // setup payload info
333     c->data = lyr->start + lyr->length;
334     len = c->data - c->pkt;
335     assert(len < PKT_MAX - IP_MAXPACKET);
336     c->max_dsize = IP_MAXPACKET - len;
337 
338     c->proto_bits = p->proto_bits;
339     c->packet_flags |= PKT_PSEUDO;
340     c->pseudo_type = type;
341     UpdateRebuiltPktCount();
342 
343     switch ( type )
344     {
345         case PSEUDO_PKT_SMB_SEG:
346         case PSEUDO_PKT_DCE_SEG:
347         case PSEUDO_PKT_DCE_FRAG:
348         case PSEUDO_PKT_SMB_TRANS:
349             c->packet_flags |= PKT_REASSEMBLED_OLD;
350             break;
351         default:
352             break;
353     }
354 
355     // setup pkt capture header
356     pkth->caplen = pkth->pktlen = len;
357     pkth->ts = p->pkth->ts;
358 
359     // cooked packet gets same policy as raw
360     c->configPolicyId = p->configPolicyId;
361 
362     if ( !c->max_dsize )
363         return -1;
364 
365     return 0;
366 }
367 
368 //-------------------------------------------------------------------------
369 // formatters:
370 // - these packets undergo detection
371 // - need to set Packet stuff except for frag3 which calls grinder
372 // - include original options except for frag3 inner ip
373 // - inner layer header is very similar but payload differs
374 // - original ttl is always used
375 //-------------------------------------------------------------------------
376 
377 #ifdef HAVE_DAQ_ADDRESS_SPACE_ID
Encode_Format(EncodeFlags f,const Packet * p,Packet * c,PseudoPacketType type)378 int Encode_Format (EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type)
379 {
380     return Encode_Format_With_DAQ_Info(f, p, c, type, p->pkth, p->pkth->opaque);
381 }
382 #elif defined(HAVE_DAQ_ACQUIRE_WITH_META)
Encode_Format(EncodeFlags f,const Packet * p,Packet * c,PseudoPacketType type)383 int Encode_Format (EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type)
384 {
385     return Encode_Format_With_DAQ_Info(f, p, c, type, p->pkth->opaque);
386 }
387 #endif
388 
389 //-------------------------------------------------------------------------
390 // updaters:  these functions set length and checksum fields, only needed
391 // when a packet is modified.  some packets only have replacements so only
392 // the checksums need to be updated.  we always set the length rather than
393 // checking each time if needed.
394 //-------------------------------------------------------------------------
395 
Encode_Update(Packet * p)396 void Encode_Update (Packet* p)
397 {
398     int i;
399     uint32_t len = 0;
400     DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)p->pkth;
401 
402     p->actual_ip_len = 0;
403 
404     for ( i = p->next_layer - 1; i >= 0; i-- )
405     {
406         Layer* lyr = p->layers + i;
407         encoders[lyr->proto].fupdate(p, lyr, &len);
408     }
409     // see IP6_Update() for an explanation of this ...
410     if ( !(p->packet_flags & PKT_MODIFIED)
411 #ifdef NORMALIZER
412         || (p->packet_flags & PKT_RESIZED)
413 #endif
414     )
415         pkth->caplen = pkth->pktlen = len;
416 
417     p->packet_flags &= ~PKT_LOGGED;
418 }
419 
420 //-------------------------------------------------------------------------
421 // internal packet support
422 //-------------------------------------------------------------------------
423 
Encode_New()424 Packet* Encode_New ()
425 {
426     Packet* p = SnortAlloc(sizeof(*p));
427     uint8_t* b = SnortAlloc(sizeof(*p->pkth) + PKT_MAX + SPARC_TWIDDLE);
428     IP6Option* ip6_extensions = SnortAlloc(sizeof(IP6Option) * ScMaxIP6Extensions());
429 
430     if ( !p || !b || !ip6_extensions )
431         FatalError("Encode_New() => Failed to allocate packet\n");
432 
433     p->pkth = (void*)b;
434     b += sizeof(*p->pkth);
435     b += SPARC_TWIDDLE;
436     p->pkt = b;
437     p->ip6_extensions = ip6_extensions;
438     return p;
439 }
440 
Encode_Delete(Packet * p)441 void Encode_Delete (Packet* p)
442 {
443     free((void*)p->pkth);  // cast away const!
444     free(p->ip6_extensions);
445     free(p);
446 }
447 
448 /* Set the destination MAC address*/
Encode_SetDstMAC(uint8_t * mac)449 void Encode_SetDstMAC(uint8_t *mac)
450 {
451    dst_mac = mac;
452 }
453 
454 //-------------------------------------------------------------------------
455 // private implementation stuff
456 //-------------------------------------------------------------------------
457 
458 static uint8_t s_pkt[PKT_MAX];
459 
Encode_Packet(EncState * enc,const Packet * p,uint32_t * len)460 static const uint8_t* Encode_Packet(
461     EncState* enc, const Packet* p, uint32_t* len)
462 {
463     Buffer ibuf, obuf;
464     ENC_STATUS status = ENC_BAD_PROTO;
465     PROTO_ID next;
466 
467     ibuf.base = (uint8_t*)p->pkt;
468     ibuf.off = ibuf.end = 0;
469     ibuf.size = p->pkth->caplen;
470 
471     obuf.base = s_pkt;
472     obuf.off = obuf.end = 0;
473     obuf.size = sizeof(s_pkt);
474 
475     enc->layer = 0;
476     enc->p = p;
477 
478     next = NextEncoder(enc);
479 
480     if ( next < PROTO_MAX )
481     {
482         Encoder e = encoders[next].fencode;
483         status = (*e)(enc, &ibuf, &obuf);
484     }
485     if ( status != ENC_OK || enc->layer != p->next_layer )
486     {
487         *len = 0;
488         return NULL;
489     }
490     *len = (uint32_t)obuf.end;
491     return obuf.base + obuf.off;
492 }
493 
494 //-------------------------------------------------------------------------
495 // ip id considerations:
496 //
497 // we use dnet's rand services to generate a vector of random 16-bit values and
498 // iterate over the vector as IDs are assigned.  when we wrap to the beginning,
499 // the vector is randomly reordered.
500 //-------------------------------------------------------------------------
501 
502 static rand_t* s_rand = NULL;
503 static uint16_t s_id_index = 0;
504 static uint16_t s_id_pool[IP_ID_COUNT];
505 
IpId_Init(void)506 static void IpId_Init (void)
507 {
508     if ( s_rand ) rand_close(s_rand);
509 
510     s_rand = rand_open();
511 
512     if ( !s_rand )
513         FatalError("encode::IpId_Init: rand_open() failed.\n");
514 
515     rand_get(s_rand, s_id_pool, sizeof(s_id_pool));
516 }
517 
IpId_Term(void)518 static void IpId_Term (void)
519 {
520     if ( s_rand ) rand_close(s_rand);
521     s_rand = NULL;
522 }
523 
IpId_Next()524 static inline uint16_t IpId_Next ()
525 {
526 #ifdef REG_TEST
527     uint16_t id = htons(s_id_index + 1);
528 #else
529     uint16_t id = s_id_pool[s_id_index];
530 #endif
531     s_id_index = (s_id_index + 1) % IP_ID_COUNT;
532 
533     if ( !s_id_index )
534         rand_shuffle(s_rand, s_id_pool, sizeof(s_id_pool), 1);
535 
536     return id;
537 }
538 
539 //-------------------------------------------------------------------------
540 // ttl considerations:
541 //
542 // we try to use the TTL captured for the session by the stream preprocessor
543 // when the session started.  if that is not available, we use the current
544 // TTL for forward packets and use (maximum - current) TTL for reverse
545 // packets.
546 //
547 // the reason we don't just force ttl to 255 (max) is to make it look a
548 // little more authentic.
549 //
550 // for reference, flexresp used a const rand >= 64 in both directions (the
551 // number was determined at startup and never changed); flexresp2 used the
552 // next higher multiple of 64 in both directions; and react used a const
553 // 64 in both directions.
554 //
555 // note that the ip6 hop limit field is entirely equivalent to the ip4 TTL.
556 // hop limit is in fact a more accurrate name for the actual usage of this
557 // field.
558 //-------------------------------------------------------------------------
559 
GetTTL(const EncState * enc)560 static inline uint8_t GetTTL (const EncState* enc)
561 {
562     char dir;
563     uint8_t ttl;
564     int outer = !enc->ip_hdr;
565 
566     if ( !enc->p->ssnptr )
567         return 0;
568 
569     if ( enc->p->packet_flags & PKT_FROM_CLIENT )
570         dir = FORWARD(enc) ? SSN_DIR_FROM_CLIENT : SSN_DIR_FROM_SERVER;
571     else
572         dir = FORWARD(enc) ? SSN_DIR_FROM_SERVER : SSN_DIR_FROM_CLIENT;
573 
574     // outermost ip is considered to be outer here,
575     // even if it is the only ip layer ...
576     ttl = session_api->get_session_ttl(enc->p->ssnptr, dir, outer);
577 
578     // so if we don't get outer, we use inner
579     if ( 0 == ttl && outer )
580         ttl = session_api->get_session_ttl(enc->p->ssnptr, dir, 0);
581 
582     return ttl;
583 }
584 
FwdTTL(const EncState * enc,uint8_t ttl)585 static inline uint8_t FwdTTL (const EncState* enc, uint8_t ttl)
586 {
587     uint8_t new_ttl = GetTTL(enc);
588     if ( !new_ttl )
589         new_ttl = ttl;
590     return new_ttl;
591 }
592 
RevTTL(const EncState * enc,uint8_t ttl)593 static inline uint8_t RevTTL (const EncState* enc, uint8_t ttl)
594 {
595     uint8_t new_ttl = GetTTL(enc);
596     if ( !new_ttl )
597         new_ttl = ( MAX_TTL - ttl );
598     if ( new_ttl < MIN_TTL )
599         new_ttl = MIN_TTL;
600     return new_ttl;
601 }
602 
603 //-------------------------------------------------------------------------
604 // the if in UPDATE_BOUND can be defined out after testing because:
605 // 1. the packet was already decoded in decode.c so is structurally sound; and
606 // 2. encode takes at most the same space as decode.
607 #define UPDATE_BOUND(buf, n) \
608     buf->end += n; \
609     if ( buf->end > buf->size ) \
610         return ENC_OVERFLOW
611 //-------------------------------------------------------------------------
612 // BUFLEN
613 // Get the buffer length for a given protocol
614 #define BUFF_DIFF(buf, ho) ((uint8_t*)(buf->base+buf->end)-(uint8_t*)ho)
615 
616 //-------------------------------------------------------------------------
617 // ethernet
618 //-------------------------------------------------------------------------
619 
Eth_Encode(EncState * enc,Buffer * in,Buffer * out)620 static ENC_STATUS Eth_Encode (EncState* enc, Buffer* in, Buffer* out)
621 {
622     // not raw ip -> encode layer 2
623     int raw = ( enc->flags & ENC_FLAG_RAW );
624 
625     EtherHdr* hi = (EtherHdr*)enc->p->layers[enc->layer-1].start;
626     PROTO_ID next = NextEncoder(enc);
627 
628     // if not raw ip AND out buf is empty
629     if ( !raw && (out->off == out->end) )
630     {
631         // for alignment
632         out->off = out->end = SPARC_TWIDDLE;
633     }
634     // if not raw ip OR out buf is not empty
635     if ( !raw || (out->off != out->end) )
636     {
637         // we get here for outer-most layer when not raw ip
638         // we also get here for any encapsulated ethernet layer.
639         EtherHdr* ho = (EtherHdr*)(out->base + out->end);
640         UPDATE_BOUND(out, sizeof(*ho));
641 
642         ho->ether_type = hi->ether_type;
643         if ( FORWARD(enc) )
644         {
645             memcpy(ho->ether_src, hi->ether_src, sizeof(ho->ether_src));
646             /*If user configured remote MAC address, use it*/
647             if (NULL != dst_mac)
648                 memcpy(ho->ether_dst, dst_mac, sizeof(ho->ether_dst));
649             else
650                 memcpy(ho->ether_dst, hi->ether_dst, sizeof(ho->ether_dst));
651         }
652         else
653         {
654             memcpy(ho->ether_src, hi->ether_dst, sizeof(ho->ether_src));
655             /*If user configured remote MAC address, use it*/
656             if (NULL != dst_mac)
657                 memcpy(ho->ether_dst, dst_mac, sizeof(ho->ether_dst));
658             else
659                 memcpy(ho->ether_dst, hi->ether_src, sizeof(ho->ether_dst));
660         }
661     }
662     if ( next < PROTO_MAX )
663         return encoders[next].fencode(enc, in, out);
664 
665     return ENC_OK;
666 }
667 
Eth_Update(Packet * p,Layer * lyr,uint32_t * len)668 static ENC_STATUS Eth_Update (Packet* p, Layer* lyr, uint32_t* len)
669 {
670     *len += lyr->length;
671     return ENC_OK;
672 }
673 
Eth_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)674 static void Eth_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
675 {
676     EtherHdr* ch = (EtherHdr*)lyr->start;
677     c->eh = ch;
678 
679     if ( REVERSE(f) )
680     {
681         int i = lyr - c->layers;
682         EtherHdr* ph = (EtherHdr*)p->layers[i].start;
683 
684         memcpy(ch->ether_dst, ph->ether_src, sizeof(ch->ether_dst));
685         memcpy(ch->ether_src, ph->ether_dst, sizeof(ch->ether_src));
686     }
687 }
688 
689 //-------------------------------------------------------------------------
690 // FabricPath
691 //-------------------------------------------------------------------------
692 
FPath_Encode(EncState * enc,Buffer * in,Buffer * out)693 static ENC_STATUS FPath_Encode (EncState* enc, Buffer* in, Buffer* out)
694 {
695     // not raw ip -> encode layer 2
696     int raw = ( enc->flags & ENC_FLAG_RAW );
697 
698     FPathHdr* hi = (FPathHdr*)enc->p->layers[enc->layer-1].start;
699     PROTO_ID next = NextEncoder(enc);
700 
701     // if not raw ip AND out buf is empty
702     if ( !raw && (out->off == out->end) )
703     {
704         // for alignment
705         out->off = out->end = 0;
706     }
707     // if not raw ip OR out buf is not empty
708     if ( !raw || (out->off != out->end) )
709     {
710         // we get here for outer-most layer when not raw ip
711         // we also get here for any encapsulated ethernet layer.
712         FPathHdr* ho = (FPathHdr*)(out->base + out->end);
713         UPDATE_BOUND(out, sizeof(*ho));
714 
715         ho->fpath_type = hi->fpath_type;
716         if ( FORWARD(enc) )
717         {
718             memcpy(ho->fpath_src, hi->fpath_src, sizeof(ho->fpath_src));
719             memcpy(ho->fpath_dst, hi->fpath_dst, sizeof(ho->fpath_dst));
720         }
721         else
722         {
723             memcpy(ho->fpath_src, hi->fpath_dst, sizeof(ho->fpath_src));
724             memcpy(ho->fpath_dst, hi->fpath_src, sizeof(ho->fpath_dst));
725         }
726     }
727     if ( next < PROTO_MAX )
728         return encoders[next].fencode(enc, in, out);
729 
730     return ENC_OK;
731 }
732 
FPath_Update(Packet * p,Layer * lyr,uint32_t * len)733 static ENC_STATUS FPath_Update (Packet* p, Layer* lyr, uint32_t* len)
734 {
735     *len += lyr->length;
736     return ENC_OK;
737 }
738 
FPath_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)739 static void FPath_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
740 {
741     FPathHdr* ch = (FPathHdr*)lyr->start;
742 
743     if ( REVERSE(f) )
744     {
745         int i = lyr - c->layers;
746         FPathHdr* ph = (FPathHdr*)p->layers[i].start;
747 
748         memcpy(ch->fpath_dst, ph->fpath_src, sizeof(ch->fpath_dst));
749         memcpy(ch->fpath_src, ph->fpath_dst, sizeof(ch->fpath_src));
750     }
751 }
752 
753 //-------------------------------------------------------------------------
754 // VLAN
755 //-------------------------------------------------------------------------
756 
VLAN_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)757 static void VLAN_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
758 {
759 #ifdef HAVE_DAQ_REAL_ADDRESSES
760       if (!(p->pkth->flags & DAQ_PKT_FLAG_IGNORE_VLAN))
761 #endif
762     c->vh = (VlanTagHdr*)lyr->start;
763 }
764 
765 //-------------------------------------------------------------------------
766 // GRE
767 //-------------------------------------------------------------------------
768 #ifdef GRE
GRE_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)769 static void GRE_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
770 {
771     c->greh = (GREHdr*)lyr->start;
772 }
773 #endif
774 
775 //-------------------------------------------------------------------------
776 // IP4
777 //-------------------------------------------------------------------------
778 
IP4_Encode(EncState * enc,Buffer * in,Buffer * out)779 static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out)
780 {
781     int len;
782     uint32_t start = out->end;
783 
784     IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start;
785     IPHdr* ho = (IPHdr*)(out->base + out->end);
786     PROTO_ID next = NextEncoder(enc);
787     UPDATE_BOUND(out, sizeof(*ho));
788 
789     /* IPv4 encoded header is hardcoded 20 bytes */
790     ho->ip_verhl = 0x45;
791     ho->ip_off = 0;
792 
793     ho->ip_id = IpId_Next();
794     ho->ip_tos = hi->ip_tos;
795     ho->ip_proto = hi->ip_proto;
796 
797     if ( FORWARD(enc) )
798     {
799         ho->ip_src.s_addr = hi->ip_src.s_addr;
800         ho->ip_dst.s_addr = hi->ip_dst.s_addr;
801 
802         ho->ip_ttl = FwdTTL(enc, hi->ip_ttl);
803     }
804     else
805     {
806         ho->ip_src.s_addr = hi->ip_dst.s_addr;
807         ho->ip_dst.s_addr = hi->ip_src.s_addr;
808 
809         ho->ip_ttl = RevTTL(enc, hi->ip_ttl);
810     }
811 
812     enc->ip_hdr = (uint8_t*)hi;
813     enc->ip_len = IP_HLEN(hi) << 2;
814 
815     if ( next < PROTO_MAX )
816     {
817         ENC_STATUS err = encoders[next].fencode(enc, in, out);
818         if ( ENC_OK != err ) return err;
819     }
820     if ( enc->proto )
821     {
822         ho->ip_proto = enc->proto;
823         enc->proto = 0;
824     }
825 
826     len = out->end - start;
827     ho->ip_len = htons((uint16_t)len);
828 
829     ho->ip_csum = 0;
830 
831     /* IPv4 encoded header is hardcoded 20 bytes, we save some
832      * cycles and use the literal header size for checksum */
833     ho->ip_csum = in_chksum_ip((const uint16_t *)ho, sizeof *ho);
834 
835     return ENC_OK;
836 }
837 
IP4_Update(Packet * p,Layer * lyr,uint32_t * len)838 static ENC_STATUS IP4_Update (Packet* p, Layer* lyr, uint32_t* len)
839 {
840     IPHdr* h = (IPHdr*)(lyr->start);
841     int i = lyr - p->layers;
842 
843     *len += GET_IP_HDR_LEN(h);
844 
845     if ( i + 1 == p->next_layer )
846     {
847         *len += p->dsize;
848     }
849     h->ip_len = htons((uint16_t)*len);
850 
851     if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) )
852     {
853         h->ip_csum = 0;
854         h->ip_csum = in_chksum_ip((const uint16_t *)h, GET_IP_HDR_LEN(h));
855     }
856 
857     return ENC_OK;
858 }
859 
IP4_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)860 static void IP4_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
861 {
862     // TBD handle nested ip layers
863     IPHdr* ch = (IPHdr*)lyr->start;
864     c->iph = ch;
865 
866     if ( REVERSE(f) )
867     {
868         int i = lyr - c->layers;
869         IPHdr* ph = (IPHdr*)p->layers[i].start;
870 
871         ch->ip_src.s_addr = ph->ip_dst.s_addr;
872         ch->ip_dst.s_addr = ph->ip_src.s_addr;
873     }
874     if ( f & ENC_FLAG_DEF )
875     {
876         int i = lyr - c->layers;
877         if ( i + 1 == p->next_layer )
878         {
879             lyr->length = sizeof(*ch);
880             ch->ip_len = htons(lyr->length);
881             SET_IP_HLEN(ch, lyr->length >> 2);
882         }
883     }
884     sfiph_build(c, c->iph, AF_INET);
885 }
886 
887 //-------------------------------------------------------------------------
888 // ICMP
889 // UNR encoder creates ICMP unreachable
890 //-------------------------------------------------------------------------
891 
IcmpCode(EncodeType et)892 static inline int IcmpCode (EncodeType et) {
893     switch ( et ) {
894     case ENC_UNR_NET:  return ICMP_UNREACH_NET;
895     case ENC_UNR_HOST: return ICMP_UNREACH_HOST;
896     case ENC_UNR_PORT: return ICMP_UNREACH_PORT;
897     case ENC_UNR_FW:   return ICMP_UNREACH_FILTER_PROHIB;
898     default: break;
899     }
900     return ICMP_UNREACH_PORT;
901 }
902 
903 typedef struct {
904     uint8_t type;
905     uint8_t code;
906     uint16_t cksum;
907     uint32_t unused;
908 } IcmpHdr;
909 
UN4_Encode(EncState * enc,Buffer * in,Buffer * out)910 static ENC_STATUS UN4_Encode (EncState* enc, Buffer* in, Buffer* out)
911 {
912     uint8_t* p;
913 
914     uint8_t* hi = enc->p->layers[enc->layer-1].start;
915     IcmpHdr* ho = (IcmpHdr*)(out->base + out->end);
916 
917 #ifdef DEBUG
918     if ( enc->type < ENC_UNR_NET )
919         return ENC_BAD_OPT;
920 #endif
921 
922     enc->proto = IPPROTO_ICMP;
923 
924     UPDATE_BOUND(out, sizeof(*ho));
925     ho->type = ICMP_UNREACH;
926     ho->code = IcmpCode(enc->type);
927     ho->cksum = 0;
928     ho->unused = 0;
929 
930     // copy original ip header
931     p = out->base + out->end;
932     UPDATE_BOUND(out, enc->ip_len);
933     memcpy(p, enc->ip_hdr, enc->ip_len);
934 
935     // copy first 8 octets of original ip data (ie udp header)
936     p = out->base + out->end;
937     UPDATE_BOUND(out, ICMP_UNREACH_DATA);
938     memcpy(p, hi, ICMP_UNREACH_DATA);
939 
940     ho->cksum = in_chksum_icmp((uint16_t *)ho, BUFF_DIFF(out, ho));
941 
942     return ENC_OK;
943 }
944 
ICMP4_Update(Packet * p,Layer * lyr,uint32_t * len)945 static ENC_STATUS ICMP4_Update (Packet* p, Layer* lyr, uint32_t* len)
946 {
947     IcmpHdr* h = (IcmpHdr*)(lyr->start);
948 
949     *len += lyr->length + p->dsize;
950 
951 
952     if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) {
953         h->cksum = 0;
954         h->cksum = in_chksum_icmp((uint16_t *)h, *len);
955     }
956 
957     return ENC_OK;
958 }
959 
ICMP4_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)960 static void ICMP4_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
961 {
962     // TBD handle nested icmp4 layers
963     c->icmph = (ICMPHdr*)lyr->start;
964 }
965 
966 //-------------------------------------------------------------------------
967 // UDP
968 //-------------------------------------------------------------------------
969 
UDP_Encode(EncState * enc,Buffer * in,Buffer * out)970 static ENC_STATUS UDP_Encode (EncState* enc, Buffer* in, Buffer* out)
971 {
972     PROTO_ID next = PROTO_MAX;
973 
974     if ( enc->layer < enc->p->next_layer )
975     {
976         next = enc->p->layers[enc->layer].proto;
977     }
978     if ( enc->type == ENC_UDP || ((PROTO_GTP == next) && (encoders[next].fencode)) )
979     {
980         int len;
981         ENC_STATUS err;
982         uint32_t start = out->end;
983 
984         UDPHdr* hi = (UDPHdr*)enc->p->layers[enc->layer-1].start;
985         UDPHdr* ho = (UDPHdr*)(out->base + out->end);
986         UPDATE_BOUND(out, sizeof(*ho));
987 
988         if ( FORWARD(enc) )
989         {
990             ho->uh_sport = hi->uh_sport;
991             ho->uh_dport = hi->uh_dport;
992         }
993         else
994         {
995             ho->uh_sport = hi->uh_dport;
996             ho->uh_dport = hi->uh_sport;
997         }
998 
999         if ( enc->type != ENC_UDP)
1000         {
1001             next = NextEncoder(enc);
1002             if ( next < PROTO_MAX )
1003             {
1004                 err = encoders[next].fencode(enc, in, out);
1005                 if (ENC_OK != err ) return err;
1006             }
1007             len = out->end - start;
1008         }
1009         else
1010         {
1011             uint8_t* pdu = out->base + out->end;
1012             UPDATE_BOUND(out, enc->payLen);
1013             memcpy(pdu, enc->payLoad, enc->payLen);
1014             len = enc->payLen + sizeof(UDPHdr);
1015         }
1016         ho->uh_len = htons((uint16_t)len);
1017 
1018         ho->uh_chk = 0;
1019 
1020         if (IP_VER((IPHdr *)enc->ip_hdr) == 4) {
1021             pseudoheader ps;
1022             ps.sip = ((IPHdr *)enc->ip_hdr)->ip_src.s_addr;
1023             ps.dip = ((IPHdr *)enc->ip_hdr)->ip_dst.s_addr;
1024             ps.zero = 0;
1025             ps.protocol = IPPROTO_UDP;
1026             ps.len = ho->uh_len;
1027             ho->uh_chk = in_chksum_udp(&ps, (uint16_t *)ho, len);
1028         }
1029         else {
1030             pseudoheader6 ps6;
1031             memcpy(ps6.sip, ((IP6RawHdr *)enc->ip_hdr)->ip6_src.s6_addr, sizeof(ps6.sip));
1032             memcpy(ps6.dip, ((IP6RawHdr *)enc->ip_hdr)->ip6_dst.s6_addr, sizeof(ps6.dip));
1033             ps6.zero = 0;
1034             ps6.protocol = IPPROTO_UDP;
1035             ps6.len = ho->uh_len;
1036             ho->uh_chk = in_chksum_udp6(&ps6, (uint16_t *)ho, len);
1037         }
1038 
1039         return ENC_OK;
1040     }
1041     if ( IP_VER((IPHdr*)enc->ip_hdr) == 4 )
1042         return UN4_Encode(enc, in, out);
1043 
1044     return UN6_UDP_Encode(enc, in, out);
1045 }
1046 
UDP_Update(Packet * p,Layer * lyr,uint32_t * len)1047 static ENC_STATUS UDP_Update (Packet* p, Layer* lyr, uint32_t* len)
1048 {
1049     UDPHdr* h = (UDPHdr*)(lyr->start);
1050 
1051     *len += sizeof(*h) + p->dsize;
1052     h->uh_len = htons((uint16_t)*len);
1053 
1054 
1055     if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) {
1056         h->uh_chk = 0;
1057 
1058         if (IS_IP4(p)) {
1059             pseudoheader ps;
1060             ps.sip = ((IPHdr *)(lyr-1)->start)->ip_src.s_addr;
1061             ps.dip = ((IPHdr *)(lyr-1)->start)->ip_dst.s_addr;
1062             ps.zero = 0;
1063             ps.protocol = IPPROTO_UDP;
1064             ps.len = htons((uint16_t)*len);
1065             h->uh_chk = in_chksum_udp(&ps, (uint16_t *)h, *len);
1066         } else {
1067             pseudoheader6 ps6;
1068             for (lyr--; lyr->proto != PROTO_IP6 && lyr != p->layers; lyr--);
1069             if (lyr->proto == PROTO_IP6)
1070             {
1071                 memcpy(ps6.sip, ((IP6RawHdr *)lyr->start)->ip6_src.s6_addr, sizeof(ps6.sip));
1072                 memcpy(ps6.dip, ((IP6RawHdr *)lyr->start)->ip6_dst.s6_addr, sizeof(ps6.dip));
1073                 ps6.zero = 0;
1074                 ps6.protocol = IPPROTO_UDP;
1075                 ps6.len = htons((uint16_t)*len);
1076                 h->uh_chk = in_chksum_udp6(&ps6, (uint16_t *)h, *len);
1077             }
1078         }
1079     }
1080 
1081     return ENC_OK;
1082 }
1083 
UDP_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)1084 static void UDP_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
1085 {
1086     UDPHdr* ch = (UDPHdr*)lyr->start;
1087     c->udph = ch;
1088 
1089     if ( REVERSE(f) )
1090     {
1091         int i = lyr - c->layers;
1092         UDPHdr* ph = (UDPHdr*)p->layers[i].start;
1093 
1094         ch->uh_sport = ph->uh_dport;
1095         ch->uh_dport = ph->uh_sport;
1096     }
1097     c->sp = ntohs(ch->uh_sport);
1098     c->dp = ntohs(ch->uh_dport);
1099 }
1100 
1101 //-------------------------------------------------------------------------
1102 // TCP
1103 // encoder creates TCP RST
1104 // should always try to use acceptable ack since we send RSTs in a
1105 // stateless fashion ... from rfc 793:
1106 //
1107 // In all states except SYN-SENT, all reset (RST) segments are validated
1108 // by checking their SEQ-fields.  A reset is valid if its sequence number
1109 // is in the window.  In the SYN-SENT state (a RST received in response
1110 // to an initial SYN), the RST is acceptable if the ACK field
1111 // acknowledges the SYN.
1112 //-------------------------------------------------------------------------
1113 
TCP_Encode(EncState * enc,Buffer * in,Buffer * out)1114 static ENC_STATUS TCP_Encode (EncState* enc, Buffer* in, Buffer* out)
1115 {
1116     int len, ctl;
1117 
1118     TCPHdr* hi = (TCPHdr*)enc->p->layers[enc->layer-1].start;
1119     TCPHdr* ho = (TCPHdr*)(out->base + out->end);
1120 
1121     UPDATE_BOUND(out, sizeof(*ho));
1122 
1123     len = GET_TCP_HDR_LEN(hi) - sizeof(*hi);
1124     UPDATE_BOUND(in, len);
1125     ctl = (hi->th_flags & TH_SYN) ? 1 : 0;
1126 
1127     if ( FORWARD(enc) )
1128     {
1129         ho->th_sport = hi->th_sport;
1130         ho->th_dport = hi->th_dport;
1131 
1132         // th_seq depends on whether the data passes or drops
1133         if ( DAQ_GetInterfaceMode(enc->p->pkth) != DAQ_MODE_INLINE )
1134             ho->th_seq = htonl(ntohl(hi->th_seq) + enc->p->dsize + ctl);
1135         else
1136             ho->th_seq = hi->th_seq;
1137 
1138         ho->th_ack = hi->th_ack;
1139     }
1140     else
1141     {
1142         ho->th_sport = hi->th_dport;
1143         ho->th_dport = hi->th_sport;
1144 
1145         ho->th_seq = hi->th_ack;
1146         ho->th_ack = htonl(ntohl(hi->th_seq) + enc->p->dsize + ctl);
1147     }
1148 
1149     if ( enc->flags & ENC_FLAG_SEQ )
1150     {
1151         uint32_t seq = ntohl(ho->th_seq);
1152         seq += (enc->flags & ENC_FLAG_VAL);
1153         ho->th_seq = htonl(seq);
1154     }
1155     ho->th_offx2 = 0;
1156     SET_TCP_OFFSET(ho, (TCP_HDR_LEN >> 2));
1157     ho->th_win = ho->th_urp = 0;
1158 
1159     if ( enc->type == ENC_TCP_FIN || enc->type == ENC_TCP_PUSH )
1160     {
1161         if ( enc->payLoad && enc->payLen > 0 )
1162         {
1163             uint8_t* pdu = out->base + out->end;
1164             UPDATE_BOUND(out, enc->payLen);
1165             memcpy(pdu, enc->payLoad, enc->payLen);
1166         }
1167 
1168         ho->th_flags = TH_ACK;
1169         if ( enc->type == ENC_TCP_PUSH )
1170         {
1171             ho->th_flags |= TH_PUSH;
1172             ho->th_win = htons(65535);
1173         }
1174         else
1175         {
1176             ho->th_flags |= TH_FIN;
1177         }
1178     }
1179     else
1180     {
1181         ho->th_flags = TH_RST | TH_ACK;
1182     }
1183 
1184     // in case of ip6 extension headers, this gets next correct
1185     enc->proto = IPPROTO_TCP;
1186 
1187     ho->th_sum = 0;
1188 
1189     if (IP_VER((IPHdr *)enc->ip_hdr) == 4) {
1190         pseudoheader ps;
1191         int len = BUFF_DIFF(out, ho);
1192 
1193         ps.sip = ((IPHdr *)(enc->ip_hdr))->ip_src.s_addr;
1194         ps.dip = ((IPHdr *)(enc->ip_hdr))->ip_dst.s_addr;
1195         ps.zero = 0;
1196         ps.protocol = IPPROTO_TCP;
1197         ps.len = htons((uint16_t)len);
1198         ho->th_sum = in_chksum_tcp(&ps, (uint16_t *)ho, len);
1199     } else {
1200         pseudoheader6 ps6;
1201         int len = BUFF_DIFF(out, ho);
1202 
1203         memcpy(ps6.sip, ((IP6RawHdr *)enc->ip_hdr)->ip6_src.s6_addr, sizeof(ps6.sip));
1204         memcpy(ps6.dip, ((IP6RawHdr *)enc->ip_hdr)->ip6_dst.s6_addr, sizeof(ps6.dip));
1205         ps6.zero = 0;
1206         ps6.protocol = IPPROTO_TCP;
1207         ps6.len = htons((uint16_t)len);
1208         ho->th_sum = in_chksum_tcp6(&ps6, (uint16_t *)ho, len);
1209     }
1210 
1211     return ENC_OK;
1212 }
1213 
TCP_Update(Packet * p,Layer * lyr,uint32_t * len)1214 static ENC_STATUS TCP_Update (Packet* p, Layer* lyr, uint32_t* len)
1215 {
1216     TCPHdr* h = (TCPHdr*)(lyr->start);
1217 
1218     *len += GET_TCP_HDR_LEN(h) + p->dsize;
1219 
1220     if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) {
1221         h->th_sum = 0;
1222 
1223         if (IS_IP4(p)) {
1224             pseudoheader ps;
1225             ps.sip = ((IPHdr *)(lyr-1)->start)->ip_src.s_addr;
1226             ps.dip = ((IPHdr *)(lyr-1)->start)->ip_dst.s_addr;
1227             ps.zero = 0;
1228             ps.protocol = IPPROTO_TCP;
1229             ps.len = htons((uint16_t)*len);
1230             h->th_sum = in_chksum_tcp(&ps, (uint16_t *)h, *len);
1231         } else {
1232             pseudoheader6 ps6;
1233             for (lyr--; lyr->proto != PROTO_IP6 && lyr != p->layers; lyr--);
1234             if (lyr->proto == PROTO_IP6)
1235             {
1236                 memcpy(ps6.sip, ((IP6RawHdr *)lyr->start)->ip6_src.s6_addr, sizeof(ps6.sip));
1237                 memcpy(ps6.dip, ((IP6RawHdr *)lyr->start)->ip6_dst.s6_addr, sizeof(ps6.dip));
1238                 ps6.zero = 0;
1239                 ps6.protocol = IPPROTO_TCP;
1240                 ps6.len = htons((uint16_t)*len);
1241                 h->th_sum = in_chksum_tcp6(&ps6, (uint16_t *)h, *len);
1242             }
1243         }
1244     }
1245 
1246     return ENC_OK;
1247 }
1248 
TCP_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)1249 static void TCP_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
1250 {
1251     TCPHdr* ch = (TCPHdr*)lyr->start;
1252     c->tcph = ch;
1253 
1254     if ( REVERSE(f) )
1255     {
1256         int i = lyr - c->layers;
1257         TCPHdr* ph = (TCPHdr*)p->layers[i].start;
1258 
1259         ch->th_sport = ph->th_dport;
1260         ch->th_dport = ph->th_sport;
1261     }
1262     c->sp = ntohs(ch->th_sport);
1263     c->dp = ntohs(ch->th_dport);
1264 }
1265 
1266 //-------------------------------------------------------------------------
1267 // IP6 encoder
1268 //-------------------------------------------------------------------------
1269 
IP6_Encode(EncState * enc,Buffer * in,Buffer * out)1270 static ENC_STATUS IP6_Encode (EncState* enc, Buffer* in, Buffer* out)
1271 {
1272     int len;
1273     uint32_t start = out->end;
1274 
1275     IP6RawHdr* hi = (IP6RawHdr*)enc->p->layers[enc->layer-1].start;
1276     IP6RawHdr* ho = (IP6RawHdr*)(out->base + out->end);
1277     PROTO_ID next = NextEncoder(enc);
1278 
1279     UPDATE_BOUND(out, sizeof(*ho));
1280 
1281     ho->ip6flow = htonl(ntohl(hi->ip6flow) & 0xFFF00000);
1282     ho->ip6nxt = hi->ip6nxt;
1283 
1284     if ( FORWARD(enc) )
1285     {
1286         memcpy(ho->ip6_src.s6_addr, hi->ip6_src.s6_addr, sizeof(ho->ip6_src.s6_addr));
1287         memcpy(ho->ip6_dst.s6_addr, hi->ip6_dst.s6_addr, sizeof(ho->ip6_dst.s6_addr));
1288 
1289         ho->ip6hops = FwdTTL(enc, hi->ip6hops);
1290     }
1291     else
1292     {
1293         memcpy(ho->ip6_src.s6_addr, hi->ip6_dst.s6_addr, sizeof(ho->ip6_src.s6_addr));
1294         memcpy(ho->ip6_dst.s6_addr, hi->ip6_src.s6_addr, sizeof(ho->ip6_dst.s6_addr));
1295 
1296         ho->ip6hops = RevTTL(enc, hi->ip6hops);
1297     }
1298 
1299     enc->ip_hdr = (uint8_t*)hi;
1300     enc->ip_len = sizeof(*hi);
1301 
1302     if ( next < PROTO_MAX )
1303     {
1304         ENC_STATUS err = encoders[next].fencode(enc, in, out);
1305         if ( ENC_OK != err ) return err;
1306     }
1307     if ( enc->proto )
1308     {
1309         ho->ip6nxt = enc->proto;
1310         enc->proto = 0;
1311     }
1312     len = out->end - start;
1313     ho->ip6plen = htons((uint16_t)(len - sizeof(*ho)));
1314 
1315     return ENC_OK;
1316 }
1317 
IP6_Update(Packet * p,Layer * lyr,uint32_t * len)1318 static ENC_STATUS IP6_Update (Packet* p, Layer* lyr, uint32_t* len)
1319 {
1320     IP6RawHdr* h = (IP6RawHdr*)(lyr->start);
1321     int i = lyr - p->layers;
1322 
1323     // if we didn't trim payload or format this packet,
1324     // we may not know the actual lengths because not all
1325     // extension headers are decoded and we stop at frag6.
1326     // in such case we do not modify the packet length.
1327     if ( (p->packet_flags & PKT_MODIFIED)
1328 #ifdef NORMALIZER
1329         && !(p->packet_flags & PKT_RESIZED)
1330 #endif
1331     ) {
1332         *len = ntohs(h->ip6plen) + sizeof(*h);
1333     }
1334     else
1335     {
1336         if ( i + 1 == p->next_layer )
1337             *len += lyr->length + p->dsize;
1338 
1339         // w/o all extension headers, can't use just the
1340         // fixed ip6 header length so we compute header delta
1341         else
1342             *len += lyr[1].start - lyr->start;
1343 
1344         // len includes header, remove for payload
1345         h->ip6plen = htons((uint16_t)(*len - sizeof(*h)));
1346     }
1347 
1348     return ENC_OK;
1349 }
1350 
IP6_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)1351 static void IP6_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
1352 {
1353     IP6RawHdr* ch = (IP6RawHdr*)lyr->start;
1354 
1355     if ( REVERSE(f) )
1356     {
1357         int i = lyr - c->layers;
1358         IP6RawHdr* ph = (IP6RawHdr*)p->layers[i].start;
1359 
1360         memcpy(ch->ip6_src.s6_addr, ph->ip6_dst.s6_addr, sizeof(ch->ip6_src.s6_addr));
1361         memcpy(ch->ip6_dst.s6_addr, ph->ip6_src.s6_addr, sizeof(ch->ip6_dst.s6_addr));
1362     }
1363     if ( f & ENC_FLAG_DEF )
1364     {
1365         int i = lyr - c->layers;
1366         if ( i + 1 == p->next_layer )
1367         {
1368             uint8_t* b = (uint8_t*)p->ip6_extensions[p->ip6_frag_index].data;
1369             if ( b ) lyr->length = b - p->layers[i].start;
1370         }
1371     }
1372     sfiph_build(c, ch, AF_INET6);
1373 
1374     // set outer to inner so this will always wind pointing to inner
1375     c->raw_ip6h = ch;
1376 }
1377 
1378 //-------------------------------------------------------------------------
1379 // IP6 options functions
1380 //-------------------------------------------------------------------------
1381 
Opt6_Encode(EncState * enc,Buffer * in,Buffer * out)1382 static ENC_STATUS Opt6_Encode (EncState* enc, Buffer* in, Buffer* out)
1383 {
1384     // we don't encode ext headers
1385     PROTO_ID next = NextEncoder(enc);
1386 
1387     if ( next < PROTO_MAX )
1388     {
1389         ENC_STATUS err = encoders[next].fencode(enc, in, out);
1390         if ( ENC_OK != err ) return err;
1391     }
1392     return ENC_OK;
1393 }
1394 
Opt6_Update(Packet * p,Layer * lyr,uint32_t * len)1395 static ENC_STATUS Opt6_Update (Packet* p, Layer* lyr, uint32_t* len)
1396 {
1397     int i = lyr - p->layers;
1398     *len += lyr->length;
1399 
1400     if ( i + 1 == p->next_layer )
1401         *len += p->dsize;
1402 
1403     return ENC_OK;
1404 }
1405 
1406 //-------------------------------------------------------------------------
1407 // ICMP6 functions
1408 //-------------------------------------------------------------------------
1409 
IcmpV6Code(EncodeType et)1410 static inline int IcmpV6Code (EncodeType et) {
1411     switch ( et ) {
1412     case ENC_UNR_NET:  return ICMP6_UNREACH_NET;
1413     case ENC_UNR_HOST: return ICMP6_UNREACH_HOST;
1414     case ENC_UNR_PORT: return ICMP6_UNREACH_PORT;
1415     case ENC_UNR_FW:   return ICMP6_UNREACH_FILTER_PROHIB;
1416     default: break;
1417     }
1418     return ICMP6_UNREACH_PORT;
1419 }
1420 
1421 
UN6_Encode_Icmpv6Hdr(EncState * enc,IcmpHdr * ho,Buffer * out)1422 static inline ENC_STATUS UN6_Encode_Icmpv6Hdr( EncState *enc, IcmpHdr *ho, Buffer *out )
1423 {
1424     enc->proto = IPPROTO_ICMPV6;
1425 
1426     UPDATE_BOUND(out, sizeof(*ho));
1427     ho->type = 1;   // dest unreachable
1428     ho->code = IcmpV6Code( enc->type );
1429     ho->cksum = 0;
1430     ho->unused = 0;
1431     return ENC_OK;
1432 }
1433 
UN6_Encode_OrigIcmpV6(EncState * enc,Buffer * out)1434 static inline ENC_STATUS UN6_Encode_OrigIcmpV6( EncState *enc, Buffer *out )
1435 {
1436     uint8_t* p;
1437 
1438     // copy original ip header
1439     p = out->base + out->end;
1440     UPDATE_BOUND(out, enc->ip_len);
1441     // TBD should be able to elminate enc->ip_hdr by using layer-2
1442     memcpy(p, enc->ip_hdr, enc->ip_len);
1443     return ENC_OK;
1444 }
1445 
UN6_Encode_OrigUdp(EncState * enc,Buffer * out)1446 static inline ENC_STATUS UN6_Encode_OrigUdp( EncState *enc, Buffer *out )
1447 {
1448     uint8_t* p;
1449     uint8_t* hi = enc->p->layers[enc->layer-1].start;
1450 
1451     // copy original ip header
1452     p = out->base + out->end;
1453     UPDATE_BOUND(out, enc->ip_len);
1454     // TBD should be able to elminate enc->ip_hdr by using layer-2
1455     memcpy(p, enc->ip_hdr, enc->ip_len);
1456     ((IP6RawHdr*)p)->ip6nxt = IPPROTO_UDP;
1457 
1458     // copy first 8 octets of original ip data (ie udp header)
1459     // TBD: copy up to minimum MTU worth of data
1460     p = out->base + out->end;
1461     UPDATE_BOUND(out, ICMP_UNREACH_DATA);
1462     memcpy(p, hi, ICMP_UNREACH_DATA);
1463 
1464     return ENC_OK;
1465 }
1466 
UN6_Encode_Compute_Chksum(EncState * enc,IcmpHdr * ho,Buffer * out)1467 static inline void UN6_Encode_Compute_Chksum( EncState *enc, IcmpHdr *ho, Buffer *out )
1468 {
1469     pseudoheader6 ps6;
1470     int len;
1471 
1472     len = BUFF_DIFF(out, ho);
1473 
1474     memcpy(ps6.sip, ((IP6RawHdr *)enc->ip_hdr)->ip6_src.s6_addr, sizeof(ps6.sip));
1475     memcpy(ps6.dip, ((IP6RawHdr *)enc->ip_hdr)->ip6_dst.s6_addr, sizeof(ps6.dip));
1476     ps6.zero = 0;
1477     ps6.protocol = IPPROTO_ICMPV6;
1478     ps6.len = htons((uint16_t)(len));
1479 
1480     ho->cksum = in_chksum_icmp6(&ps6, (uint16_t *)ho, len);
1481 }
1482 
UN6_ICMP6_Encode(EncState * enc,Buffer * in,Buffer * out)1483 static ENC_STATUS UN6_ICMP6_Encode (EncState* enc, Buffer* in, Buffer* out)
1484 {
1485     IcmpHdr* ho = (IcmpHdr*)(out->base + out->end);
1486 
1487 #ifdef DEBUG
1488     if ( enc->type < ENC_UNR_NET )
1489         return ENC_BAD_OPT;
1490 #endif
1491 
1492     UN6_Encode_Icmpv6Hdr( enc, ho, out);
1493     UN6_Encode_OrigIcmpV6( enc, out );
1494     UN6_Encode_Compute_Chksum( enc, ho, out );
1495 
1496     return ENC_OK;
1497 }
1498 
UN6_UDP_Encode(EncState * enc,Buffer * in,Buffer * out)1499 static ENC_STATUS UN6_UDP_Encode(EncState* enc, Buffer* in, Buffer* out)
1500 {
1501     IcmpHdr* ho = (IcmpHdr*)(out->base + out->end);
1502 
1503 #ifdef DEBUG
1504     if ( enc->type < ENC_UNR_NET )
1505         return ENC_BAD_OPT;
1506 #endif
1507 
1508     UN6_Encode_Icmpv6Hdr( enc, ho, out);
1509     UN6_Encode_OrigUdp( enc, out );
1510     UN6_Encode_Compute_Chksum( enc, ho, out );
1511 
1512     return ENC_OK;
1513 }
1514 
ICMP6_Update(Packet * p,Layer * lyr,uint32_t * len)1515 static ENC_STATUS ICMP6_Update (Packet* p, Layer* lyr, uint32_t* len)
1516 {
1517     IcmpHdr* h = (IcmpHdr*)(lyr->start);
1518 
1519     *len += lyr->length + p->dsize;
1520 
1521     if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) {
1522         pseudoheader6 ps6;
1523         for (lyr--; lyr->proto != PROTO_IP6 && lyr != p->layers; lyr--);
1524         if (lyr->proto == PROTO_IP6)
1525         {
1526             h->cksum = 0;
1527             memcpy(ps6.sip, ((IP6RawHdr *)lyr->start)->ip6_src.s6_addr, sizeof(ps6.sip));
1528             memcpy(ps6.dip, ((IP6RawHdr *)lyr->start)->ip6_dst.s6_addr, sizeof(ps6.dip));
1529             ps6.zero = 0;
1530             ps6.protocol = IPPROTO_ICMPV6;
1531             ps6.len = htons((uint16_t)*len);
1532             h->cksum = in_chksum_icmp6(&ps6, (uint16_t *)h, *len);
1533         }
1534     }
1535 
1536     return ENC_OK;
1537 }
1538 
ICMP6_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)1539 static void ICMP6_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
1540 {
1541     // TBD handle nested icmp6 layers
1542     c->icmp6h = (ICMP6Hdr*)lyr->start;
1543 }
1544 
1545 //-------------------------------------------------------------------------
1546 // GTP functions
1547 //-------------------------------------------------------------------------
1548 
update_GTP_length(GTPHdr * h,int gtp_total_len)1549 static ENC_STATUS update_GTP_length(GTPHdr* h, int gtp_total_len )
1550 {
1551     /*The first 3 bits are version number*/
1552     uint8_t version = (h->flag & 0xE0) >> 5;
1553     switch (version)
1554     {
1555     case 0: /*GTP v0*/
1556         h->length = htons((uint16_t)(gtp_total_len - GTP_V0_HEADER_LEN));
1557         break;
1558     case 1: /*GTP v1*/
1559         h->length = htons((uint16_t)(gtp_total_len - GTP_MIN_LEN));
1560         break;
1561     default:
1562         return ENC_BAD_PROTO;
1563     }
1564     return ENC_OK;
1565 
1566 }
1567 
GTP_Encode(EncState * enc,Buffer * in,Buffer * out)1568 static ENC_STATUS GTP_Encode (EncState* enc, Buffer* in, Buffer* out)
1569 {
1570     int n = enc->p->layers[enc->layer-1].length;
1571     int len;
1572 
1573     GTPHdr* hi = (GTPHdr*) (enc->p->layers[enc->layer-1].start);
1574     GTPHdr* ho = (GTPHdr*)(out->base + out->end);
1575     uint32_t start = out->end;
1576     PROTO_ID next = NextEncoder(enc);
1577 
1578     UPDATE_BOUND(out, n);
1579     memcpy(ho, hi, n);
1580 
1581     if ( next < PROTO_MAX )
1582     {
1583         ENC_STATUS err = encoders[next].fencode(enc, in, out);
1584         if (ENC_OK != err ) return err;
1585     }
1586     len = out->end - start;
1587     return( update_GTP_length(ho,len));
1588 }
1589 
GTP_Update(Packet * p,Layer * lyr,uint32_t * len)1590 static ENC_STATUS GTP_Update (Packet* p, Layer* lyr, uint32_t* len)
1591 {
1592     GTPHdr* h = (GTPHdr*)(lyr->start);
1593     *len += lyr->length;
1594     return( update_GTP_length(h,*len));
1595 }
1596 
1597 //-------------------------------------------------------------------------
1598 // PPPoE functions
1599 //-------------------------------------------------------------------------
1600 
PPPoE_Encode(EncState * enc,Buffer * in,Buffer * out)1601 static ENC_STATUS PPPoE_Encode (EncState* enc, Buffer* in, Buffer* out)
1602 {
1603     int n = enc->p->layers[enc->layer-1].length;
1604     int len;
1605 
1606     PPPoEHdr* hi = (PPPoEHdr*)(enc->p->layers[enc->layer-1].start);
1607     PPPoEHdr* ho = (PPPoEHdr*)(out->base + out->end);
1608 
1609     uint32_t start;
1610     PROTO_ID next = NextEncoder(enc);
1611 
1612     UPDATE_BOUND(out, n);
1613     memcpy(ho, hi, n);
1614 
1615     start = out->end;
1616 
1617     if ( next < PROTO_MAX )
1618     {
1619         ENC_STATUS err = encoders[next].fencode(enc, in, out);
1620         if (ENC_OK != err ) return err;
1621     }
1622     len = out->end - start;
1623     ho->length = htons((uint16_t)len);
1624 
1625     return ENC_OK;
1626 }
1627 
1628  //-------------------------------------------------------------------------
1629 // MPLS functions
1630 //-------------------------------------------------------------------------
1631 
MPLS_Encode(EncState * enc,Buffer * in,Buffer * out)1632 static ENC_STATUS MPLS_Encode (EncState* enc, Buffer* in, Buffer* out)
1633 {
1634    uint16_t n;
1635    uint8_t* hi = NULL;
1636    uint8_t* ho;
1637    PROTO_ID next;
1638 
1639    SessionControlBlock* scb = (SessionControlBlock*)(enc->p->ssnptr);
1640 
1641    if ( FORWARD(enc) )
1642    {
1643        if( scb != NULL && scb->clientMplsHeader != NULL )
1644        {
1645            n  = scb->clientMplsHeader->length;
1646            hi = scb->clientMplsHeader->start;
1647        }
1648    }
1649    else
1650    {
1651        if( scb != NULL && scb->serverMplsHeader != NULL )
1652        {
1653            n  = scb->serverMplsHeader->length;
1654            hi = scb->serverMplsHeader->start;
1655        }
1656    }
1657    if(!(hi) )
1658    {
1659        n  = enc->p->layers[enc->layer-1].length;
1660        hi = enc->p->layers[enc->layer-1].start;
1661    }
1662    ho = (uint8_t*)(out->base + out->end);
1663    next = NextEncoder(enc);
1664 
1665    UPDATE_BOUND(out, n);
1666    memcpy(ho, hi, n);
1667 
1668    if ( next < PROTO_MAX )
1669    {
1670        ENC_STATUS err = encoders[next].fencode(enc, in, out);
1671        if (ENC_OK != err ) return err;
1672    }
1673    return ENC_OK;
1674 }
1675 
1676 
1677 //-------------------------------------------------------------------------
1678 // XXX (generic) functions
1679 //-------------------------------------------------------------------------
1680 
XXX_Encode(EncState * enc,Buffer * in,Buffer * out)1681 static ENC_STATUS XXX_Encode (EncState* enc, Buffer* in, Buffer* out)
1682 {
1683     int n = enc->p->layers[enc->layer-1].length;
1684 
1685     uint8_t* hi = enc->p->layers[enc->layer-1].start;
1686     uint8_t* ho = (uint8_t*)(out->base + out->end);
1687     PROTO_ID next = NextEncoder(enc);
1688 
1689     UPDATE_BOUND(out, n);
1690     memcpy(ho, hi, n);
1691 
1692     if ( next < PROTO_MAX )
1693     {
1694         ENC_STATUS err = encoders[next].fencode(enc, in, out);
1695         if (ENC_OK != err ) return err;
1696     }
1697     return ENC_OK;
1698 }
1699 
1700 // for general cases, may need to move dsize out of top, tcp, and
1701 // udp and put in Encode_Update() (then this can be eliminated and
1702 // xxx called instead).  (another thought is to add data as a "layer").
1703 
1704 #if 0
1705 static ENC_STATUS Top_Update (Packet* p, Layer* lyr, uint32_t* len)
1706 {
1707     *len += lyr->length + p->dsize;
1708     return ENC_OK;
1709 }
1710 #endif
1711 
XXX_Update(Packet * p,Layer * lyr,uint32_t * len)1712 static ENC_STATUS XXX_Update (Packet* p, Layer* lyr, uint32_t* len)
1713 {
1714     *len += lyr->length;
1715     return ENC_OK;
1716 }
1717 
GRE_Update(Packet * p,Layer * lyr,uint32_t * len)1718 static ENC_STATUS GRE_Update (Packet* p, Layer* lyr, uint32_t* len)
1719 {
1720     GREHdr* h = (GREHdr*)(lyr->start);
1721     *len += lyr->length;
1722     if(GRE_CHKSUM(h))
1723     {
1724         if(lyr->length >= 6)
1725         {
1726             uint16_t *csum = (uint16_t *) (lyr->start + 4);
1727             *csum = 0;
1728             *csum = ones_compl_checksum((const char *)h, *len);
1729         }
1730     }
1731     return ENC_OK;
1732 }
1733 
XXX_Format(EncodeFlags f,const Packet * p,Packet * c,Layer * lyr)1734 static void XXX_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
1735 {
1736     // nop
1737 }
1738 
GRE_Encode(EncState * enc,Buffer * in,Buffer * out)1739 static ENC_STATUS GRE_Encode (EncState* enc, Buffer* in, Buffer* out)
1740 {
1741     int n = enc->p->layers[enc->layer-1].length;
1742 
1743     GREHdr* hi = (GREHdr *)enc->p->layers[enc->layer-1].start;
1744     GREHdr* ho = (GREHdr *)(out->base + out->end);
1745     PROTO_ID next = NextEncoder(enc);
1746 
1747     UPDATE_BOUND(out, n);
1748     memcpy(ho, hi, n);
1749 
1750     if ( next < PROTO_MAX )
1751     {
1752         ENC_STATUS err = encoders[next].fencode(enc, in, out);
1753         if (ENC_OK != err ) return err;
1754     }
1755     if(GRE_CHKSUM(ho))
1756     {
1757         if(n >= 6)
1758         {
1759             int len = BUFF_DIFF(out, ho);
1760             uint16_t *csum = (uint16_t *) ((uint8_t *)ho + 4);
1761             *csum = 0;
1762             *csum = ones_compl_checksum((const char *)ho, len);
1763         }
1764     }
1765 
1766     return ENC_OK;
1767 }
1768 
1769 
1770 //-------------------------------------------------------------------------
1771 // function table:
1772 // these must be in the same order PROTO_IDs are defined!
1773 // all entries must have a function
1774 //-------------------------------------------------------------------------
1775 
1776 static EncoderFunctions encoders[PROTO_MAX] = {
1777     { Eth_Encode,  Eth_Update,   Eth_Format   },
1778     { FPath_Encode, FPath_Update, FPath_Format },  // FabricPath
1779     { XXX_Encode,  XXX_Update,   XXX_Format   }, // Cisco Metadata
1780     { IP4_Encode,  IP4_Update,   IP4_Format   },
1781     { UN4_Encode,  ICMP4_Update, ICMP4_Format },
1782     { XXX_Encode,  XXX_Update,   XXX_Format,  },  // ICMP_IP4
1783     { UDP_Encode,  UDP_Update,   UDP_Format   },
1784     { TCP_Encode,  TCP_Update,   TCP_Format   },
1785     { IP6_Encode,  IP6_Update,   IP6_Format   },
1786     { Opt6_Encode, Opt6_Update,  XXX_Format   },  // IP6 Hop Opts
1787     { Opt6_Encode, Opt6_Update,  XXX_Format   },  // IP6 Dst Opts
1788     { UN6_ICMP6_Encode,  ICMP6_Update, ICMP6_Format },
1789     { XXX_Encode,  XXX_Update,   XXX_Format,  },  // ICMP_IP6
1790     { XXX_Encode,  XXX_Update,   VLAN_Format  },
1791 #ifdef GRE
1792     { GRE_Encode,  GRE_Update,   GRE_Format   },
1793     { XXX_Encode,  XXX_Update,   XXX_Format   },  // ERSPAN
1794 #endif
1795     { PPPoE_Encode,XXX_Update,   XXX_Format   },
1796     { XXX_Encode,  XXX_Update,   XXX_Format   },  // PPP Encap
1797 #ifdef MPLS
1798     { MPLS_Encode,  XXX_Update,   XXX_Format   },  // MPLS
1799 #endif
1800     { XXX_Encode,  XXX_Update,   XXX_Format,  },  // ARP
1801     { GTP_Encode,  GTP_Update,   XXX_Format,  },  // GTP
1802     { XXX_Encode,  XXX_Update,   XXX_Format,  }   // Auth Header
1803 };
1804 
1805