From 01692d9e13bab1a3faf011878aff6ae45c7e9faa Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Wed, 18 Apr 2018 13:59:20 +0200 Subject: [PATCH] xtables-addons: rtsp: update source in expected RTP connection Update source IP of the expected RTP connection according to the SOURCE attribute value if present in the RTSP SETUP REPLY message. Signed-off-by: Hans Dedecker --- net/xtables-addons/Makefile | 2 +- .../patches/100-add-rtsp-conntrack.patch | 159 ++++++++++++++++-- 2 files changed, 145 insertions(+), 16 deletions(-) diff --git a/net/xtables-addons/Makefile b/net/xtables-addons/Makefile index b8d8abe495..5c78ff891f 100644 --- a/net/xtables-addons/Makefile +++ b/net/xtables-addons/Makefile @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=xtables-addons PKG_VERSION:=2.14 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_HASH:=d215a9a8b8e66aae04b982fa2e1228e8a71e7dfe42320df99e34e5000cbdf152 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz diff --git a/net/xtables-addons/patches/100-add-rtsp-conntrack.patch b/net/xtables-addons/patches/100-add-rtsp-conntrack.patch index 917baf41a7..7ac2cc5638 100644 --- a/net/xtables-addons/patches/100-add-rtsp-conntrack.patch +++ b/net/xtables-addons/patches/100-add-rtsp-conntrack.patch @@ -235,7 +235,7 @@ +#endif /* _NETFILTER_MIME_H */ --- /dev/null +++ b/extensions/rtsp/nf_conntrack_rtsp.c -@@ -0,0 +1,604 @@ +@@ -0,0 +1,732 @@ +/* + * RTSP extension for IP connection tracking + * (C) 2003 by Tom Marshall @@ -254,6 +254,9 @@ + * 2018-04-17: Alin Nastac + * Hans Dedecker + * - use IP address read from SETUP URI in expected connections ++ * 2018-04-18: Hans Dedecker ++ * - update RTP expected connection source IP based on SOURCE ++ * in the SETUP reply message + * + * based on ip_conntrack_irc.c + * @@ -402,13 +405,14 @@ +} + +/* -+ * Find lo/hi client ports (if any) in transport header ++ * Find lo/hi client ports and/or source (if any) in transport header + * In: + * ptcp, tcplen = packet + * tranoff, tranlen = buffer to search + * + * Out: + * pport_lo, pport_hi = lo/hi ports (host endian) ++ * srvaddr + * + * Returns nonzero if any client ports found + * @@ -485,6 +489,17 @@ + } + rc = 1; + } ++ } else if (strncmp(ptran+off, "source=", 7) == 0) { ++ uint srcaddrlen; ++ ++ off += 7; ++ srcaddrlen = nextfieldoff - off - 1; ++ ++ if (in4_pton(ptran + off, srcaddrlen, ++ (u8 *)&prtspexp->srvaddr.in, ++ -1, NULL)) ++ pr_debug("source found : %pI4\n", ++ &prtspexp->srvaddr.ip); + } + + /* @@ -687,11 +702,120 @@ + + +static inline int -+help_in(struct sk_buff *skb, size_t pktlen, -+ struct nf_conn* ct, enum ip_conntrack_info ctinfo) -+{ -+ return NF_ACCEPT; -+} ++help_in(struct sk_buff *skb, unsigned char *rb_ptr, unsigned int datalen, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) ++ struct nf_conn *ct, enum ip_conntrack_info ctinfo, ++ unsigned int protoff) ++#else ++ struct nf_conn *ct, enum ip_conntrack_info ctinfo) ++#endif ++ { ++ struct ip_ct_rtsp_expect expinfo; ++ union nf_inet_addr srvaddr; ++ int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */ ++ int len; ++ char* pdata = rb_ptr; ++ uint dataoff = 0; ++ int ret = NF_ACCEPT; ++ u_int8_t family; ++ struct nf_conntrack_expect *exp_ct = NULL; ++ struct nf_conntrack_tuple t; ++ struct net *net = nf_ct_net(ct); ++ ++ memset(&expinfo, 0, sizeof(expinfo)); ++ ++ while (dataoff < datalen) { ++ uint cmdoff = dataoff; ++ uint hdrsoff = 0; ++ uint hdrslen = 0; ++ uint cseqoff = 0; ++ uint cseqlen = 0; ++ uint transoff = 0; ++ uint translen = 0; ++ ++ if (!rtsp_parse_message(pdata, datalen, &dataoff, ++ &hdrsoff, &hdrslen, ++ &cseqoff, &cseqlen, ++ &transoff, &translen)) ++ break; /* not a valid message */ ++ ++ if (strncmp(pdata+cmdoff, "RTSP/", 5) == 0 && translen) { ++ union nf_inet_addr zeroaddr; ++ ++ memset(&zeroaddr, 0, sizeof(zeroaddr)); ++ ++ if (!rtsp_parse_transport(pdata+transoff, translen, &expinfo)) ++ continue; ++ ++ srvaddr = expinfo.srvaddr; ++ ++ if (nf_inet_addr_cmp(&srvaddr, &ct->tuplehash[dir].tuple.src.u3) || ++ nf_inet_addr_cmp(&srvaddr, &zeroaddr)) ++ continue; ++ } else ++ continue; /* not valid RTSP reply */ ++ ++ if (expinfo.loport == 0) { ++ pr_debug("no udp transports found\n"); ++ continue; /* no udp transports found */ ++ } ++ ++ family = nf_ct_l3num(ct); ++ if (family == AF_INET) ++ len = 4; ++ else ++ len = 16; ++ ++ /* replace rtp expect src addr */ ++ t.src.l3num = family; ++ t.dst.protonum = IPPROTO_UDP; ++ ++ memcpy(&t.src.u3, &ct->tuplehash[dir].tuple.src.u3, len); ++ if (sizeof(t.src.u3) > len) ++ /* address needs to be cleared for nf_ct_tuple_equal */ ++ memset((void *)&t.src.u3 + len, 0, sizeof(t.src.u3) - len); ++ ++ t.src.u.all = 0; ++ ++ memcpy(&t.dst.u3, &ct->tuplehash[dir].tuple.dst.u3, len); ++ if (sizeof(t.dst.u3) > len) ++ /* address needs to be cleared for nf_ct_tuple_equal */ ++ memset((void *)&t.dst.u3 + len, 0, sizeof(t.dst.u3) - len); ++ ++ t.dst.u.all = htons(expinfo.loport); ++ ++ /* get the rtp expect and replace the srcaddr with RTP server addr */ ++ exp_ct = nf_ct_expect_find_get(net, nf_ct_zone(ct), &t); ++ if (exp_ct) { ++ memcpy(&exp_ct->tuple.src.u3, &srvaddr, len); ++ if (sizeof(exp_ct->tuple.src.u3) > len) ++ /* address needs to be cleared for nf_ct_tuple_equal */ ++ memset((void *)&exp_ct->tuple.src.u3 + len, 0, ++ sizeof(exp_ct->tuple.src.u3) - len); ++ } else ++ goto out; ++ ++ /* replace rtcp expect src addr */ ++ if (expinfo.pbtype == pb_range) { ++ t.dst.u.all = htons(expinfo.hiport); ++ ++ /* get the rtcp expect and replace the srcaddr with RTP server addr */ ++ exp_ct = nf_ct_expect_find_get(net, nf_ct_zone(ct), &t); ++ if (exp_ct) { ++ memcpy(&exp_ct->tuple.src.u3, &srvaddr, len); ++ if (sizeof(exp_ct->tuple.src.u3) > len) ++ /* address needs to be cleared for nf_ct_tuple_equal */ ++ memset((void *)&exp_ct->tuple.src.u3 + len, 0, ++ sizeof(exp_ct->tuple.src.u3) - len); ++ } else ++ goto out; ++ } ++ ++ goto out; ++ } ++out: ++ return ret; ++ } + +static int help(struct sk_buff *skb, unsigned int protoff, + struct nf_conn *ct, enum ip_conntrack_info ctinfo) @@ -748,7 +872,11 @@ + case IP_CT_DIR_REPLY: + pr_debug("IP_CT_DIR_REPLY\n"); + /* inbound packet: server->client */ -+ ret = NF_ACCEPT; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) ++ ret = help_in(skb, rb_ptr, datalen, ct, ctinfo, protoff); ++#else ++ ret = help_in(skb, rb_ptr, datalen, ct, ctinfo); ++#endif + break; + } + @@ -842,7 +970,7 @@ +module_exit(fini); --- /dev/null +++ b/extensions/rtsp/nf_conntrack_rtsp.h -@@ -0,0 +1,72 @@ +@@ -0,0 +1,73 @@ +/* + * RTSP extension for IP connection tracking. + * (C) 2003 by Tom Marshall @@ -889,13 +1017,14 @@ + */ +struct ip_ct_rtsp_expect +{ -+ u_int32_t len; /* length of header block */ -+ portblock_t pbtype; /* Type of port block that was requested */ -+ u_int16_t loport; /* Port that was requested, low or first */ -+ u_int16_t hiport; /* Port that was requested, high or second */ ++ u_int32_t len; /* length of header block */ ++ portblock_t pbtype; /* Type of port block that was requested */ ++ u_int16_t loport; /* Port that was requested, low or first */ ++ u_int16_t hiport; /* Port that was requested, high or second */ ++ union nf_inet_addr srvaddr; /* src address in SETUP reply */ +#if 0 -+ uint method; /* RTSP method */ -+ uint cseq; /* CSeq from request */ ++ uint method; /* RTSP method */ ++ uint cseq; /* CSeq from request */ +#endif +}; +