From 7d820165825b4931f0f4f744b762fe25515067b7 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 7 May 2014 10:16:18 -0400 Subject: [PATCH] implement source address checking - kernel part --- kernel-module/xt_MEDIAPROXY.c | 30 +++++++++++++++++++++++++++--- kernel-module/xt_MEDIAPROXY.h | 11 ++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/kernel-module/xt_MEDIAPROXY.c b/kernel-module/xt_MEDIAPROXY.c index 2582788d5..ec76e1576 100644 --- a/kernel-module/xt_MEDIAPROXY.c +++ b/kernel-module/xt_MEDIAPROXY.c @@ -2092,7 +2092,7 @@ static inline int is_dtls(struct rtp_parsed *r) { return 1; } -static unsigned int mediaproxy46(struct sk_buff *skb, struct mediaproxy_table *t) { +static unsigned int mediaproxy46(struct sk_buff *skb, struct mediaproxy_table *t, struct mp_address *src) { struct udphdr *uh; struct mediaproxy_target *g; struct sk_buff *skb2; @@ -2114,6 +2114,8 @@ static unsigned int mediaproxy46(struct sk_buff *skb, struct mediaproxy_table *t DBG("udp payload = %u\n", datalen); skb_trim(skb, datalen); + src->port = ntohs(uh->source); + g = get_target(t, ntohs(uh->dest)); if (!g) goto skip2; @@ -2141,6 +2143,17 @@ static unsigned int mediaproxy46(struct sk_buff *skb, struct mediaproxy_table *t goto skip1; not_stun: + if (g->target.src_mismatch == MSM_IGNORE) + goto src_check_ok; + if (!memcmp(&g->target.expected_src, src, sizeof(*src))) + goto src_check_ok; + if (g->target.src_mismatch == MSM_PROPAGATE) + goto skip1; + /* MSM_DROP */ + err = -1; + goto out; + +src_check_ok: parse_rtp(&rtp, skb); if (rtp.ok) { if (g->target.rtp_only) @@ -2186,6 +2199,7 @@ not_rtp: err = send_proxy_packet(skb, &g->target.src_addr, &g->target.dst_addr, g->target.tos); +out: spin_lock_irqsave(&g->stats_lock, flags); if (err) g->stats.errors++; @@ -2226,6 +2240,7 @@ static unsigned int mediaproxy4(struct sk_buff *oskb, const struct xt_action_par struct sk_buff *skb; struct iphdr *ih; struct mediaproxy_table *t; + struct mp_address src; t = get_table(pinfo->id); if (!t) @@ -2241,7 +2256,11 @@ static unsigned int mediaproxy4(struct sk_buff *oskb, const struct xt_action_par if (ih->protocol != IPPROTO_UDP) goto skip2; - return mediaproxy46(skb, t); + memset(&src, 0, sizeof(src)); + src.family = AF_INET; + src.u.ipv4 = ih->saddr; + + return mediaproxy46(skb, t, &src); skip2: kfree_skb(skb); @@ -2263,6 +2282,7 @@ static unsigned int mediaproxy6(struct sk_buff *oskb, const struct xt_action_par struct sk_buff *skb; struct ipv6hdr *ih; struct mediaproxy_table *t; + struct mp_address src; t = get_table(pinfo->id); if (!t) @@ -2278,7 +2298,11 @@ static unsigned int mediaproxy6(struct sk_buff *oskb, const struct xt_action_par if (ih->nexthdr != IPPROTO_UDP) goto skip2; - return mediaproxy46(skb, t); + memset(&src, 0, sizeof(src)); + src.family = AF_INET6; + memcpy(&src.u.ipv6, &ih->saddr, sizeof(src.u.ipv6)); + + return mediaproxy46(skb, t, &src); skip2: kfree_skb(skb); diff --git a/kernel-module/xt_MEDIAPROXY.h b/kernel-module/xt_MEDIAPROXY.h index 5e7b56412..6c6e00a95 100644 --- a/kernel-module/xt_MEDIAPROXY.h +++ b/kernel-module/xt_MEDIAPROXY.h @@ -41,6 +41,7 @@ enum mediaproxy_hmac { __MPH_LAST }; + struct mediaproxy_srtp { enum mediaproxy_cipher cipher; enum mediaproxy_hmac hmac; @@ -53,10 +54,18 @@ struct mediaproxy_srtp { }; +enum mediaproxy_src_mismatch { + MSM_IGNORE = 0, /* process packet as normal */ + MSM_DROP, /* drop packet */ + MSM_PROPAGATE, /* propagate to userspace daemon */ +}; + struct mediaproxy_target_info { u_int16_t target_port; + struct mp_address expected_src; /* for incoming packets */ + enum mediaproxy_src_mismatch src_mismatch; - struct mp_address src_addr; + struct mp_address src_addr; /* for outgoing packets */ struct mp_address dst_addr; struct mp_address mirror_addr;