1/*#define CHASE_CHAIN*/ |
2/* 3 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that: (1) source code distributions 8 * retain the above copyright notice and this paragraph in its entirety, (2) 9 * distributions including binary code include the above copyright notice and 10 * this paragraph in its entirety in the documentation or other materials 11 * provided with the distribution, and (3) all advertising materials mentioning 12 * features or use of this software display the following acknowledgement: 13 * ``This product includes software developed by the University of California, 14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 15 * the University nor the names of its contributors may be used to endorse 16 * or promote products derived from this software without specific prior 17 * written permission. 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
21 * 22 * $FreeBSD: head/contrib/libpcap/gencode.c 56891 2000-01-30 00:43:38Z fenner $ |
23 */ 24#ifndef lint 25static const char rcsid[] = |
26 "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.100 1999/12/08 19:54:03 mcr Exp $ (LBL)"; |
27#endif 28 29#include <sys/types.h> 30#include <sys/socket.h> 31#include <sys/time.h> |
32#ifdef __NetBSD__ 33#include <sys/param.h> 34#endif |
35 36#if __STDC__ 37struct mbuf; 38struct rtentry; 39#endif 40 41#include <net/if.h> 42#include <net/ethernet.h> --- 12 unchanged lines hidden (view full) --- 55 56#include "pcap-int.h" 57 58#include "ethertype.h" 59#include "nlpid.h" 60#include "gencode.h" 61#include "ppp.h" 62#include <pcap-namedb.h> |
63#ifdef INET6 64#include <netdb.h> 65#include <sys/socket.h> 66#endif /*INET6*/ |
67 68#include "gnuc.h" 69#ifdef HAVE_OS_PROTO_H 70#include "os-proto.h" 71#endif 72 73#define JMP(c) ((c)|BPF_JMP|BPF_K) 74 --- 67 unchanged lines hidden (view full) --- 142static struct block *gen_cmp(u_int, u_int, bpf_int32); 143static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); 144static struct block *gen_bcmp(u_int, u_int, const u_char *); 145static struct block *gen_uncond(int); 146static inline struct block *gen_true(void); 147static inline struct block *gen_false(void); 148static struct block *gen_linktype(int); 149static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); |
150#ifdef INET6 151static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int); 152#endif |
153static struct block *gen_ehostop(const u_char *, int); 154static struct block *gen_fhostop(const u_char *, int); 155static struct block *gen_dnhostop(bpf_u_int32, int, u_int); 156static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int); |
157#ifdef INET6 158static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int); 159#endif |
160static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); 161static struct block *gen_ipfrag(void); 162static struct block *gen_portatom(int, bpf_int32); |
163#ifdef INET6 164static struct block *gen_portatom6(int, bpf_int32); 165#endif |
166struct block *gen_portop(int, int, int); 167static struct block *gen_port(int, int, int); |
168#ifdef INET6 169struct block *gen_portop6(int, int, int); 170static struct block *gen_port6(int, int, int); 171#endif |
172static int lookup_proto(const char *, int); 173static struct block *gen_proto(int, int, int); 174static struct slist *xfer_to_x(struct arth *); 175static struct slist *xfer_to_a(struct arth *); 176static struct block *gen_len(int, int); 177 178static void * 179newchunk(n) 180 u_int n; 181{ 182 struct chunk *cp; 183 int k, size; 184 |
185#ifndef __NetBSD__ |
186 /* XXX Round up to nearest long. */ 187 n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); |
188#else 189 /* XXX Round up to structure boundary. */ 190 n = ALIGN(n); 191#endif |
192 193 cp = &chunks[cur_chunk]; 194 if (n > cp->n_left) { 195 ++cp, k = ++cur_chunk; 196 if (k >= NCHUNKS) 197 bpf_error("out of memory"); 198 size = CHUNK0SIZE << k; 199 cp->m = (void *)malloc(size); --- 71 unchanged lines hidden (view full) --- 271static inline void 272syntax() 273{ 274 bpf_error("syntax error in filter expression"); 275} 276 277static bpf_u_int32 netmask; 278static int snaplen; |
279int no_optimize; |
280 281int 282pcap_compile(pcap_t *p, struct bpf_program *program, 283 char *buf, int optimize, bpf_u_int32 mask) 284{ 285 extern int n_errors; 286 int len; 287 |
288 no_optimize = 0; |
289 n_errors = 0; 290 root = NULL; 291 bpf_pcap = p; 292 if (setjmp(top_ctx)) { 293 freechunks(); 294 return (-1); 295 } 296 --- 5 unchanged lines hidden (view full) --- 302 (void)pcap_parse(); 303 304 if (n_errors) 305 syntax(); 306 307 if (root == NULL) 308 root = gen_retblk(snaplen); 309 |
310 if (optimize && !no_optimize) { 311 bpf_optimize(&root); 312 if (root == NULL || 313 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 314 bpf_error("expression rejects all packets"); 315 } 316 program->bf_insns = icode_to_fcode(root, &len); 317 program->bf_len = len; 318 319 freechunks(); 320 return (0); 321} 322 323/* 324 * entry point for using the compiler with no pcap open 325 * pass in all the stuff that is needed explicitly instead. 326 */ 327int 328pcap_compile_nopcap(int snaplen_arg, int linktype_arg, 329 struct bpf_program *program, 330 char *buf, int optimize, bpf_u_int32 mask) 331{ 332 extern int n_errors; 333 int len; 334 335 n_errors = 0; 336 root = NULL; 337 bpf_pcap = NULL; 338 if (setjmp(top_ctx)) { 339 freechunks(); 340 return (-1); 341 } 342 343 netmask = mask; 344 345 /* XXX needed? I don't grok the use of globals here. */ 346 snaplen = snaplen_arg; 347 348 lex_init(buf ? buf : ""); 349 init_linktype(linktype_arg); 350 (void)pcap_parse(); 351 352 if (n_errors) 353 syntax(); 354 355 if (root == NULL) 356 root = gen_retblk(snaplen_arg); 357 |
358 if (optimize) { 359 bpf_optimize(&root); 360 if (root == NULL || 361 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) 362 bpf_error("expression rejects all packets"); 363 } 364 program->bf_insns = icode_to_fcode(root, &len); 365 program->bf_len = len; --- 196 unchanged lines hidden (view full) --- 562 return; 563 564 case DLT_NULL: 565 off_linktype = 0; 566 off_nl = 4; 567 return; 568 569 case DLT_PPP: |
570#ifdef DLT_CHDLC 571 case DLT_CHDLC: 572#endif |
573 off_linktype = 2; 574 off_nl = 4; 575 return; 576 577 case DLT_PPP_BSDOS: 578 off_linktype = 5; 579 off_nl = 24; 580 return; --- 77 unchanged lines hidden (view full) --- 658 switch (linktype) { 659 660 case DLT_SLIP: 661 return gen_false(); 662 663 case DLT_PPP: 664 if (proto == ETHERTYPE_IP) 665 proto = PPP_IP; /* XXX was 0x21 */ |
666#ifdef INET6 667 else if (proto == ETHERTYPE_IPV6) 668 proto = PPP_IPV6; 669#endif |
670 break; 671 672 case DLT_PPP_BSDOS: 673 switch (proto) { 674 675 case ETHERTYPE_IP: 676 b0 = gen_cmp(off_linktype, BPF_H, PPP_IP); 677 b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC); 678 gen_or(b0, b1); 679 b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC); 680 gen_or(b1, b0); 681 return b0; 682 |
683#ifdef INET6 684 case ETHERTYPE_IPV6: 685 proto = PPP_IPV6; 686 /* more to go? */ 687 break; 688#endif 689 |
690 case ETHERTYPE_DN: 691 proto = PPP_DECNET; 692 break; 693 694 case ETHERTYPE_ATALK: 695 proto = PPP_APPLE; 696 break; 697 698 case ETHERTYPE_NS: 699 proto = PPP_NS; 700 break; 701 } 702 break; 703 704 case DLT_NULL: 705 /* XXX */ 706 if (proto == ETHERTYPE_IP) 707 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET))); |
708#ifdef INET6 709 else if (proto == ETHERTYPE_IPV6) 710 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6))); 711#endif |
712 else 713 return gen_false(); 714 case DLT_EN10MB: 715 /* 716 * Having to look at SAP's here is quite disgusting, 717 * but given an internal architecture that _knows_ that 718 * it's looking at IP on Ethernet... 719 */ --- 50 unchanged lines hidden (view full) --- 770 abort(); 771 } 772 b0 = gen_linktype(proto); 773 b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); 774 gen_and(b0, b1); 775 return b1; 776} 777 |
778#ifdef INET6 |
779static struct block * |
780gen_hostop6(addr, mask, dir, proto, src_off, dst_off) 781 struct in6_addr *addr; 782 struct in6_addr *mask; 783 int dir, proto; 784 u_int src_off, dst_off; 785{ 786 struct block *b0, *b1; 787 u_int offset; 788 u_int32_t *a, *m; 789 790 switch (dir) { 791 792 case Q_SRC: 793 offset = src_off; 794 break; 795 796 case Q_DST: 797 offset = dst_off; 798 break; 799 800 case Q_AND: 801 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); 802 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); 803 gen_and(b0, b1); 804 return b1; 805 806 case Q_OR: 807 case Q_DEFAULT: 808 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); 809 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); 810 gen_or(b0, b1); 811 return b1; 812 813 default: 814 abort(); 815 } 816 /* this order is important */ 817 a = (u_int32_t *)addr; 818 m = (u_int32_t *)mask; 819 b1 = gen_mcmp(offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); 820 b0 = gen_mcmp(offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); 821 gen_and(b0, b1); 822 b0 = gen_mcmp(offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); 823 gen_and(b0, b1); 824 b0 = gen_mcmp(offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); 825 gen_and(b0, b1); 826 b0 = gen_linktype(proto); 827 gen_and(b0, b1); 828 return b1; 829} 830#endif /*INET6*/ 831 832static struct block * |
833gen_ehostop(eaddr, dir) 834 register const u_char *eaddr; 835 register int dir; 836{ 837 register struct block *b0, *b1; 838 839 switch (dir) { 840 case Q_SRC: --- 190 unchanged lines hidden (view full) --- 1031 bpf_error("'icmp' modifier applied to host"); 1032 1033 case Q_IGMP: 1034 bpf_error("'igmp' modifier applied to host"); 1035 1036 case Q_IGRP: 1037 bpf_error("'igrp' modifier applied to host"); 1038 |
1039 case Q_PIM: 1040 bpf_error("'pim' modifier applied to host"); 1041 |
1042 case Q_ATALK: 1043 bpf_error("ATALK host filtering not implemented"); 1044 1045 case Q_DECNET: 1046 return gen_dnhostop(addr, dir, off_nl); 1047 1048 case Q_SCA: 1049 bpf_error("SCA host filtering not implemented"); --- 4 unchanged lines hidden (view full) --- 1054 case Q_MOPDL: 1055 bpf_error("MOPDL host filtering not implemented"); 1056 1057 case Q_MOPRC: 1058 bpf_error("MOPRC host filtering not implemented"); 1059 1060 case Q_ISO: 1061 bpf_error("ISO host filtering not implemented"); |
1062 1063#ifdef INET6 1064 case Q_IPV6: 1065 bpf_error("'ip6' modifier applied to ip host"); 1066 1067 case Q_ICMPV6: 1068 bpf_error("'icmp6' modifier applied to host"); 1069#endif /* INET6 */ 1070 1071 case Q_AH: 1072 bpf_error("'ah' modifier applied to host"); 1073 1074 case Q_ESP: 1075 bpf_error("'esp' modifier applied to host"); 1076 |
1077 default: 1078 abort(); 1079 } 1080 /* NOTREACHED */ 1081} 1082 |
1083#ifdef INET6 |
1084static struct block * |
1085gen_host6(addr, mask, proto, dir) 1086 struct in6_addr *addr; 1087 struct in6_addr *mask; 1088 int proto; 1089 int dir; 1090{ 1091 struct block *b0, *b1; 1092 1093 switch (proto) { 1094 1095 case Q_DEFAULT: 1096 return gen_host6(addr, mask, Q_IPV6, dir); 1097 1098 case Q_IP: 1099 bpf_error("'ip' modifier applied to ip6 host"); 1100 1101 case Q_RARP: 1102 bpf_error("'rarp' modifier applied to ip6 host"); 1103 1104 case Q_ARP: 1105 bpf_error("'arp' modifier applied to ip6 host"); 1106 1107 case Q_TCP: 1108 bpf_error("'tcp' modifier applied to host"); 1109 1110 case Q_UDP: 1111 bpf_error("'udp' modifier applied to host"); 1112 1113 case Q_ICMP: 1114 bpf_error("'icmp' modifier applied to host"); 1115 1116 case Q_IGMP: 1117 bpf_error("'igmp' modifier applied to host"); 1118 1119 case Q_IGRP: 1120 bpf_error("'igrp' modifier applied to host"); 1121 1122 case Q_PIM: 1123 bpf_error("'pim' modifier applied to host"); 1124 1125 case Q_ATALK: 1126 bpf_error("ATALK host filtering not implemented"); 1127 1128 case Q_DECNET: 1129 bpf_error("'decnet' modifier applied to ip6 host"); 1130 1131 case Q_SCA: 1132 bpf_error("SCA host filtering not implemented"); 1133 1134 case Q_LAT: 1135 bpf_error("LAT host filtering not implemented"); 1136 1137 case Q_MOPDL: 1138 bpf_error("MOPDL host filtering not implemented"); 1139 1140 case Q_MOPRC: 1141 bpf_error("MOPRC host filtering not implemented"); 1142 1143 case Q_IPV6: 1144 return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 1145 off_nl + 8, off_nl + 24); 1146 1147 case Q_ICMPV6: 1148 bpf_error("'icmp6' modifier applied to host"); 1149 1150 case Q_AH: 1151 bpf_error("'ah' modifier applied to host"); 1152 1153 case Q_ESP: 1154 bpf_error("'esp' modifier applied to host"); 1155 1156 default: 1157 abort(); 1158 } 1159 /* NOTREACHED */ 1160} 1161#endif /*INET6*/ 1162 1163static struct block * |
1164gen_gateway(eaddr, alist, proto, dir) 1165 const u_char *eaddr; 1166 bpf_u_int32 **alist; 1167 int proto; 1168 int dir; 1169{ 1170 struct block *b0, *b1, *tmp; 1171 --- 31 unchanged lines hidden (view full) --- 1203gen_proto_abbrev(proto) 1204 int proto; 1205{ 1206 struct block *b0, *b1; 1207 1208 switch (proto) { 1209 1210 case Q_TCP: |
1211 b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT); 1212#ifdef INET6 1213 b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT); 1214 gen_or(b0, b1); 1215#endif |
1216 break; 1217 1218 case Q_UDP: |
1219 b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT); 1220#ifdef INET6 1221 b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT); 1222 gen_or(b0, b1); 1223#endif |
1224 break; 1225 1226 case Q_ICMP: |
1227 b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT); |
1228 break; 1229 1230 case Q_IGMP: |
1231 b1 = gen_proto(2, Q_IP, Q_DEFAULT); |
1232 break; 1233 1234#ifndef IPPROTO_IGRP 1235#define IPPROTO_IGRP 9 1236#endif 1237 case Q_IGRP: |
1238 b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT); |
1239 break; 1240 |
1241#ifndef IPPROTO_PIM 1242#define IPPROTO_PIM 103 1243#endif 1244 1245 case Q_PIM: 1246 b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT); 1247#ifdef INET6 1248 b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT); 1249 gen_or(b0, b1); 1250#endif 1251 break; 1252 |
1253 case Q_IP: 1254 b1 = gen_linktype(ETHERTYPE_IP); 1255 break; 1256 1257 case Q_ARP: 1258 b1 = gen_linktype(ETHERTYPE_ARP); 1259 break; 1260 --- 23 unchanged lines hidden (view full) --- 1284 case Q_MOPDL: 1285 b1 = gen_linktype(ETHERTYPE_MOPDL); 1286 break; 1287 1288 case Q_MOPRC: 1289 b1 = gen_linktype(ETHERTYPE_MOPRC); 1290 break; 1291 |
1292#ifdef INET6 1293 case Q_IPV6: 1294 b1 = gen_linktype(ETHERTYPE_IPV6); 1295 break; 1296 1297#ifndef IPPROTO_ICMPV6 1298#define IPPROTO_ICMPV6 58 1299#endif 1300 case Q_ICMPV6: 1301 b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); 1302 break; 1303#endif /* INET6 */ 1304 1305#ifndef IPPROTO_AH 1306#define IPPROTO_AH 51 1307#endif 1308 case Q_AH: 1309 b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT); 1310#ifdef INET6 1311 b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT); 1312 gen_or(b0, b1); 1313#endif 1314 break; 1315 1316#ifndef IPPROTO_ESP 1317#define IPPROTO_ESP 50 1318#endif 1319 case Q_ESP: 1320 b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT); 1321#ifdef INET6 1322 b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT); 1323 gen_or(b0, b1); 1324#endif 1325 break; 1326 |
1327 case Q_ISO: 1328 b1 = gen_linktype(LLC_ISO_LSAP); 1329 break; 1330 1331 case Q_ESIS: 1332 b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); 1333 break; 1334 --- 40 unchanged lines hidden (view full) --- 1375 1376 b = new_block(JMP(BPF_JEQ)); 1377 b->stmts = s; 1378 b->s.k = v; 1379 1380 return b; 1381} 1382 |
1383#ifdef INET6 1384static struct block * 1385gen_portatom6(off, v) 1386 int off; 1387 bpf_int32 v; 1388{ 1389 return gen_cmp(off_nl + 40 + off, BPF_H, v); 1390} 1391#endif/*INET6*/ 1392 |
1393struct block * 1394gen_portop(port, proto, dir) 1395 int port, proto, dir; 1396{ 1397 struct block *b0, *b1, *tmp; 1398 1399 /* ip proto 'proto' */ 1400 tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); --- 55 unchanged lines hidden (view full) --- 1456 1457 default: 1458 abort(); 1459 } 1460 gen_and(b0, b1); 1461 return b1; 1462} 1463 |
1464#ifdef INET6 1465struct block * 1466gen_portop6(port, proto, dir) 1467 int port, proto, dir; 1468{ 1469 struct block *b0, *b1, *tmp; 1470 1471 /* ip proto 'proto' */ 1472 b0 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)proto); 1473 1474 switch (dir) { 1475 case Q_SRC: 1476 b1 = gen_portatom6(0, (bpf_int32)port); 1477 break; 1478 1479 case Q_DST: 1480 b1 = gen_portatom6(2, (bpf_int32)port); 1481 break; 1482 1483 case Q_OR: 1484 case Q_DEFAULT: 1485 tmp = gen_portatom6(0, (bpf_int32)port); 1486 b1 = gen_portatom6(2, (bpf_int32)port); 1487 gen_or(tmp, b1); 1488 break; 1489 1490 case Q_AND: 1491 tmp = gen_portatom6(0, (bpf_int32)port); 1492 b1 = gen_portatom6(2, (bpf_int32)port); 1493 gen_and(tmp, b1); 1494 break; 1495 1496 default: 1497 abort(); 1498 } 1499 gen_and(b0, b1); 1500 1501 return b1; 1502} 1503 1504static struct block * 1505gen_port6(port, ip_proto, dir) 1506 int port; 1507 int ip_proto; 1508 int dir; 1509{ 1510 struct block *b0, *b1, *tmp; 1511 1512 /* ether proto ip */ 1513 b0 = gen_linktype(ETHERTYPE_IPV6); 1514 1515 switch (ip_proto) { 1516 case IPPROTO_UDP: 1517 case IPPROTO_TCP: 1518 b1 = gen_portop6(port, ip_proto, dir); 1519 break; 1520 1521 case PROTO_UNDEF: 1522 tmp = gen_portop6(port, IPPROTO_TCP, dir); 1523 b1 = gen_portop6(port, IPPROTO_UDP, dir); 1524 gen_or(tmp, b1); 1525 break; 1526 1527 default: 1528 abort(); 1529 } 1530 gen_and(b0, b1); 1531 return b1; 1532} 1533#endif /* INET6 */ 1534 |
1535static int 1536lookup_proto(name, proto) 1537 register const char *name; 1538 register int proto; 1539{ 1540 register int v; 1541 1542 switch (proto) { --- 14 unchanged lines hidden (view full) --- 1557 1558 default: 1559 v = PROTO_UNDEF; 1560 break; 1561 } 1562 return v; 1563} 1564 |
1565struct stmt * 1566gen_joinsp(s, n) 1567 struct stmt **s; 1568 int n; 1569{ 1570} 1571 1572struct block * 1573gen_protochain(v, proto, dir) 1574 int v; 1575 int proto; 1576 int dir; 1577{ 1578#ifdef NO_PROTOCHAIN 1579 return gen_proto(v, proto, dir); 1580#else 1581 struct block *b0, *b; 1582 struct slist *s[100], *sp; 1583 int fix2, fix3, fix4, fix5; 1584 int ahcheck, again, end; 1585 int i, max; 1586 int reg1 = alloc_reg(); 1587 int reg2 = alloc_reg(); 1588 1589 memset(s, 0, sizeof(s)); 1590 fix2 = fix3 = fix4 = fix5 = 0; 1591 1592 switch (proto) { 1593 case Q_IP: 1594 case Q_IPV6: 1595 break; 1596 case Q_DEFAULT: 1597 b0 = gen_protochain(v, Q_IP, dir); 1598 b = gen_protochain(v, Q_IPV6, dir); 1599 gen_or(b0, b); 1600 return b; 1601 default: 1602 bpf_error("bad protocol applied for 'protochain'"); 1603 /*NOTREACHED*/ 1604 } 1605 1606 no_optimize = 1; /*this code is not compatible with optimzer yet */ 1607 1608 /* 1609 * s[0] is a dummy entry to protect other BPF insn from damaged 1610 * by s[fix] = foo with uninitialized variable "fix". It is somewhat 1611 * hard to find interdependency made by jump table fixup. 1612 */ 1613 i = 0; 1614 s[i] = new_stmt(0); /*dummy*/ 1615 i++; 1616 1617 switch (proto) { 1618 case Q_IP: 1619 b0 = gen_linktype(ETHERTYPE_IP); 1620 1621 /* A = ip->ip_p */ 1622 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); 1623 s[i]->s.k = off_nl + 9; 1624 i++; 1625 /* X = ip->ip_hl << 2 */ 1626 s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 1627 s[i]->s.k = off_nl; 1628 i++; 1629 break; 1630#ifdef INET6 1631 case Q_IPV6: 1632 b0 = gen_linktype(ETHERTYPE_IPV6); 1633 1634 /* A = ip6->ip_nxt */ 1635 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); 1636 s[i]->s.k = off_nl + 6; 1637 i++; 1638 /* X = sizeof(struct ip6_hdr) */ 1639 s[i] = new_stmt(BPF_LDX|BPF_IMM); 1640 s[i]->s.k = 40; 1641 i++; 1642 break; 1643#endif 1644 default: 1645 bpf_error("unsupported proto to gen_protochain"); 1646 /*NOTREACHED*/ 1647 } 1648 1649 /* again: if (A == v) goto end; else fall through; */ 1650 again = i; 1651 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1652 s[i]->s.k = v; 1653 s[i]->s.jt = NULL; /*later*/ 1654 s[i]->s.jf = NULL; /*update in next stmt*/ 1655 fix5 = i; 1656 i++; 1657 1658#ifndef IPPROTO_NONE 1659#define IPPROTO_NONE 59 1660#endif 1661 /* if (A == IPPROTO_NONE) goto end */ 1662 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1663 s[i]->s.jt = NULL; /*later*/ 1664 s[i]->s.jf = NULL; /*update in next stmt*/ 1665 s[i]->s.k = IPPROTO_NONE; 1666 s[fix5]->s.jf = s[i]; 1667 fix2 = i; 1668 i++; 1669 1670#ifdef INET6 1671 if (proto == Q_IPV6) { 1672 int v6start, v6end, v6advance, j; 1673 1674 v6start = i; 1675 /* if (A == IPPROTO_HOPOPTS) goto v6advance */ 1676 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1677 s[i]->s.jt = NULL; /*later*/ 1678 s[i]->s.jf = NULL; /*update in next stmt*/ 1679 s[i]->s.k = IPPROTO_HOPOPTS; 1680 s[fix2]->s.jf = s[i]; 1681 i++; 1682 /* if (A == IPPROTO_DSTOPTS) goto v6advance */ 1683 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1684 s[i]->s.jt = NULL; /*later*/ 1685 s[i]->s.jf = NULL; /*update in next stmt*/ 1686 s[i]->s.k = IPPROTO_DSTOPTS; 1687 i++; 1688 /* if (A == IPPROTO_ROUTING) goto v6advance */ 1689 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1690 s[i]->s.jt = NULL; /*later*/ 1691 s[i]->s.jf = NULL; /*update in next stmt*/ 1692 s[i]->s.k = IPPROTO_ROUTING; 1693 i++; 1694 /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ 1695 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1696 s[i]->s.jt = NULL; /*later*/ 1697 s[i]->s.jf = NULL; /*later*/ 1698 s[i]->s.k = IPPROTO_FRAGMENT; 1699 fix3 = i; 1700 v6end = i; 1701 i++; 1702 1703 /* v6advance: */ 1704 v6advance = i; 1705 1706 /* 1707 * in short, 1708 * A = P[X + 1]; 1709 * X = X + (P[X] + 1) * 8; 1710 */ 1711 /* A = X */ 1712 s[i] = new_stmt(BPF_MISC|BPF_TXA); 1713 i++; 1714 /* MEM[reg1] = A */ 1715 s[i] = new_stmt(BPF_ST); 1716 s[i]->s.k = reg1; 1717 i++; 1718 /* A += 1 */ 1719 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1720 s[i]->s.k = 1; 1721 i++; 1722 /* X = A */ 1723 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1724 i++; 1725 /* A = P[X + packet head]; */ 1726 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1727 s[i]->s.k = off_nl; 1728 i++; 1729 /* MEM[reg2] = A */ 1730 s[i] = new_stmt(BPF_ST); 1731 s[i]->s.k = reg2; 1732 i++; 1733 /* X = MEM[reg1] */ 1734 s[i] = new_stmt(BPF_LDX|BPF_MEM); 1735 s[i]->s.k = reg1; 1736 i++; 1737 /* A = P[X + packet head] */ 1738 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1739 s[i]->s.k = off_nl; 1740 i++; 1741 /* A += 1 */ 1742 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1743 s[i]->s.k = 1; 1744 i++; 1745 /* A *= 8 */ 1746 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 1747 s[i]->s.k = 8; 1748 i++; 1749 /* X = A; */ 1750 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1751 i++; 1752 /* A = MEM[reg2] */ 1753 s[i] = new_stmt(BPF_LD|BPF_MEM); 1754 s[i]->s.k = reg2; 1755 i++; 1756 1757 /* goto again; (must use BPF_JA for backward jump) */ 1758 s[i] = new_stmt(BPF_JMP|BPF_JA); 1759 s[i]->s.k = again - i - 1; 1760 s[i - 1]->s.jf = s[i]; 1761 i++; 1762 1763 /* fixup */ 1764 for (j = v6start; j <= v6end; j++) 1765 s[j]->s.jt = s[v6advance]; 1766 } else 1767#endif 1768 { 1769 /* nop */ 1770 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1771 s[i]->s.k = 0; 1772 s[fix2]->s.jf = s[i]; 1773 i++; 1774 } 1775 1776 /* ahcheck: */ 1777 ahcheck = i; 1778 /* if (A == IPPROTO_AH) then fall through; else goto end; */ 1779 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); 1780 s[i]->s.jt = NULL; /*later*/ 1781 s[i]->s.jf = NULL; /*later*/ 1782 s[i]->s.k = IPPROTO_AH; 1783 if (fix3) 1784 s[fix3]->s.jf = s[ahcheck]; 1785 fix4 = i; 1786 i++; 1787 1788 /* 1789 * in short, 1790 * A = P[X + 1]; 1791 * X = X + (P[X] + 2) * 4; 1792 */ 1793 /* A = X */ 1794 s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); 1795 i++; 1796 /* MEM[reg1] = A */ 1797 s[i] = new_stmt(BPF_ST); 1798 s[i]->s.k = reg1; 1799 i++; 1800 /* A += 1 */ 1801 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1802 s[i]->s.k = 1; 1803 i++; 1804 /* X = A */ 1805 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1806 i++; 1807 /* A = P[X + packet head]; */ 1808 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1809 s[i]->s.k = off_nl; 1810 i++; 1811 /* MEM[reg2] = A */ 1812 s[i] = new_stmt(BPF_ST); 1813 s[i]->s.k = reg2; 1814 i++; 1815 /* X = MEM[reg1] */ 1816 s[i] = new_stmt(BPF_LDX|BPF_MEM); 1817 s[i]->s.k = reg1; 1818 i++; 1819 /* A = P[X + packet head] */ 1820 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); 1821 s[i]->s.k = off_nl; 1822 i++; 1823 /* A += 2 */ 1824 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1825 s[i]->s.k = 2; 1826 i++; 1827 /* A *= 4 */ 1828 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); 1829 s[i]->s.k = 4; 1830 i++; 1831 /* X = A; */ 1832 s[i] = new_stmt(BPF_MISC|BPF_TAX); 1833 i++; 1834 /* A = MEM[reg2] */ 1835 s[i] = new_stmt(BPF_LD|BPF_MEM); 1836 s[i]->s.k = reg2; 1837 i++; 1838 1839 /* goto again; (must use BPF_JA for backward jump) */ 1840 s[i] = new_stmt(BPF_JMP|BPF_JA); 1841 s[i]->s.k = again - i - 1; 1842 i++; 1843 1844 /* end: nop */ 1845 end = i; 1846 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); 1847 s[i]->s.k = 0; 1848 s[fix2]->s.jt = s[end]; 1849 s[fix4]->s.jf = s[end]; 1850 s[fix5]->s.jt = s[end]; 1851 i++; 1852 1853 /* 1854 * make slist chain 1855 */ 1856 max = i; 1857 for (i = 0; i < max - 1; i++) 1858 s[i]->next = s[i + 1]; 1859 s[max - 1]->next = NULL; 1860 1861 /* 1862 * emit final check 1863 */ 1864 b = new_block(JMP(BPF_JEQ)); 1865 b->stmts = s[1]; /*remember, s[0] is dummy*/ 1866 b->s.k = v; 1867 1868 free_reg(reg1); 1869 free_reg(reg2); 1870 1871 gen_and(b0, b); 1872 return b; 1873#endif 1874} 1875 |
1876static struct block * 1877gen_proto(v, proto, dir) 1878 int v; 1879 int proto; 1880 int dir; 1881{ 1882 struct block *b0, *b1; 1883 1884 if (dir != Q_DEFAULT) 1885 bpf_error("direction applied to 'proto'"); 1886 1887 switch (proto) { 1888 case Q_DEFAULT: |
1889#ifdef INET6 1890 b0 = gen_proto(v, Q_IP, dir); 1891 b1 = gen_proto(v, Q_IPV6, dir); 1892 gen_or(b0, b1); 1893 return b1; 1894#else 1895 /*FALLTHROUGH*/ 1896#endif |
1897 case Q_IP: 1898 b0 = gen_linktype(ETHERTYPE_IP); |
1899#ifndef CHASE_CHAIN |
1900 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v); |
1901#else 1902 b1 = gen_protochain(v, Q_IP); 1903#endif |
1904 gen_and(b0, b1); 1905 return b1; 1906 1907 case Q_ISO: 1908 b0 = gen_linktype(LLC_ISO_LSAP); 1909 b1 = gen_cmp(off_nl + 3, BPF_B, (long)v); 1910 gen_and(b0, b1); 1911 return b1; --- 48 unchanged lines hidden (view full) --- 1960 case Q_IGMP: 1961 bpf_error("'igmp proto' is bogus"); 1962 /* NOTREACHED */ 1963 1964 case Q_IGRP: 1965 bpf_error("'igrp proto' is bogus"); 1966 /* NOTREACHED */ 1967 |
1968 case Q_PIM: 1969 bpf_error("'pim proto' is bogus"); 1970 /* NOTREACHED */ 1971 1972#ifdef INET6 1973 case Q_IPV6: 1974 b0 = gen_linktype(ETHERTYPE_IPV6); 1975#ifndef CHASE_CHAIN 1976 b1 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)v); 1977#else 1978 b1 = gen_protochain(v, Q_IPV6); 1979#endif 1980 gen_and(b0, b1); 1981 return b1; 1982 1983 case Q_ICMPV6: 1984 bpf_error("'icmp6 proto' is bogus"); 1985#endif /* INET6 */ 1986 1987 case Q_AH: 1988 bpf_error("'ah proto' is bogus"); 1989 1990 case Q_ESP: 1991 bpf_error("'ah proto' is bogus"); 1992 |
1993 default: 1994 abort(); 1995 /* NOTREACHED */ 1996 } 1997 /* NOTREACHED */ 1998} 1999 2000struct block * 2001gen_scode(name, q) 2002 register const char *name; 2003 struct qual q; 2004{ 2005 int proto = q.proto; 2006 int dir = q.dir; 2007 int tproto; 2008 u_char *eaddr; 2009 bpf_u_int32 mask, addr, **alist; |
2010#ifdef INET6 2011 int tproto6; 2012 struct sockaddr_in *sin; 2013 struct sockaddr_in6 *sin6; 2014 struct addrinfo *res, *res0; 2015 struct in6_addr mask128; 2016#endif /*INET6*/ |
2017 struct block *b, *tmp; 2018 int port, real_proto; 2019 2020 switch (q.addr) { 2021 2022 case Q_NET: 2023 addr = pcap_nametonetaddr(name); 2024 if (addr == 0) --- 33 unchanged lines hidden (view full) --- 2058 } else if (proto == Q_DECNET) { 2059 unsigned short dn_addr = __pcap_nametodnaddr(name); 2060 /* 2061 * I don't think DECNET hosts can be multihomed, so 2062 * there is no need to build up a list of addresses 2063 */ 2064 return (gen_host(dn_addr, 0, proto, dir)); 2065 } else { |
2066#ifndef INET6 |
2067 alist = pcap_nametoaddr(name); 2068 if (alist == NULL || *alist == NULL) 2069 bpf_error("unknown host '%s'", name); 2070 tproto = proto; 2071 if (off_linktype == -1 && tproto == Q_DEFAULT) 2072 tproto = Q_IP; 2073 b = gen_host(**alist++, 0xffffffff, tproto, dir); 2074 while (*alist) { 2075 tmp = gen_host(**alist++, 0xffffffff, 2076 tproto, dir); 2077 gen_or(b, tmp); 2078 b = tmp; 2079 } 2080 return b; |
2081#else 2082 memset(&mask128, 0xff, sizeof(mask128)); 2083 res0 = res = pcap_nametoaddr(name); 2084 if (res == NULL) 2085 bpf_error("unknown host '%s'", name); 2086 b = tmp = NULL; 2087 tproto = tproto6 = proto; 2088 if (off_linktype == -1 && tproto == Q_DEFAULT) { 2089 tproto = Q_IP; 2090 tproto6 = Q_IPV6; 2091 } 2092 while (res) { 2093 switch (res->ai_family) { 2094 case AF_INET: 2095 sin = (struct sockaddr_in *) 2096 res->ai_addr; 2097 tmp = gen_host(ntohl(sin->sin_addr.s_addr), 2098 0xffffffff, tproto, dir); 2099 break; 2100 case AF_INET6: 2101 sin6 = (struct sockaddr_in6 *) 2102 res->ai_addr; 2103 tmp = gen_host6(&sin6->sin6_addr, 2104 &mask128, tproto6, dir); 2105 break; 2106 } 2107 if (b) 2108 gen_or(b, tmp); 2109 b = tmp; 2110 2111 res = res->ai_next; 2112 } 2113 freeaddrinfo(res0); 2114 return b; 2115#endif /*INET6*/ |
2116 } 2117 2118 case Q_PORT: 2119 if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP) 2120 bpf_error("illegal qualifier of 'port'"); 2121 if (pcap_nametoport(name, &port, &real_proto) == 0) 2122 bpf_error("unknown port '%s'", name); 2123 if (proto == Q_UDP) { --- 5 unchanged lines hidden (view full) --- 2129 } 2130 if (proto == Q_TCP) { 2131 if (real_proto == IPPROTO_UDP) 2132 bpf_error("port '%s' is udp", name); 2133 else 2134 /* override PROTO_UNDEF */ 2135 real_proto = IPPROTO_TCP; 2136 } |
2137#ifndef INET6 |
2138 return gen_port(port, real_proto, dir); |
2139#else 2140 { 2141 struct block *b; 2142 b = gen_port(port, real_proto, dir); 2143 gen_or(gen_port6(port, real_proto, dir), b); 2144 return b; 2145 } 2146#endif /* INET6 */ |
2147 2148 case Q_GATEWAY: |
2149#ifndef INET6 |
2150 eaddr = pcap_ether_hostton(name); 2151 if (eaddr == NULL) 2152 bpf_error("unknown ether host: %s", name); 2153 2154 alist = pcap_nametoaddr(name); 2155 if (alist == NULL || *alist == NULL) 2156 bpf_error("unknown host '%s'", name); 2157 return gen_gateway(eaddr, alist, proto, dir); |
2158#else 2159 bpf_error("'gateway' not supported in this configuration"); 2160#endif /*INET6*/ |
2161 2162 case Q_PROTO: 2163 real_proto = lookup_proto(name, proto); 2164 if (real_proto >= 0) 2165 return gen_proto(real_proto, proto, dir); 2166 else 2167 bpf_error("unknown protocol: %s", name); 2168 |
2169 case Q_PROTOCHAIN: 2170 real_proto = lookup_proto(name, proto); 2171 if (real_proto >= 0) 2172 return gen_protochain(real_proto, proto, dir); 2173 else 2174 bpf_error("unknown protocol: %s", name); 2175 2176 |
2177 case Q_UNDEF: 2178 syntax(); 2179 /* NOTREACHED */ 2180 } 2181 abort(); 2182 /* NOTREACHED */ 2183} 2184 --- 86 unchanged lines hidden (view full) --- 2271 proto = IPPROTO_UDP; 2272 else if (proto == Q_TCP) 2273 proto = IPPROTO_TCP; 2274 else if (proto == Q_DEFAULT) 2275 proto = PROTO_UNDEF; 2276 else 2277 bpf_error("illegal qualifier of 'port'"); 2278 |
2279#ifndef INET6 |
2280 return gen_port((int)v, proto, dir); |
2281#else 2282 { 2283 struct block *b; 2284 b = gen_port((int)v, proto, dir); 2285 gen_or(gen_port6((int)v, proto, dir), b); 2286 return b; 2287 } 2288#endif /* INET6 */ |
2289 2290 case Q_GATEWAY: 2291 bpf_error("'gateway' requires a name"); 2292 /* NOTREACHED */ 2293 2294 case Q_PROTO: 2295 return gen_proto((int)v, proto, dir); 2296 |
2297 case Q_PROTOCHAIN: 2298 return gen_protochain((int)v, proto, dir); 2299 |
2300 case Q_UNDEF: 2301 syntax(); 2302 /* NOTREACHED */ 2303 2304 default: 2305 abort(); 2306 /* NOTREACHED */ 2307 } 2308 /* NOTREACHED */ 2309} 2310 |
2311#ifdef INET6 |
2312struct block * |
2313gen_mcode6(s1, s2, masklen, q) 2314 register const char *s1, *s2; 2315 register int masklen; 2316 struct qual q; 2317{ 2318 struct addrinfo *res; 2319 struct in6_addr *addr; 2320 struct in6_addr mask; 2321 struct block *b; 2322 u_int32_t *a, *m; 2323 2324 if (s2) 2325 bpf_error("no mask %s supported", s2); 2326 2327 res = pcap_nametoaddr(s1); 2328 if (!res) 2329 bpf_error("invalid ip6 address %s", s1); 2330 if (res->ai_next) 2331 bpf_error("%s resolved to multiple address", s1); 2332 addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; 2333 2334 if (sizeof(mask) * 8 < masklen) 2335 bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); 2336 memset(&mask, 0xff, masklen / 8); 2337 if (masklen % 8) { 2338 mask.s6_addr[masklen / 8] = 2339 (0xff << (8 - masklen % 8)) & 0xff; 2340 } 2341 2342 a = (u_int32_t *)addr; 2343 m = (u_int32_t *)&mask; 2344 if ((a[0] & ~m[0]) || (a[1] & ~m[1]) 2345 || (a[2] & ~m[2]) || (a[3] & ~m[3])) { 2346 bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); 2347 } 2348 2349 switch (q.addr) { 2350 2351 case Q_DEFAULT: 2352 case Q_HOST: 2353 if (masklen != 128) 2354 bpf_error("Mask syntax for networks only"); 2355 /* FALLTHROUGH */ 2356 2357 case Q_NET: 2358 b = gen_host6(addr, &mask, q.proto, q.dir); 2359 freeaddrinfo(res); 2360 return b; 2361 2362 default: 2363 bpf_error("invalid qualifier against IPv6 address"); 2364 /* NOTREACHED */ 2365 } 2366} 2367#endif /*INET6*/ 2368 2369struct block * |
2370gen_ecode(eaddr, q) 2371 register const u_char *eaddr; 2372 struct qual q; 2373{ 2374 if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { 2375 if (linktype == DLT_EN10MB) 2376 return gen_ehostop(eaddr, (int)q.dir); 2377 if (linktype == DLT_FDDI) --- 81 unchanged lines hidden (view full) --- 2459 case Q_ARP: 2460 case Q_RARP: 2461 case Q_ATALK: 2462 case Q_DECNET: 2463 case Q_SCA: 2464 case Q_LAT: 2465 case Q_MOPRC: 2466 case Q_MOPDL: |
2467#ifdef INET6 2468 case Q_IPV6: 2469#endif |
2470 /* XXX Note that we assume a fixed link header here. */ 2471 s = xfer_to_x(index); 2472 tmp = new_stmt(BPF_LD|BPF_IND|size); 2473 tmp->s.k = off_nl; 2474 sappend(s, tmp); 2475 sappend(index->s, s); 2476 2477 b = gen_proto_abbrev(proto); 2478 if (index->b) 2479 gen_and(index->b, b); 2480 index->b = b; 2481 break; 2482 2483 case Q_TCP: 2484 case Q_UDP: 2485 case Q_ICMP: 2486 case Q_IGMP: 2487 case Q_IGRP: |
2488 case Q_PIM: |
2489 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); 2490 s->s.k = off_nl; 2491 sappend(s, xfer_to_a(index)); 2492 sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); 2493 sappend(s, new_stmt(BPF_MISC|BPF_TAX)); 2494 sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); 2495 tmp->s.k = off_nl; 2496 sappend(index->s, s); 2497 2498 gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); 2499 if (index->b) 2500 gen_and(index->b, b); |
2501#ifdef INET6 2502 gen_and(gen_proto_abbrev(Q_IP), b); 2503#endif |
2504 index->b = b; 2505 break; |
2506#ifdef INET6 2507 case Q_ICMPV6: 2508 bpf_error("IPv6 upper-layer protocol is not supported by proto[x]"); 2509 /*NOTREACHED*/ 2510#endif |
2511 } 2512 index->regno = regno; 2513 s = new_stmt(BPF_ST); 2514 s->s.k = regno; 2515 sappend(index->s, s); 2516 2517 return index; 2518} --- 309 unchanged lines hidden (view full) --- 2828 break; 2829 2830 case Q_IP: 2831 b0 = gen_linktype(ETHERTYPE_IP); 2832 b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); 2833 b1->s.code = JMP(BPF_JGE); 2834 gen_and(b0, b1); 2835 return b1; |
2836 2837#ifdef INET6 2838 case Q_IPV6: 2839 b0 = gen_linktype(ETHERTYPE_IPV6); 2840 b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255); 2841 gen_and(b0, b1); 2842 return b1; 2843#endif /* INET6 */ |
2844 } 2845 bpf_error("only IP multicast filters supported on ethernet/FDDI"); 2846} 2847 2848/* 2849 * generate command for inbound/outbound. It's here so we can 2850 * make it link-type specific. 'dir' = 0 implies "inbound", 2851 * = 1 implies "outbound". --- 13 unchanged lines hidden --- |