arprefresh: document the BPF program to make it readable
[olsrd.git] / lib / arprefresh / src / olsrd_arprefresh.c
index 8282dcf..cdcad72 100644 (file)
@@ -166,23 +166,30 @@ olsrd_plugin_init(void)
     struct sock_fprog filter;
     struct sock_filter BPF_code[] = {
       /* tcpdump -s [sizeof(arprefresh_buf)] -ni lo udp and dst port [arprefresh_portnum] -dd */
-      {0x28, 0, 0, 0x0000000c},
-      {0x15, 0, 4, 0x000086dd},
-      {0x30, 0, 0, 0x00000014},
-      {0x15, 0, 11, 0x00000011},
-      {0x28, 0, 0, 0x00000038},
-      {0x15, 8, 9, arprefresh_portnum},
-      {0x15, 0, 8, 0x00000800},
-      {0x30, 0, 0, 0x00000017},
-      {0x15, 0, 6, 0x00000011},
-      {0x28, 0, 0, 0x00000014},
-      {0x45, 4, 0, 0x00001fff},
-      {0xb1, 0, 0, 0x0000000e},
-      {0x48, 0, 0, 0x00000010},
-      {0x15, 0, 1, arprefresh_portnum},
-      {0x6, 0, 0, sizeof(arprefresh_buf)}
-      ,
-      {0x6, 0, 0, 0x00000000}
+
+      /* Note: This program assumes NON-VLAN */
+      /* See also http://www.unix.com/man-page/FreeBSD/4/bpf/ */
+      /*      code                          jump-true jump-false generic-multiuse-field */
+             {BPF_LD  | BPF_H    | BPF_ABS , 0,        0,         0x0000000c},             // 0x28: A <- P[k:2], get 2-bytes from offset 0x0c : get Ethernet type
+
+/* test6  */ {BPF_JMP | BPF_JEQ  | BPF_K   , 0,        4,         0x000086dd},             // 0x15: pc += (A == k) ? ipv6 : test4             : IPv6?
+/* ipv6   */ {BPF_LD  | BPF_B    | BPF_ABS , 0,        0,         0x00000014},             // 0x30: A <- P[k:1], get 1-byte from offset 0x14  : get IPv6 protocol/next header
+             {BPF_JMP | BPF_JEQ  | BPF_K   , 0,        11,        0x00000011},             // 0x15: pc += (A == k) ? udp6 : ignore            : UDP?
+/* udp6   */ {BPF_LD  | BPF_H    | BPF_ABS , 0,        0,         0x00000038},             // 0x28: A <- P[k:2], get 2-bytes from offset 0x38 : get UDP destination port
+             {BPF_JMP | BPF_JEQ  | BPF_K   , 8,        9,         arprefresh_portnum},     // 0x15: pc += (A == k) ? ok : ignore              : sent to port arprefresh_portnum?
+
+/* test4  */ {BPF_JMP | BPF_JEQ  | BPF_K   , 0,        8,         0x00000800},             // 0x15: pc += (A == k) ? ipv4 : ignore            : IPv4?
+/* ipv4   */ {BPF_LD  | BPF_B    | BPF_ABS , 0,        0,         0x00000017},             // 0x30: A <- P[k:1], get 1-byte from offset 0x17  : get IPv4 protocol
+             {BPF_JMP | BPF_JEQ  | BPF_K   , 0,        6,         0x00000011},             // 0x15: pc += (A == k) ? udp4 : ignore            : UDP?
+/* udp4   */ {BPF_LD  | BPF_H    | BPF_ABS , 0,        0,         0x00000014},             // 0x28: A <- P[k:2], get 2-bytes from offset 0x14 : get fragment offset
+             {BPF_JMP | BPF_JSET | BPF_K   , 4,        0,         0x00001fff},             // 0x45: pc += (A & k) ? ignore : nofrag           : is this a fragment?
+/* nofrag */ {BPF_LDX | BPF_B    | BPF_MSH , 0,        0,         0x0000000e},             // 0xb1: X <- 4*(P[k:1]&0xf)                       : get the IP header length in bytes
+             {BPF_LD  | BPF_H    | BPF_IND , 0,        0,         0x00000010},             // 0x48: A <- P[X+k:2]                             : get UDP destination port
+             {BPF_JMP | BPF_JEQ  | BPF_K   , 0,        1,         arprefresh_portnum},     // 0x15: pc += (A == k) ? ok : ignore              : sent to port arprefresh_portnum?
+
+/* ok     */ {BPF_RET | BPF_K              , 0,        0,         sizeof(arprefresh_buf)}, //                                                 : accept sizeof(arprefresh_buf) bytes (all headers)
+/* ignore */ {BPF_RET | BPF_K              , 0,        0,         0x00000000}              //                                                 : accept 0 bytes
+
     };
     filter.len = sizeof(BPF_code) / sizeof(BPF_code[0]);
     filter.filter = BPF_code;