summaryrefslogtreecommitdiff
path: root/minecproxy/igmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'minecproxy/igmp.c')
-rw-r--r--minecproxy/igmp.c115
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,