nf_nat_sip.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* SIP extension for NAT alteration.
  3. *
  4. * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
  5. * based on RR's ip_nat_ftp.c and other modules.
  6. * (C) 2007 United Security Providers
  7. * (C) 2007, 2008, 2011, 2012 Patrick McHardy <kaber@trash.net>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/inet.h>
  12. #include <linux/udp.h>
  13. #include <linux/tcp.h>
  14. #include <net/netfilter/nf_nat.h>
  15. #include <net/netfilter/nf_nat_helper.h>
  16. #include <net/netfilter/nf_conntrack_core.h>
  17. #include <net/netfilter/nf_conntrack_helper.h>
  18. #include <net/netfilter/nf_conntrack_expect.h>
  19. #include <net/netfilter/nf_conntrack_seqadj.h>
  20. #include <linux/netfilter/nf_conntrack_sip.h>
  21. #define NAT_HELPER_NAME "sip"
  22. MODULE_LICENSE("GPL");
  23. MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
  24. MODULE_DESCRIPTION("SIP NAT helper");
  25. MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME);
  26. static struct nf_conntrack_nat_helper nat_helper_sip =
  27. NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME);
  28. static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff,
  29. unsigned int dataoff,
  30. const char **dptr, unsigned int *datalen,
  31. unsigned int matchoff, unsigned int matchlen,
  32. const char *buffer, unsigned int buflen)
  33. {
  34. enum ip_conntrack_info ctinfo;
  35. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  36. struct tcphdr *th;
  37. unsigned int baseoff;
  38. if (nf_ct_protonum(ct) == IPPROTO_TCP) {
  39. th = (struct tcphdr *)(skb->data + protoff);
  40. baseoff = protoff + th->doff * 4;
  41. matchoff += dataoff - baseoff;
  42. if (!__nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
  43. protoff, matchoff, matchlen,
  44. buffer, buflen, false))
  45. return 0;
  46. } else {
  47. baseoff = protoff + sizeof(struct udphdr);
  48. matchoff += dataoff - baseoff;
  49. if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
  50. protoff, matchoff, matchlen,
  51. buffer, buflen))
  52. return 0;
  53. }
  54. /* Reload data pointer and adjust datalen value */
  55. *dptr = skb->data + dataoff;
  56. *datalen += buflen - matchlen;
  57. return 1;
  58. }
  59. static int sip_sprintf_addr(const struct nf_conn *ct, char *buffer,
  60. const union nf_inet_addr *addr, bool delim)
  61. {
  62. if (nf_ct_l3num(ct) == NFPROTO_IPV4)
  63. return sprintf(buffer, "%pI4", &addr->ip);
  64. else {
  65. if (delim)
  66. return sprintf(buffer, "[%pI6c]", &addr->ip6);
  67. else
  68. return sprintf(buffer, "%pI6c", &addr->ip6);
  69. }
  70. }
  71. static int sip_sprintf_addr_port(const struct nf_conn *ct, char *buffer,
  72. const union nf_inet_addr *addr, u16 port)
  73. {
  74. if (nf_ct_l3num(ct) == NFPROTO_IPV4)
  75. return sprintf(buffer, "%pI4:%u", &addr->ip, port);
  76. else
  77. return sprintf(buffer, "[%pI6c]:%u", &addr->ip6, port);
  78. }
  79. static int map_addr(struct sk_buff *skb, unsigned int protoff,
  80. unsigned int dataoff,
  81. const char **dptr, unsigned int *datalen,
  82. unsigned int matchoff, unsigned int matchlen,
  83. union nf_inet_addr *addr, __be16 port)
  84. {
  85. enum ip_conntrack_info ctinfo;
  86. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  87. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  88. struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
  89. char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
  90. unsigned int buflen;
  91. union nf_inet_addr newaddr;
  92. __be16 newport;
  93. if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, addr) &&
  94. ct->tuplehash[dir].tuple.src.u.udp.port == port) {
  95. newaddr = ct->tuplehash[!dir].tuple.dst.u3;
  96. newport = ct->tuplehash[!dir].tuple.dst.u.udp.port;
  97. } else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, addr) &&
  98. ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
  99. newaddr = ct->tuplehash[!dir].tuple.src.u3;
  100. newport = ct_sip_info->forced_dport ? :
  101. ct->tuplehash[!dir].tuple.src.u.udp.port;
  102. } else
  103. return 1;
  104. if (nf_inet_addr_cmp(&newaddr, addr) && newport == port)
  105. return 1;
  106. buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, ntohs(newport));
  107. return mangle_packet(skb, protoff, dataoff, dptr, datalen,
  108. matchoff, matchlen, buffer, buflen);
  109. }
  110. static int map_sip_addr(struct sk_buff *skb, unsigned int protoff,
  111. unsigned int dataoff,
  112. const char **dptr, unsigned int *datalen,
  113. enum sip_header_types type)
  114. {
  115. enum ip_conntrack_info ctinfo;
  116. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  117. unsigned int matchlen, matchoff;
  118. union nf_inet_addr addr;
  119. __be16 port;
  120. if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL,
  121. &matchoff, &matchlen, &addr, &port) <= 0)
  122. return 1;
  123. return map_addr(skb, protoff, dataoff, dptr, datalen,
  124. matchoff, matchlen, &addr, port);
  125. }
  126. static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
  127. unsigned int dataoff,
  128. const char **dptr, unsigned int *datalen)
  129. {
  130. enum ip_conntrack_info ctinfo;
  131. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  132. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  133. struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
  134. unsigned int coff, matchoff, matchlen;
  135. enum sip_header_types hdr;
  136. union nf_inet_addr addr;
  137. __be16 port;
  138. int request, in_header;
  139. /* Basic rules: requests and responses. */
  140. if (strncasecmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) {
  141. if (ct_sip_parse_request(ct, *dptr, *datalen,
  142. &matchoff, &matchlen,
  143. &addr, &port) > 0 &&
  144. !map_addr(skb, protoff, dataoff, dptr, datalen,
  145. matchoff, matchlen, &addr, port)) {
  146. nf_ct_helper_log(skb, ct, "cannot mangle SIP message");
  147. return NF_DROP;
  148. }
  149. request = 1;
  150. } else
  151. request = 0;
  152. if (nf_ct_protonum(ct) == IPPROTO_TCP)
  153. hdr = SIP_HDR_VIA_TCP;
  154. else
  155. hdr = SIP_HDR_VIA_UDP;
  156. /* Translate topmost Via header and parameters */
  157. if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
  158. hdr, NULL, &matchoff, &matchlen,
  159. &addr, &port) > 0) {
  160. unsigned int olen, matchend, poff, plen, buflen, n;
  161. char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
  162. /* We're only interested in headers related to this
  163. * connection */
  164. if (request) {
  165. if (!nf_inet_addr_cmp(&addr,
  166. &ct->tuplehash[dir].tuple.src.u3) ||
  167. port != ct->tuplehash[dir].tuple.src.u.udp.port)
  168. goto next;
  169. } else {
  170. if (!nf_inet_addr_cmp(&addr,
  171. &ct->tuplehash[dir].tuple.dst.u3) ||
  172. port != ct->tuplehash[dir].tuple.dst.u.udp.port)
  173. goto next;
  174. }
  175. olen = *datalen;
  176. if (!map_addr(skb, protoff, dataoff, dptr, datalen,
  177. matchoff, matchlen, &addr, port)) {
  178. nf_ct_helper_log(skb, ct, "cannot mangle Via header");
  179. return NF_DROP;
  180. }
  181. matchend = matchoff + matchlen + *datalen - olen;
  182. /* The maddr= parameter (RFC 2361) specifies where to send
  183. * the reply. */
  184. if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
  185. "maddr=", &poff, &plen,
  186. &addr, true) > 0 &&
  187. nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3) &&
  188. !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3)) {
  189. buflen = sip_sprintf_addr(ct, buffer,
  190. &ct->tuplehash[!dir].tuple.dst.u3,
  191. true);
  192. if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
  193. poff, plen, buffer, buflen)) {
  194. nf_ct_helper_log(skb, ct, "cannot mangle maddr");
  195. return NF_DROP;
  196. }
  197. }
  198. /* The received= parameter (RFC 2361) contains the address
  199. * from which the server received the request. */
  200. if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
  201. "received=", &poff, &plen,
  202. &addr, false) > 0 &&
  203. nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.dst.u3) &&
  204. !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.src.u3)) {
  205. buflen = sip_sprintf_addr(ct, buffer,
  206. &ct->tuplehash[!dir].tuple.src.u3,
  207. false);
  208. if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
  209. poff, plen, buffer, buflen)) {
  210. nf_ct_helper_log(skb, ct, "cannot mangle received");
  211. return NF_DROP;
  212. }
  213. }
  214. /* The rport= parameter (RFC 3581) contains the port number
  215. * from which the server received the request. */
  216. if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen,
  217. "rport=", &poff, &plen,
  218. &n) > 0 &&
  219. htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port &&
  220. htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
  221. __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
  222. buflen = sprintf(buffer, "%u", ntohs(p));
  223. if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
  224. poff, plen, buffer, buflen)) {
  225. nf_ct_helper_log(skb, ct, "cannot mangle rport");
  226. return NF_DROP;
  227. }
  228. }
  229. }
  230. next:
  231. /* Translate Contact headers */
  232. coff = 0;
  233. in_header = 0;
  234. while (ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
  235. SIP_HDR_CONTACT, &in_header,
  236. &matchoff, &matchlen,
  237. &addr, &port) > 0) {
  238. if (!map_addr(skb, protoff, dataoff, dptr, datalen,
  239. matchoff, matchlen,
  240. &addr, port)) {
  241. nf_ct_helper_log(skb, ct, "cannot mangle contact");
  242. return NF_DROP;
  243. }
  244. }
  245. if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) ||
  246. !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO)) {
  247. nf_ct_helper_log(skb, ct, "cannot mangle SIP from/to");
  248. return NF_DROP;
  249. }
  250. /* Mangle destination port for Cisco phones, then fix up checksums */
  251. if (dir == IP_CT_DIR_REPLY && ct_sip_info->forced_dport) {
  252. struct udphdr *uh;
  253. if (skb_ensure_writable(skb, skb->len)) {
  254. nf_ct_helper_log(skb, ct, "cannot mangle packet");
  255. return NF_DROP;
  256. }
  257. uh = (void *)skb->data + protoff;
  258. uh->dest = ct_sip_info->forced_dport;
  259. if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, protoff,
  260. 0, 0, NULL, 0)) {
  261. nf_ct_helper_log(skb, ct, "cannot mangle packet");
  262. return NF_DROP;
  263. }
  264. }
  265. return NF_ACCEPT;
  266. }
  267. static void nf_nat_sip_seq_adjust(struct sk_buff *skb, unsigned int protoff,
  268. s16 off)
  269. {
  270. enum ip_conntrack_info ctinfo;
  271. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  272. const struct tcphdr *th;
  273. if (nf_ct_protonum(ct) != IPPROTO_TCP || off == 0)
  274. return;
  275. th = (struct tcphdr *)(skb->data + protoff);
  276. nf_ct_seqadj_set(ct, ctinfo, th->seq, off);
  277. }
  278. /* Handles expected signalling connections and media streams */
  279. static void nf_nat_sip_expected(struct nf_conn *ct,
  280. struct nf_conntrack_expect *exp)
  281. {
  282. struct nf_conn_help *help = nfct_help(ct->master);
  283. struct nf_conntrack_expect *pair_exp;
  284. int range_set_for_snat = 0;
  285. struct nf_nat_range2 range;
  286. /* This must be a fresh one. */
  287. BUG_ON(ct->status & IPS_NAT_DONE_MASK);
  288. /* For DST manip, map port here to where it's expected. */
  289. range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
  290. range.min_proto = range.max_proto = exp->saved_proto;
  291. range.min_addr = range.max_addr = exp->saved_addr;
  292. nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
  293. /* Do media streams SRC manip according with the parameters
  294. * found in the paired expectation.
  295. */
  296. if (exp->class != SIP_EXPECT_SIGNALLING) {
  297. spin_lock_bh(&nf_conntrack_expect_lock);
  298. hlist_for_each_entry(pair_exp, &help->expectations, lnode) {
  299. if (pair_exp->tuple.src.l3num == nf_ct_l3num(ct) &&
  300. pair_exp->tuple.dst.protonum == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum &&
  301. nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, &pair_exp->saved_addr) &&
  302. ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all == pair_exp->saved_proto.all) {
  303. range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
  304. range.min_proto.all = range.max_proto.all = pair_exp->tuple.dst.u.all;
  305. range.min_addr = range.max_addr = pair_exp->tuple.dst.u3;
  306. range_set_for_snat = 1;
  307. break;
  308. }
  309. }
  310. spin_unlock_bh(&nf_conntrack_expect_lock);
  311. }
  312. /* When no paired expectation has been found, change src to
  313. * where master sends to, but only if the connection actually came
  314. * from the same source.
  315. */
  316. if (!range_set_for_snat &&
  317. nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
  318. &ct->master->tuplehash[exp->dir].tuple.src.u3)) {
  319. range.flags = NF_NAT_RANGE_MAP_IPS;
  320. range.min_addr = range.max_addr
  321. = ct->master->tuplehash[!exp->dir].tuple.dst.u3;
  322. range_set_for_snat = 1;
  323. }
  324. /* Perform SRC manip. */
  325. if (range_set_for_snat)
  326. nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
  327. }
  328. static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
  329. unsigned int dataoff,
  330. const char **dptr, unsigned int *datalen,
  331. struct nf_conntrack_expect *exp,
  332. unsigned int matchoff,
  333. unsigned int matchlen)
  334. {
  335. enum ip_conntrack_info ctinfo;
  336. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  337. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  338. struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
  339. union nf_inet_addr newaddr;
  340. u_int16_t port;
  341. __be16 srcport;
  342. char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
  343. unsigned int buflen;
  344. /* Connection will come from reply */
  345. if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
  346. &ct->tuplehash[!dir].tuple.dst.u3))
  347. newaddr = exp->tuple.dst.u3;
  348. else
  349. newaddr = ct->tuplehash[!dir].tuple.dst.u3;
  350. /* If the signalling port matches the connection's source port in the
  351. * original direction, try to use the destination port in the opposite
  352. * direction. */
  353. srcport = ct_sip_info->forced_dport ? :
  354. ct->tuplehash[dir].tuple.src.u.udp.port;
  355. if (exp->tuple.dst.u.udp.port == srcport)
  356. port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
  357. else
  358. port = ntohs(exp->tuple.dst.u.udp.port);
  359. exp->saved_addr = exp->tuple.dst.u3;
  360. exp->tuple.dst.u3 = newaddr;
  361. exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
  362. exp->dir = !dir;
  363. exp->expectfn = nf_nat_sip_expected;
  364. for (; port != 0; port++) {
  365. int ret;
  366. exp->tuple.dst.u.udp.port = htons(port);
  367. ret = nf_ct_expect_related(exp, NF_CT_EXP_F_SKIP_MASTER);
  368. if (ret == 0)
  369. break;
  370. else if (ret != -EBUSY) {
  371. port = 0;
  372. break;
  373. }
  374. }
  375. if (port == 0) {
  376. nf_ct_helper_log(skb, ct, "all ports in use for SIP");
  377. return NF_DROP;
  378. }
  379. if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) ||
  380. exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
  381. buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port);
  382. if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
  383. matchoff, matchlen, buffer, buflen)) {
  384. nf_ct_helper_log(skb, ct, "cannot mangle packet");
  385. goto err;
  386. }
  387. }
  388. return NF_ACCEPT;
  389. err:
  390. nf_ct_unexpect_related(exp);
  391. return NF_DROP;
  392. }
  393. static int mangle_content_len(struct sk_buff *skb, unsigned int protoff,
  394. unsigned int dataoff,
  395. const char **dptr, unsigned int *datalen)
  396. {
  397. enum ip_conntrack_info ctinfo;
  398. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  399. unsigned int matchoff, matchlen;
  400. char buffer[sizeof("65536")];
  401. int buflen, c_len;
  402. /* Get actual SDP length */
  403. if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
  404. SDP_HDR_VERSION, SDP_HDR_UNSPEC,
  405. &matchoff, &matchlen) <= 0)
  406. return 0;
  407. c_len = *datalen - matchoff + strlen("v=");
  408. /* Now, update SDP length */
  409. if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CONTENT_LENGTH,
  410. &matchoff, &matchlen) <= 0)
  411. return 0;
  412. buflen = sprintf(buffer, "%u", c_len);
  413. return mangle_packet(skb, protoff, dataoff, dptr, datalen,
  414. matchoff, matchlen, buffer, buflen);
  415. }
  416. static int mangle_sdp_packet(struct sk_buff *skb, unsigned int protoff,
  417. unsigned int dataoff,
  418. const char **dptr, unsigned int *datalen,
  419. unsigned int sdpoff,
  420. enum sdp_header_types type,
  421. enum sdp_header_types term,
  422. char *buffer, int buflen)
  423. {
  424. enum ip_conntrack_info ctinfo;
  425. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  426. unsigned int matchlen, matchoff;
  427. if (ct_sip_get_sdp_header(ct, *dptr, sdpoff, *datalen, type, term,
  428. &matchoff, &matchlen) <= 0)
  429. return -ENOENT;
  430. return mangle_packet(skb, protoff, dataoff, dptr, datalen,
  431. matchoff, matchlen, buffer, buflen) ? 0 : -EINVAL;
  432. }
  433. static unsigned int nf_nat_sdp_addr(struct sk_buff *skb, unsigned int protoff,
  434. unsigned int dataoff,
  435. const char **dptr, unsigned int *datalen,
  436. unsigned int sdpoff,
  437. enum sdp_header_types type,
  438. enum sdp_header_types term,
  439. const union nf_inet_addr *addr)
  440. {
  441. enum ip_conntrack_info ctinfo;
  442. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  443. char buffer[INET6_ADDRSTRLEN];
  444. unsigned int buflen;
  445. buflen = sip_sprintf_addr(ct, buffer, addr, false);
  446. if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen,
  447. sdpoff, type, term, buffer, buflen))
  448. return 0;
  449. return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
  450. }
  451. static unsigned int nf_nat_sdp_port(struct sk_buff *skb, unsigned int protoff,
  452. unsigned int dataoff,
  453. const char **dptr, unsigned int *datalen,
  454. unsigned int matchoff,
  455. unsigned int matchlen,
  456. u_int16_t port)
  457. {
  458. char buffer[sizeof("nnnnn")];
  459. unsigned int buflen;
  460. buflen = sprintf(buffer, "%u", port);
  461. if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
  462. matchoff, matchlen, buffer, buflen))
  463. return 0;
  464. return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
  465. }
  466. static unsigned int nf_nat_sdp_session(struct sk_buff *skb, unsigned int protoff,
  467. unsigned int dataoff,
  468. const char **dptr, unsigned int *datalen,
  469. unsigned int sdpoff,
  470. const union nf_inet_addr *addr)
  471. {
  472. enum ip_conntrack_info ctinfo;
  473. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  474. char buffer[INET6_ADDRSTRLEN];
  475. unsigned int buflen;
  476. /* Mangle session description owner and contact addresses */
  477. buflen = sip_sprintf_addr(ct, buffer, addr, false);
  478. if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
  479. SDP_HDR_OWNER, SDP_HDR_MEDIA, buffer, buflen))
  480. return 0;
  481. switch (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
  482. SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
  483. buffer, buflen)) {
  484. case 0:
  485. /*
  486. * RFC 2327:
  487. *
  488. * Session description
  489. *
  490. * c=* (connection information - not required if included in all media)
  491. */
  492. case -ENOENT:
  493. break;
  494. default:
  495. return 0;
  496. }
  497. return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
  498. }
  499. /* So, this packet has hit the connection tracking matching code.
  500. Mangle it, and change the expectation to match the new version. */
  501. static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff,
  502. unsigned int dataoff,
  503. const char **dptr, unsigned int *datalen,
  504. struct nf_conntrack_expect *rtp_exp,
  505. struct nf_conntrack_expect *rtcp_exp,
  506. unsigned int mediaoff,
  507. unsigned int medialen,
  508. union nf_inet_addr *rtp_addr)
  509. {
  510. enum ip_conntrack_info ctinfo;
  511. struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  512. enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
  513. u_int16_t port;
  514. /* Connection will come from reply */
  515. if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
  516. &ct->tuplehash[!dir].tuple.dst.u3))
  517. *rtp_addr = rtp_exp->tuple.dst.u3;
  518. else
  519. *rtp_addr = ct->tuplehash[!dir].tuple.dst.u3;
  520. rtp_exp->saved_addr = rtp_exp->tuple.dst.u3;
  521. rtp_exp->tuple.dst.u3 = *rtp_addr;
  522. rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
  523. rtp_exp->dir = !dir;
  524. rtp_exp->expectfn = nf_nat_sip_expected;
  525. rtcp_exp->saved_addr = rtcp_exp->tuple.dst.u3;
  526. rtcp_exp->tuple.dst.u3 = *rtp_addr;
  527. rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
  528. rtcp_exp->dir = !dir;
  529. rtcp_exp->expectfn = nf_nat_sip_expected;
  530. /* Try to get same pair of ports: if not, try to change them. */
  531. for (port = ntohs(rtp_exp->tuple.dst.u.udp.port);
  532. port != 0; port += 2) {
  533. int ret;
  534. rtp_exp->tuple.dst.u.udp.port = htons(port);
  535. ret = nf_ct_expect_related(rtp_exp,
  536. NF_CT_EXP_F_SKIP_MASTER);
  537. if (ret == -EBUSY)
  538. continue;
  539. else if (ret < 0) {
  540. port = 0;
  541. break;
  542. }
  543. rtcp_exp->tuple.dst.u.udp.port = htons(port + 1);
  544. ret = nf_ct_expect_related(rtcp_exp,
  545. NF_CT_EXP_F_SKIP_MASTER);
  546. if (ret == 0)
  547. break;
  548. else if (ret == -EBUSY) {
  549. nf_ct_unexpect_related(rtp_exp);
  550. continue;
  551. } else if (ret < 0) {
  552. nf_ct_unexpect_related(rtp_exp);
  553. port = 0;
  554. break;
  555. }
  556. }
  557. if (port == 0) {
  558. nf_ct_helper_log(skb, ct, "all ports in use for SDP media");
  559. goto err1;
  560. }
  561. /* Update media port. */
  562. if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
  563. !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen,
  564. mediaoff, medialen, port)) {
  565. nf_ct_helper_log(skb, ct, "cannot mangle SDP message");
  566. goto err2;
  567. }
  568. return NF_ACCEPT;
  569. err2:
  570. nf_ct_unexpect_related(rtp_exp);
  571. nf_ct_unexpect_related(rtcp_exp);
  572. err1:
  573. return NF_DROP;
  574. }
  575. static struct nf_ct_helper_expectfn sip_nat = {
  576. .name = "sip",
  577. .expectfn = nf_nat_sip_expected,
  578. };
  579. static void __exit nf_nat_sip_fini(void)
  580. {
  581. nf_nat_helper_unregister(&nat_helper_sip);
  582. RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
  583. nf_ct_helper_expectfn_unregister(&sip_nat);
  584. synchronize_rcu();
  585. }
  586. static const struct nf_nat_sip_hooks sip_hooks = {
  587. .msg = nf_nat_sip,
  588. .seq_adjust = nf_nat_sip_seq_adjust,
  589. .expect = nf_nat_sip_expect,
  590. .sdp_addr = nf_nat_sdp_addr,
  591. .sdp_port = nf_nat_sdp_port,
  592. .sdp_session = nf_nat_sdp_session,
  593. .sdp_media = nf_nat_sdp_media,
  594. };
  595. static int __init nf_nat_sip_init(void)
  596. {
  597. BUG_ON(nf_nat_sip_hooks != NULL);
  598. nf_nat_helper_register(&nat_helper_sip);
  599. RCU_INIT_POINTER(nf_nat_sip_hooks, &sip_hooks);
  600. nf_ct_helper_expectfn_register(&sip_nat);
  601. return 0;
  602. }
  603. module_init(nf_nat_sip_init);
  604. module_exit(nf_nat_sip_fini);