summaryrefslogtreecommitdiff
path: root/common/bpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/bpf.c')
-rw-r--r--common/bpf.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/common/bpf.c b/common/bpf.c
index dc41f809..16076fea 100644
--- a/common/bpf.c
+++ b/common/bpf.c
@@ -192,12 +192,51 @@ struct bpf_insn dhcp_bpf_filter [] = {
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
/* If we passed all the tests, ask for the whole packet. */
- BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+ BPF_STMT (BPF_RET + BPF_K, (u_int)-1),
/* Otherwise, drop it. */
- BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT (BPF_RET + BPF_K, 0),
};
+#if defined(RELAY_PORT)
+/*
+ * For relay port extension
+ */
+struct bpf_insn dhcp_bpf_relay_filter [] = {
+ /* Make sure this is an IP packet... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10),
+
+ /* Make sure it's a UDP packet... */
+ BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
+
+ /* Make sure this isn't a fragment... */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0),
+
+ /* Get the IP header length... */
+ BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
+
+ /* Make sure it's to the right port... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 2, 0), /* patch */
+
+ /* relay can have an alternative port... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
+
+ /* If we passed all the tests, ask for the whole packet. */
+ BPF_STMT (BPF_RET + BPF_K, (u_int)-1),
+
+ /* Otherwise, drop it. */
+ BPF_STMT (BPF_RET + BPF_K, 0),
+};
+
+int dhcp_bpf_relay_filter_len =
+ sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn);
+#endif
+
#if defined (DEC_FDDI)
struct bpf_insn *bpf_fddi_filter = NULL;
#endif
@@ -309,7 +348,19 @@ void if_register_receive (info)
/* Patch the server port into the BPF program...
XXX changes to filter program may require changes
to the insn number(s) used below! XXX */
- dhcp_bpf_filter [8].k = ntohs (local_port);
+#if defined(RELAY_PORT)
+ if (relay_port) {
+ /*
+ * If user defined relay UDP port, we need to filter
+ * also on the user UDP port.
+ */
+ p.bf_len = dhcp_bpf_relay_filter_len;
+ p.bf_insns = dhcp_bpf_relay_filter;
+
+ dhcp_bpf_relay_filter [10].k = ntohs (relay_port);
+ }
+#endif
+ p.bf_insns [8].k = ntohs (local_port);
if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
log_fatal ("Can't install packet filter program: %m");