diff options
Diffstat (limited to 'minecproxy/igmp.c')
-rw-r--r-- | minecproxy/igmp.c | 115 |
1 files changed, 73 insertions, 42 deletions
diff --git a/minecproxy/igmp.c b/minecproxy/igmp.c index f1d380d..f3579f4 100644 --- a/minecproxy/igmp.c +++ b/minecproxy/igmp.c @@ -345,7 +345,8 @@ igmp_parse(struct igmp *igmp) body_len -= sizeof(*record); pos += sizeof(*record); - if (body_len < record->nsrcs * sizeof(uint32_t) + record->auxlen) { + if (body_len < + (record->nsrcs * sizeof(uint32_t) + record->auxlen)) { error("IGMPv3 too short"); break; } @@ -364,10 +365,12 @@ igmp_parse(struct igmp *igmp) } /* Yes, EXCL, not INCL, see RFC3376 */ + /* clang-format off */ if ((htonl(record->addr) == cinet_addr(224,0,2,60)) && ((record->type == IGMP_V3_REC_MODE_IS_EXCL) || (record->type == IGMP_V3_REC_MODE_CH_EXCL))) igmp_match(); + /* clang-format on */ body_len -= record->auxlen; pos += record->auxlen; @@ -409,7 +412,7 @@ igmp_read_cb(struct uring_task *task, int res) task->tbuf->len = res; - if (task->saddr.storage.ss_family == AF_PACKET || + if (task->saddr.st.ss_family == AF_PACKET || task->saddr.ll.sll_protocol == htons(ETH_P_IP)) igmp_parse(igmp); else @@ -450,46 +453,74 @@ void igmp_init() { 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 iphdr), 1, 0), /* A < sizeof(iphdr) */ - BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */ - - 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, 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, 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, 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, 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, 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 != ip->tot_len */ - BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */ - - BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1), /* accept packet */ - }; + /* A <- packet length */ + BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), + /* A < sizeof(iphdr) */ + BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct iphdr), 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* A <- version + ihl */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 0 /* iphdr[0] */), + /* A <- A >> 4 (version) */ + BPF_STMT(BPF_ALU + BPF_RSH + BPF_K, 4), + /* A != 4 */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x04, 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* A <- ip protocol */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct iphdr, protocol)), + /* A != IPPROTO_IGMP */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_IGMP, 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* A <- ip dst addr */ + BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct iphdr, daddr)), + /* A != 224.0.2.60 */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, chtobe32(cinet_addr(224,0,2,60)), 2, 0), + /* A != 224.0.0.22 */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, chtobe32(cinet_addr(224,0,0,22)), 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* X <- pkt->ihl * 4 */ + BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0 /* iphdr[0] */), + /* A <- 20 */ + BPF_STMT(BPF_LD + BPF_IMM, 20), + /* A > X */ + BPF_JUMP(BPF_JMP + BPF_JGT + BPF_X, 0, 0, 1), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* A <- ip tot_len */ + BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct iphdr, tot_len)), + /* A <= ip->ihl * 4 */ + BPF_JUMP(BPF_JMP + BPF_JGT + BPF_X, 0, 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + /* A <- A - X (bodylen) */ + BPF_STMT(BPF_ALU + BPF_SUB + BPF_X, 0), + /* A < 8 */ + BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, 8, 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* A <- ip->tot_len */ + BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct iphdr, tot_len)), + /* X <- A */ + BPF_STMT(BPF_MISC + BPF_TAX, 0), + /* A <- packet length */ + BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), + /* A != ip->tot_len */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), + /* drop packet */ + BPF_STMT(BPF_RET + BPF_K, 0), + + /* accept packet */ + BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1), + }; static const struct sock_fprog fprog = { .len = ARRAY_SIZE(filter), .filter = (struct sock_filter*) filter, |