From 18a5dcf9ef6f9bde77326bb363ec61bbf6b5e587 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Tue, 16 Jun 2020 10:42:56 +0200 Subject: Use SOCK_DGRAM instead of SOCK_RAW in igmp to not have to deal with ethernet headers --- igmp.c | 36 +++++++++++++----------------------- 1 file 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; -- cgit v1.2.3