summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-06-16 10:42:56 +0200
committerDavid Härdeman <david@hardeman.nu>2020-06-16 10:42:56 +0200
commit18a5dcf9ef6f9bde77326bb363ec61bbf6b5e587 (patch)
tree48b40ef5ee8816e499bba8017fbcc86bd0ddbdde
parent1ec5e43c9aef58e134f570946e280956db4ef189 (diff)
Use SOCK_DGRAM instead of SOCK_RAW in igmp to not have to deal with ethernet headers
-rw-r--r--igmp.c36
1 files changed, 13 insertions, 23 deletions
diff --git a/igmp.c b/igmp.c
index b3d7d2c..ab55aef 100644
--- a/igmp.c
+++ b/igmp.c
@@ -175,18 +175,14 @@ igmp_match()
}
static void
-igmp_parse(struct cfg *cfg, struct igmp *igmp, int res)
+igmp_parse(struct cfg *cfg, struct igmp *igmp)
{
- char *buf = &igmp->task.tbuf->buf[ETH_HDR_LEN];
+ char *buf = igmp->task.tbuf->buf;
+ size_t len = igmp->task.tbuf->len;
struct ipv4_hdr *hdr = (struct ipv4_hdr *)buf;
size_t body_len;
union igmp_msg *igmp_msg;
- size_t len;
- if (res < ETH_HDR_LEN)
- return;
-
- len = res - ETH_HDR_LEN;
if (len <= IPV4_MIN_HDR_LEN)
return;
@@ -399,7 +395,7 @@ igmp_read_cb(struct cfg *cfg, struct uring_task *task, int res)
if (task->addr.storage.ss_family == AF_PACKET ||
task->addr.ll.sll_protocol == htons(ETH_P_IP))
- igmp_parse(cfg, igmp, res);
+ igmp_parse(cfg, igmp);
else
fprintf(stderr, "Invalid packet type received\n");
@@ -444,46 +440,41 @@ igmp_init(struct cfg *cfg)
{
static const struct sock_filter filter[] = {
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
- BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ethhdr) + sizeof(struct iphdr), 1, 0), /* A < eth + ip */
+ BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct iphdr), 1, 0), /* A < sizeof(iphdr) */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_proto)), /* A <- ethernet protocol */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0), /* A != ETHERTYPE_IP */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
-
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, sizeof(struct ethhdr) + 0 /* iphdr[0] */), /* A <- version + ihl */
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 0 /* iphdr[0] */), /* A <- version + ihl */
BPF_STMT(BPF_ALU + BPF_RSH + BPF_K, 4), /* A <- A >> 4 (version) */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x04, 1, 0), /* A != 4 */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, sizeof(struct ethhdr) + offsetof(struct iphdr, protocol)), /* A <- ip protocol */
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct iphdr, protocol)), /* A <- ip protocol */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_IGMP, 1, 0), /* A != IPPROTO_IGMP */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, sizeof(struct ethhdr) + offsetof(struct iphdr, daddr)), /* A <- ip dst addr */
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct iphdr, daddr)), /* A <- ip dst addr */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, chtobe32(cinet_addr(224,0,2,60)), 2, 0), /* A != 224.0.2.60 */
//BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0xe000023c, 2, 0), /* A != 224.0.2.60 */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, chtobe32(cinet_addr(224,0,0,22)), 1, 0), /* A != 224.0.0.22 */
//BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0xe0000016, 1, 0), /* A != 224.0.0.22 */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, sizeof(struct ethhdr) + 0 /* iphdr[0] */), /* X <- pkt->ihl * 4 */
+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0 /* iphdr[0] */), /* X <- pkt->ihl * 4 */
BPF_STMT(BPF_LD + BPF_IMM, 20), /* A <- 20 */
BPF_JUMP(BPF_JMP + BPF_JGT + BPF_X, 0, 0, 1), /* A > X */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, sizeof(struct ethhdr) + offsetof(struct iphdr, tot_len)), /* A <- ip tot_len */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct iphdr, tot_len)), /* A <- ip tot_len */
BPF_JUMP(BPF_JMP + BPF_JGT + BPF_X, 0, 1, 0), /* A <= ip->ihl * 4 */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
BPF_STMT(BPF_ALU + BPF_SUB + BPF_X, 0), /* A <- A - X (bodylen) */
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, 8, 1, 0), /* A < 8 */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, sizeof(struct ethhdr) + offsetof(struct iphdr, tot_len)), /* A <- ip->tot_len */
- BPF_STMT(BPF_ALU + BPF_ADD + BPF_K, sizeof(struct ethhdr)), /* A <- A + sizeof(struct ethhdr) */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct iphdr, tot_len)), /* A <- ip->tot_len */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), /* A != sizeof(ethhdr) + ip->tot_len */
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), /* A != ip->tot_len */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1), /* accept packet */
@@ -508,7 +499,7 @@ igmp_init(struct cfg *cfg)
* Kernel limitation, must be ETH_P_ALL, not ETH_P_IP or we won't get
* outgoing packets, https://lkml.org/lkml/1999/12/23/112
*/
- sfd = socket(AF_PACKET, SOCK_RAW | SOCK_CLOEXEC, htons(ETH_P_ALL));
+ sfd = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_ALL));
if (sfd < 0) {
perror("igmp socket");
goto out_free;
@@ -547,7 +538,6 @@ igmp_init(struct cfg *cfg)
*/
/* can't set .sll_protocol to htons(ETH_P_IP), see comment above */
-
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
goto out_fd;