1 /*
2 * Copyright (c) 2018-2021, OARC, Inc.
3 * All rights reserved.
4 *
5 * This file is part of dnsjit.
6 *
7 * dnsjit is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * dnsjit is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include "filter/layer.h"
24 #include "core/assert.h"
25
26 #include <string.h>
27 #include <pcap/pcap.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <netinet/ip.h>
32 #include <netinet/ip6.h>
33 #ifdef HAVE_NET_ETHERNET_H
34 #include <net/ethernet.h>
35 #endif
36 #ifdef HAVE_NET_ETHERTYPES_H
37 #include <net/ethertypes.h>
38 #endif
39 #ifdef HAVE_ENDIAN_H
40 #include <endian.h>
41 #else
42 #ifdef HAVE_SYS_ENDIAN_H
43 #include <sys/endian.h>
44 #else
45 #ifdef HAVE_MACHINE_ENDIAN_H
46 #include <machine/endian.h>
47 #endif
48 #endif
49 #endif
50 #ifdef HAVE_BYTESWAP_H
51 #include <byteswap.h>
52 #endif
53 #ifndef bswap_16
54 #ifndef bswap16
55 #define bswap_16(x) swap16(x)
56 #define bswap_32(x) swap32(x)
57 #define bswap_64(x) swap64(x)
58 #else
59 #define bswap_16(x) bswap16(x)
60 #define bswap_32(x) bswap32(x)
61 #define bswap_64(x) bswap64(x)
62 #endif
63 #endif
64
65 #define N_IEEE802 3
66
67 static core_log_t _log = LOG_T_INIT("filter.layer");
68 static filter_layer_t _defaults = {
69 LOG_T_INIT_OBJ("filter.layer"),
70 0, 0,
71 0, 0,
72 0,
73 CORE_OBJECT_NULL_INIT(0),
74 CORE_OBJECT_ETHER_INIT(0),
75 CORE_OBJECT_LOOP_INIT(0),
76 CORE_OBJECT_LINUXSLL_INIT(0),
77 0, { CORE_OBJECT_IEEE802_INIT(0), CORE_OBJECT_IEEE802_INIT(0), CORE_OBJECT_IEEE802_INIT(0) },
78 CORE_OBJECT_IP_INIT(0),
79 CORE_OBJECT_IP6_INIT(0),
80 CORE_OBJECT_GRE_INIT(0),
81 CORE_OBJECT_ICMP_INIT(0),
82 CORE_OBJECT_ICMP6_INIT(0),
83 CORE_OBJECT_UDP_INIT(0),
84 CORE_OBJECT_TCP_INIT(0),
85 CORE_OBJECT_PAYLOAD_INIT(0)
86 };
87
filter_layer_log()88 core_log_t* filter_layer_log()
89 {
90 return &_log;
91 }
92
filter_layer_init(filter_layer_t * self)93 void filter_layer_init(filter_layer_t* self)
94 {
95 mlassert_self();
96
97 *self = _defaults;
98 }
99
filter_layer_destroy(filter_layer_t * self)100 void filter_layer_destroy(filter_layer_t* self)
101 {
102 mlassert_self();
103 }
104
105 #define need4x2(v1, v2, p, l) \
106 if (l < 1) { \
107 break; \
108 } \
109 v1 = (*p) >> 4; \
110 v2 = (*p) & 0xf; \
111 p += 1; \
112 l -= 1
113
114 #define need8(v, p, l) \
115 if (l < 1) { \
116 break; \
117 } \
118 v = *p; \
119 p += 1; \
120 l -= 1
121
_need16(const void * ptr)122 static inline uint16_t _need16(const void* ptr)
123 {
124 uint16_t v;
125 memcpy(&v, ptr, sizeof(v));
126 return be16toh(v);
127 }
128
129 #define need16(v, p, l) \
130 if (l < 2) { \
131 break; \
132 } \
133 v = _need16(p); \
134 p += 2; \
135 l -= 2
136
137 #define needr16(v, p, l) \
138 if (l < 2) { \
139 break; \
140 } \
141 v = bswap_16(_need16(p)); \
142 p += 2; \
143 l -= 2
144
_need32(const void * ptr)145 static inline uint32_t _need32(const void* ptr)
146 {
147 uint32_t v;
148 memcpy(&v, ptr, sizeof(v));
149 return be32toh(v);
150 }
151
152 #define need32(v, p, l) \
153 if (l < 4) { \
154 break; \
155 } \
156 v = _need32(p); \
157 p += 4; \
158 l -= 4
159
160 #define needr32(v, p, l) \
161 if (l < 4) { \
162 break; \
163 } \
164 v = bswap_32(_need32(p)); \
165 p += 4; \
166 l -= 4
167
168 #define needxb(b, x, p, l) \
169 if (l < x) { \
170 break; \
171 } \
172 memcpy(b, p, x); \
173 p += x; \
174 l -= x
175
176 #define advancexb(x, p, l) \
177 if (l < x) { \
178 break; \
179 } \
180 p += x; \
181 l -= x
182
183 //static int _ip(filter_layer_t* self, const core_object_t* obj, const unsigned char* pkt, size_t len);
184
_proto(filter_layer_t * self,uint8_t proto,const core_object_t * obj,const unsigned char * pkt,size_t len)185 static inline int _proto(filter_layer_t* self, uint8_t proto, const core_object_t* obj, const unsigned char* pkt, size_t len)
186 {
187 switch (proto) {
188 case IPPROTO_GRE: {
189 core_object_gre_t* gre = &self->gre;
190 gre->obj_prev = obj;
191
192 need16(gre->gre_flags, pkt, len);
193 need16(gre->ether_type, pkt, len);
194
195 /* TODO: Incomplete, check RFC 1701 */
196
197 self->produced = (core_object_t*)gre;
198
199 // if (gre.gre_flags & 0x1) {
200 // need16(gre.checksum, pkt, len);
201 // }
202 // if (gre.gre_flags & 0x4) {
203 // need16(gre.key, pkt, len);
204 // }
205 // if (gre.gre_flags & 0x8) {
206 // need16(gre.sequence, pkt, len);
207 // }
208 //
209 // switch (gre.ether_type) {
210 // case ETHERTYPE_IP:
211 // case ETHERTYPE_IPV6:
212 // return _ip(self, (core_object_t*)gre, pkt, len);
213 //
214 // default:
215 // break;
216 // }
217 break;
218 }
219 case IPPROTO_ICMP: {
220 core_object_icmp_t* icmp = &self->icmp;
221 icmp->obj_prev = obj;
222
223 need8(icmp->type, pkt, len);
224 need8(icmp->code, pkt, len);
225 need16(icmp->cksum, pkt, len);
226
227 self->produced = (core_object_t*)icmp;
228 break;
229 }
230 case IPPROTO_ICMPV6: {
231 core_object_icmp6_t* icmp6 = &self->icmp6;
232 icmp6->obj_prev = obj;
233
234 need8(icmp6->type, pkt, len);
235 need8(icmp6->code, pkt, len);
236 need16(icmp6->cksum, pkt, len);
237
238 self->produced = (core_object_t*)icmp6;
239 break;
240 }
241 case IPPROTO_UDP: {
242 core_object_udp_t* udp = &self->udp;
243 core_object_payload_t* payload = &self->payload;
244 udp->obj_prev = obj;
245
246 need16(udp->sport, pkt, len);
247 need16(udp->dport, pkt, len);
248 need16(udp->ulen, pkt, len);
249 need16(udp->sum, pkt, len);
250
251 payload->obj_prev = (core_object_t*)udp;
252
253 /* Check for padding */
254 if (len > udp->ulen) {
255 payload->padding = len - udp->ulen;
256 payload->len = len - payload->padding;
257 } else {
258 payload->padding = 0;
259 payload->len = len;
260 }
261 payload->payload = (uint8_t*)pkt;
262
263 self->produced = (core_object_t*)payload;
264 break;
265 }
266 case IPPROTO_TCP: {
267 core_object_tcp_t* tcp = &self->tcp;
268 core_object_payload_t* payload = &self->payload;
269 tcp->obj_prev = obj;
270
271 need16(tcp->sport, pkt, len);
272 need16(tcp->dport, pkt, len);
273 need32(tcp->seq, pkt, len);
274 need32(tcp->ack, pkt, len);
275 need4x2(tcp->off, tcp->x2, pkt, len);
276 need8(tcp->flags, pkt, len);
277 need16(tcp->win, pkt, len);
278 need16(tcp->sum, pkt, len);
279 need16(tcp->urp, pkt, len);
280 if (tcp->off > 5) {
281 tcp->opts_len = (tcp->off - 5) * 4;
282 needxb(tcp->opts, tcp->opts_len, pkt, len);
283 } else {
284 tcp->opts_len = 0;
285 }
286
287 payload->obj_prev = (core_object_t*)tcp;
288
289 /* Check for padding */
290 if (obj->obj_type == CORE_OBJECT_IP && len > (((const core_object_ip_t*)obj)->len - (((const core_object_ip_t*)obj)->hl * 4))) {
291 payload->padding = len - (((const core_object_ip_t*)obj)->len - (((const core_object_ip_t*)obj)->hl * 4));
292 payload->len = len - payload->padding;
293 } else if (obj->obj_type == CORE_OBJECT_IP6 && len > ((const core_object_ip6_t*)obj)->plen) {
294 payload->padding = len - ((const core_object_ip6_t*)obj)->plen;
295 payload->len = len - payload->padding;
296 } else {
297 payload->padding = 0;
298 payload->len = len;
299 }
300
301 payload->payload = (uint8_t*)pkt;
302
303 self->produced = (core_object_t*)payload;
304 break;
305 }
306 default:
307 self->produced = obj;
308 break;
309 }
310
311 return 0;
312 }
313
_ip(filter_layer_t * self,const core_object_t * obj,const unsigned char * pkt,size_t len)314 static inline int _ip(filter_layer_t* self, const core_object_t* obj, const unsigned char* pkt, size_t len)
315 {
316 if (len) {
317 switch ((*pkt >> 4)) {
318 case 4: {
319 core_object_ip_t* ip = &self->ip;
320
321 ip->obj_prev = obj;
322
323 need4x2(ip->v, ip->hl, pkt, len);
324 need8(ip->tos, pkt, len);
325 need16(ip->len, pkt, len);
326 need16(ip->id, pkt, len);
327 need16(ip->off, pkt, len);
328 need8(ip->ttl, pkt, len);
329 need8(ip->p, pkt, len);
330 need16(ip->sum, pkt, len);
331 needxb(&ip->src, 4, pkt, len);
332 needxb(&ip->dst, 4, pkt, len);
333
334 /* TODO: IPv4 options */
335
336 if (ip->hl < 5)
337 break;
338 if (ip->hl > 5) {
339 advancexb((ip->hl - 5) * 4, pkt, len);
340 }
341
342 /* Check reported length for missing payload */
343 if (ip->len < (ip->hl * 4)) {
344 break;
345 }
346 if (len < (ip->len - (ip->hl * 4))) {
347 break;
348 }
349
350 if (ip->off & 0x2000 || ip->off & 0x1fff) {
351 core_object_payload_t* payload = &self->payload;
352
353 payload->obj_prev = (core_object_t*)ip;
354
355 /* Check for padding */
356 if (len > (ip->len - (ip->hl * 4))) {
357 payload->padding = len - (ip->len - (ip->hl * 4));
358 payload->len = len - payload->padding;
359 } else {
360 payload->padding = 0;
361 payload->len = len;
362 }
363 payload->payload = (uint8_t*)pkt;
364
365 self->produced = (core_object_t*)payload;
366 return 0;
367 }
368
369 return _proto(self, ip->p, (core_object_t*)ip, pkt, len);
370 }
371 case 6: {
372 core_object_ip6_t* ip6 = &self->ip6;
373 struct ip6_ext ext;
374
375 ip6->obj_prev = obj;
376 ip6->is_frag = ip6->have_rtdst = 0;
377
378 need32(ip6->flow, pkt, len);
379 need16(ip6->plen, pkt, len);
380 need8(ip6->nxt, pkt, len);
381 need8(ip6->hlim, pkt, len);
382 needxb(&ip6->src, 16, pkt, len);
383 needxb(&ip6->dst, 16, pkt, len);
384
385 /* Check reported length for missing payload */
386 if (len < ip6->plen) {
387 break;
388 }
389
390 ext.ip6e_nxt = ip6->nxt;
391 ext.ip6e_len = 0;
392 while (ext.ip6e_nxt != IPPROTO_NONE
393 && ext.ip6e_nxt != IPPROTO_GRE
394 && ext.ip6e_nxt != IPPROTO_ICMPV6
395 && ext.ip6e_nxt != IPPROTO_UDP
396 && ext.ip6e_nxt != IPPROTO_TCP) {
397
398 /*
399 * Advance to the start of next header, this may not be needed
400 * if it's the first header or if the header is supported.
401 */
402 if (ext.ip6e_len) {
403 advancexb(ext.ip6e_len * 8, pkt, len);
404 }
405
406 /* TODO: Store IPv6 headers? */
407
408 /* Handle supported headers */
409 if (ext.ip6e_nxt == IPPROTO_FRAGMENT) {
410 if (ip6->is_frag) {
411 return 1;
412 }
413 need8(ext.ip6e_nxt, pkt, len);
414 need8(ext.ip6e_len, pkt, len);
415 if (ext.ip6e_len) {
416 return 1;
417 }
418 need16(ip6->frag_offlg, pkt, len);
419 need32(ip6->frag_ident, pkt, len);
420 ip6->is_frag = 1;
421 } else if (ext.ip6e_nxt == IPPROTO_ROUTING) {
422 struct ip6_rthdr rthdr;
423
424 if (ip6->have_rtdst) {
425 return 1;
426 }
427
428 need8(ext.ip6e_nxt, pkt, len);
429 need8(ext.ip6e_len, pkt, len);
430 need8(rthdr.ip6r_type, pkt, len);
431 need8(rthdr.ip6r_segleft, pkt, len);
432 advancexb(4, pkt, len);
433
434 if (!rthdr.ip6r_type && rthdr.ip6r_segleft) {
435 if (ext.ip6e_len & 1) {
436 return 1;
437 }
438 if (ext.ip6e_len > 2) {
439 advancexb(ext.ip6e_len - 2, pkt, len);
440 }
441 needxb(ip6->rtdst, 16, pkt, len);
442 ip6->have_rtdst = 1;
443 }
444 } else {
445 need8(ext.ip6e_nxt, pkt, len);
446 need8(ext.ip6e_len, pkt, len);
447 advancexb(6, pkt, len);
448 }
449 }
450
451 if (ext.ip6e_nxt == IPPROTO_NONE || ip6->is_frag) {
452 core_object_payload_t* payload = &self->payload;
453
454 payload->obj_prev = (core_object_t*)ip6;
455
456 /* Check for padding */
457 if (len > ip6->plen) {
458 payload->padding = len - ip6->plen;
459 payload->len = len - payload->padding;
460 } else {
461 payload->padding = 0;
462 payload->len = len;
463 }
464 payload->payload = (uint8_t*)pkt;
465
466 self->produced = (core_object_t*)payload;
467 return 0;
468 }
469
470 return _proto(self, ext.ip6e_nxt, (core_object_t*)ip6, pkt, len);
471 }
472 default:
473 break;
474 }
475 }
476
477 self->produced = obj;
478
479 return 0;
480 }
481
_ieee802(filter_layer_t * self,uint16_t tpid,const core_object_t * obj,const unsigned char * pkt,size_t len)482 static inline int _ieee802(filter_layer_t* self, uint16_t tpid, const core_object_t* obj, const unsigned char* pkt, size_t len)
483 {
484 core_object_ieee802_t* ieee802 = &self->ieee802[self->n_ieee802];
485 uint16_t tci;
486
487 ieee802->obj_prev = obj;
488
489 for (;;) {
490 ieee802->tpid = tpid;
491 need16(tci, pkt, len);
492 ieee802->pcp = (tci & 0xe000) >> 13;
493 ieee802->dei = (tci & 0x1000) >> 12;
494 ieee802->vid = tci & 0x0fff;
495 need16(ieee802->ether_type, pkt, len);
496
497 switch (ieee802->ether_type) {
498 case 0x88a8: /* 802.1ad */
499 case 0x9100: /* 802.1 QinQ non-standard */
500 self->n_ieee802++;
501 if (self->n_ieee802 < N_IEEE802) {
502 obj = (const core_object_t*)ieee802;
503 ieee802 = &self->ieee802[self->n_ieee802];
504 ieee802->obj_prev = obj;
505 tpid = ieee802->ether_type;
506 continue;
507 }
508 return 1;
509
510 case ETHERTYPE_IP:
511 case ETHERTYPE_IPV6:
512 return _ip(self, (core_object_t*)ieee802, pkt, len);
513
514 default:
515 break;
516 }
517 break;
518 }
519
520 self->produced = obj;
521
522 return 0;
523 }
524
_link(filter_layer_t * self,const core_object_pcap_t * pcap)525 static inline int _link(filter_layer_t* self, const core_object_pcap_t* pcap)
526 {
527 const unsigned char* pkt;
528 size_t len;
529
530 self->n_ieee802 = 0;
531
532 pkt = pcap->bytes;
533 len = pcap->caplen;
534
535 switch (pcap->linktype) {
536 case DLT_NULL: {
537 core_object_null_t* null = &self->null;
538 null->obj_prev = (core_object_t*)pcap;
539
540 if (pcap->is_swapped) {
541 needr32(null->family, pkt, len);
542 } else {
543 need32(null->family, pkt, len);
544 }
545
546 switch (null->family) {
547 case 2:
548 case 24:
549 case 28:
550 case 30:
551 return _ip(self, (core_object_t*)null, pkt, len);
552
553 default:
554 break;
555 }
556 break;
557 }
558 case DLT_EN10MB: {
559 core_object_ether_t* ether = &self->ether;
560 ether->obj_prev = (core_object_t*)pcap;
561
562 needxb(ether->dhost, 6, pkt, len);
563 needxb(ether->shost, 6, pkt, len);
564 need16(ether->type, pkt, len);
565
566 switch (ether->type) {
567 case 0x8100: /* 802.1q */
568 case 0x88a8: /* 802.1ad */
569 case 0x9100: /* 802.1 QinQ non-standard */
570 return _ieee802(self, ether->type, (core_object_t*)ether, pkt, len);
571
572 case ETHERTYPE_IP:
573 case ETHERTYPE_IPV6:
574 return _ip(self, (core_object_t*)ether, pkt, len);
575
576 default:
577 break;
578 }
579 break;
580 }
581 case DLT_LOOP: {
582 core_object_loop_t* loop = &self->loop;
583 loop->obj_prev = (core_object_t*)pcap;
584
585 need32(loop->family, pkt, len);
586
587 switch (loop->family) {
588 case 2:
589 case 24:
590 case 28:
591 case 30:
592 return _ip(self, (core_object_t*)loop, pkt, len);
593
594 default:
595 break;
596 }
597 break;
598 }
599 case DLT_RAW:
600 #ifdef DLT_IPV4
601 case DLT_IPV4:
602 #endif
603 #ifdef DLT_IPV6
604 case DLT_IPV6:
605 #endif
606 return _ip(self, (core_object_t*)pcap, pkt, len);
607 case DLT_LINUX_SLL: {
608 core_object_linuxsll_t* linuxsll = &self->linuxsll;
609 linuxsll->obj_prev = (core_object_t*)pcap;
610
611 need16(linuxsll->packet_type, pkt, len);
612 need16(linuxsll->arp_hardware, pkt, len);
613 need16(linuxsll->link_layer_address_length, pkt, len);
614 needxb(linuxsll->link_layer_address, 8, pkt, len);
615 need16(linuxsll->ether_type, pkt, len);
616
617 switch (linuxsll->ether_type) {
618 case 0x8100: /* 802.1q */
619 case 0x88a8: /* 802.1ad */
620 case 0x9100: /* 802.1 QinQ non-standard */
621 return _ieee802(self, linuxsll->ether_type, (core_object_t*)linuxsll, pkt, len);
622
623 case ETHERTYPE_IP:
624 case ETHERTYPE_IPV6:
625 return _ip(self, (core_object_t*)linuxsll, pkt, len);
626
627 default:
628 break;
629 }
630 break;
631 }
632 /* TODO: These might be interesting to implement
633 case DLT_IPNET:
634 case DLT_PKTAP:
635 */
636 default:
637 break;
638 }
639
640 self->produced = (core_object_t*)pcap;
641
642 return 0;
643 }
644
_receive(filter_layer_t * self,const core_object_t * obj)645 static void _receive(filter_layer_t* self, const core_object_t* obj)
646 {
647 mlassert_self();
648 lassert(obj, "obj is nil");
649
650 if (!self->recv) {
651 lfatal("no receiver set");
652 }
653 if (obj->obj_type != CORE_OBJECT_PCAP) {
654 lfatal("obj is not CORE_OBJECT_PCAP");
655 }
656
657 if (!_link(self, (core_object_pcap_t*)obj)) {
658 self->recv(self->ctx, self->produced);
659 }
660 }
661
filter_layer_receiver()662 core_receiver_t filter_layer_receiver()
663 {
664 return (core_receiver_t)_receive;
665 }
666
_produce(filter_layer_t * self)667 static const core_object_t* _produce(filter_layer_t* self)
668 {
669 const core_object_t* obj;
670 mlassert_self();
671
672 obj = self->prod(self->prod_ctx);
673 if (!obj || obj->obj_type != CORE_OBJECT_PCAP || _link(self, (core_object_pcap_t*)obj)) {
674 return 0;
675 }
676
677 return self->produced;
678 }
679
filter_layer_producer(filter_layer_t * self)680 core_producer_t filter_layer_producer(filter_layer_t* self)
681 {
682 mlassert_self();
683
684 if (!self->prod) {
685 lfatal("no producer set");
686 }
687
688 return (core_producer_t)_produce;
689 }
690