xtables-addons: rtsp: support destination format address:port
authorHans Dedecker <[email protected]>
Fri, 3 Aug 2018 17:12:55 +0000 (19:12 +0200)
committerHans Dedecker <[email protected]>
Mon, 6 Aug 2018 15:52:40 +0000 (17:52 +0200)
RFC2326 specifies the attribute client_port as the RTP/RTCP port pair on
which the client has chosen to receive media data and control info;
however some clients (mostly STBs) embed the client_port value in the
destination attribute in the form of destination=<address:port> without
specifying the client_port attribute in the SETUP message.
To support such clients check if the destination attribute contains a
port value and use it as port value for the expected RTP connection.

Signed-off-by: Hans Dedecker <[email protected]>
net/xtables-addons/Makefile
net/xtables-addons/patches/100-add-rtsp-conntrack.patch

index 5c78ff891f9af095e1cfc6ae05a25b0c6d5851ff..17da4103f3438f49f4a43ed8b7fa58be9f9dccd3 100644 (file)
@@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=xtables-addons
 PKG_VERSION:=2.14
-PKG_RELEASE:=4
+PKG_RELEASE:=5
 PKG_HASH:=d215a9a8b8e66aae04b982fa2e1228e8a71e7dfe42320df99e34e5000cbdf152
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
index e280ec447c29d063b5f56ae73d067afe690172bc..08ed4e84512aa807adf06b92479afea657d88711 100644 (file)
 +#endif /* _NETFILTER_MIME_H */
 --- /dev/null
 +++ b/extensions/rtsp/nf_conntrack_rtsp.c
-@@ -0,0 +1,735 @@
+@@ -0,0 +1,761 @@
 +/*
 + * RTSP extension for IP connection tracking
 + * (C) 2003 by Tom Marshall <tmarshall at real.com>
 + * 2018-04-18: Hans Dedecker <dedeckeh at gmail.com>
 + *       - update RTP expected connection source IP based on SOURCE
 + *         in the SETUP reply message
++ * 2018-08-03: Alin Nastac <alin.nastac at gmail.com>
++ *             Hans Dedecker <dedeckeh at gmail.com>
++ *       - parse non-standard destination=address:port format
 + *
 + * based on ip_conntrack_irc.c
 + *
 +                                           -1, NULL))
 +                                      pr_debug("source found : %pI4\n",
 +                                               &prtspexp->srvaddr.ip);
++                      } else if (nextfieldoff - off > 12 && strncmp(ptran+off, "destination=", 12) == 0) {
++                              const char *psep;
++                              u_int16_t   port;
++
++                              off += 12;
++
++                              if (in4_pton(ptran+off, nextfieldoff - off - 1, (u8 *)&prtspexp->cltaddr.in, -1, NULL)) {
++                                      pr_debug("destination found : %pI4\n", &prtspexp->cltaddr.ip);
++
++                                      /*
++                                       * Some RTSP clients(mostly STBs) use non-standard destination parameters:
++                                       * destination=address:port
++                                       */
++                                      psep = memchr(ptran+off, ':', nextfieldoff-off);
++                                      if (psep != NULL && nf_strtou16(psep + 1, &port)) {
++                                              if (prtspexp->loport != 0 && prtspexp->loport != port)
++                                                      pr_debug("multiple ports found, port %hu ignored\n", port);
++                                              else {
++                                                      pr_debug("lo port found : %hu\n", port);
++                                                      prtspexp->loport = prtspexp->hiport = port;
++                                              }
++                                      }
++                              }
 +                      }
 +                      
 +                      /*
 +module_exit(fini);
 --- /dev/null
 +++ b/extensions/rtsp/nf_conntrack_rtsp.h
-@@ -0,0 +1,73 @@
+@@ -0,0 +1,74 @@
 +/*
 + * RTSP extension for IP connection tracking.
 + * (C) 2003 by Tom Marshall <tmarshall at real.com>
 +    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 */
++    union nf_inet_addr cltaddr;    /* destination address */
 +#if 0
 +    uint               method;     /* RTSP method */
 +    uint               cseq;       /* CSeq from request */
 +#endif /* _IP_CONNTRACK_RTSP_H */
 --- /dev/null
 +++ b/extensions/rtsp/nf_nat_rtsp.c
-@@ -0,0 +1,617 @@
+@@ -0,0 +1,634 @@
 +/*
 + * RTSP extension for TCP NAT alteration
 + * (C) 2003 by Tom Marshall <tmarshall at real.com>
 +      struct nf_conntrack_tuple *rtp_t;
 +
 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
-+      char szextaddr[INET6_ADDRSTRLEN];
++      char szextaddr[INET6_ADDRSTRLEN + 16];
 +#else
-+      char szextaddr[INET_ADDRSTRLEN];
++      char szextaddr[INET_ADDRSTRLEN + 16];
 +#endif
 +      uint extaddrlen;
 +      int  is_stun;
 +
 +                      pfieldend = memchr(ptran+off, ';', nextparamoff-off);
 +                      nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
++                      SKIP_WSPACE(ptran, nextfieldoff, off);
 +
-+                      if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) {
++                      if (dstact != DSTACT_NONE && nextfieldoff - off > 12 && strncmp(ptran+off, "destination=", 12) == 0) {
 +                              if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
 +                                      is_stun = 1;
 +
 +                                      uint dstreplen = 0;
 +                                      diff = dstlen;
 +                                      if (dstact == DSTACT_AUTO && !is_stun) {
-+                                              pr_debug("RTSP: replace dst addr\n");
++                                              const char* psep = memchr(ptran+off, ':', dstlen);
++                                              u_int16_t port;
++
 +                                              dstoff += 12;
 +                                              dstlen -= 13;
 +                                              pdstrep = szextaddr;
-+                                              dstreplen = extaddrlen;
-+                                              diff = nextfieldoff-off-13-extaddrlen;
++
++                                              if (psep != NULL && nf_strtou16(psep + 1, &port)) {
++                                                      pr_debug("RTSP: replace dst addr&port\n");
++
++                                                      if (port != prtspexp->loport) {
++                                                              pr_debug("multiple ports found, port %hu ignored\n", port);
++                                                              dstreplen = extaddrlen;
++                                                      } else {
++                                                              sprintf(szextaddr+extaddrlen, ":%s", rbuf1);
++                                                              dstreplen = extaddrlen+1+rbuf1len;
++                                                      }
++                                              } else {
++                                                      pr_debug("RTSP: replace dst addr\n");
++                                                      dstreplen = extaddrlen;
++                                              }
++                                              diff = nextfieldoff-off-13-dstreplen;
 +                                      }
 +
 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
 +                      pfieldend = memchr(ptran+off, ';', nextparamoff-off);
 +                      nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
 +
-+                      if (strncmp(ptran+off, "client_port=", 12) == 0) {
++                      if (nextfieldoff - off > 12 && strncmp(ptran+off, "client_port=", 12) == 0) {
 +                              u_int16_t port;
 +                              uint      numlen;
 +                              uint      origoff;