aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-02-11 06:23:53 -0500
committerPatrick McHardy <kaber@trash.net>2010-02-11 06:23:53 -0500
commit3b6b9fab42fe98358d70735cf98d43fc18dc79c9 (patch)
tree98703e92c7259e35b7d6cd557bf0c1a6965f4e7c /net/netfilter
parent54101f4f3bed87fa968b57f77f8ff3b09fd88bcf (diff)
netfilter: nf_conntrack_sip: pass data offset to NAT functions
When using TCP multiple SIP messages might be present in a single packet. A following patch will parse them by setting the dptr to the beginning of each message. The NAT helper needs to reload the dptr value after mangling the packet however, so it needs to know the offset of the message to the beginning of the packet. Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_sip.c82
1 files changed, 44 insertions, 38 deletions
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 0ca2f2b5c2fa..0ec37d6a2df7 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -50,12 +50,13 @@ module_param(sip_direct_media, int, 0600);
50MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " 50MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
51 "endpoints only (default 1)"); 51 "endpoints only (default 1)");
52 52
53unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, 53unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int dataoff,
54 const char **dptr, 54 const char **dptr,
55 unsigned int *datalen) __read_mostly; 55 unsigned int *datalen) __read_mostly;
56EXPORT_SYMBOL_GPL(nf_nat_sip_hook); 56EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
57 57
58unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, 58unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
59 unsigned int dataoff,
59 const char **dptr, 60 const char **dptr,
60 unsigned int *datalen, 61 unsigned int *datalen,
61 struct nf_conntrack_expect *exp, 62 struct nf_conntrack_expect *exp,
@@ -63,17 +64,17 @@ unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
63 unsigned int matchlen) __read_mostly; 64 unsigned int matchlen) __read_mostly;
64EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook); 65EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook);
65 66
66unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, 67unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int dataoff,
67 const char **dptr, 68 const char **dptr,
68 unsigned int dataoff,
69 unsigned int *datalen, 69 unsigned int *datalen,
70 unsigned int sdpoff,
70 enum sdp_header_types type, 71 enum sdp_header_types type,
71 enum sdp_header_types term, 72 enum sdp_header_types term,
72 const union nf_inet_addr *addr) 73 const union nf_inet_addr *addr)
73 __read_mostly; 74 __read_mostly;
74EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook); 75EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook);
75 76
76unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, 77unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int dataoff,
77 const char **dptr, 78 const char **dptr,
78 unsigned int *datalen, 79 unsigned int *datalen,
79 unsigned int matchoff, 80 unsigned int matchoff,
@@ -82,14 +83,15 @@ unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb,
82EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook); 83EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook);
83 84
84unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, 85unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
85 const char **dptr,
86 unsigned int dataoff, 86 unsigned int dataoff,
87 const char **dptr,
87 unsigned int *datalen, 88 unsigned int *datalen,
89 unsigned int sdpoff,
88 const union nf_inet_addr *addr) 90 const union nf_inet_addr *addr)
89 __read_mostly; 91 __read_mostly;
90EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook); 92EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook);
91 93
92unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, 94unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int dataoff,
93 const char **dptr, 95 const char **dptr,
94 unsigned int *datalen, 96 unsigned int *datalen,
95 struct nf_conntrack_expect *rtp_exp, 97 struct nf_conntrack_expect *rtp_exp,
@@ -729,7 +731,7 @@ static void flush_expectations(struct nf_conn *ct, bool media)
729 spin_unlock_bh(&nf_conntrack_lock); 731 spin_unlock_bh(&nf_conntrack_lock);
730} 732}
731 733
732static int set_expected_rtp_rtcp(struct sk_buff *skb, 734static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int dataoff,
733 const char **dptr, unsigned int *datalen, 735 const char **dptr, unsigned int *datalen,
734 union nf_inet_addr *daddr, __be16 port, 736 union nf_inet_addr *daddr, __be16 port,
735 enum sip_expectation_classes class, 737 enum sip_expectation_classes class,
@@ -806,7 +808,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
806 if (direct_rtp) { 808 if (direct_rtp) {
807 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook); 809 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook);
808 if (nf_nat_sdp_port && 810 if (nf_nat_sdp_port &&
809 !nf_nat_sdp_port(skb, dptr, datalen, 811 !nf_nat_sdp_port(skb, dataoff, dptr, datalen,
810 mediaoff, medialen, ntohs(rtp_port))) 812 mediaoff, medialen, ntohs(rtp_port)))
811 goto err1; 813 goto err1;
812 } 814 }
@@ -828,7 +830,8 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
828 830
829 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook); 831 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
830 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp) 832 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp)
831 ret = nf_nat_sdp_media(skb, dptr, datalen, rtp_exp, rtcp_exp, 833 ret = nf_nat_sdp_media(skb, dataoff, dptr, datalen,
834 rtp_exp, rtcp_exp,
832 mediaoff, medialen, daddr); 835 mediaoff, medialen, daddr);
833 else { 836 else {
834 if (nf_ct_expect_related(rtp_exp) == 0) { 837 if (nf_ct_expect_related(rtp_exp) == 0) {
@@ -867,7 +870,7 @@ static const struct sdp_media_type *sdp_media_type(const char *dptr,
867 return NULL; 870 return NULL;
868} 871}
869 872
870static int process_sdp(struct sk_buff *skb, 873static int process_sdp(struct sk_buff *skb, unsigned int dataoff,
871 const char **dptr, unsigned int *datalen, 874 const char **dptr, unsigned int *datalen,
872 unsigned int cseq) 875 unsigned int cseq)
873{ 876{
@@ -942,7 +945,7 @@ static int process_sdp(struct sk_buff *skb,
942 else 945 else
943 return NF_DROP; 946 return NF_DROP;
944 947
945 ret = set_expected_rtp_rtcp(skb, dptr, datalen, 948 ret = set_expected_rtp_rtcp(skb, dataoff, dptr, datalen,
946 &rtp_addr, htons(port), t->class, 949 &rtp_addr, htons(port), t->class,
947 mediaoff, medialen); 950 mediaoff, medialen);
948 if (ret != NF_ACCEPT) 951 if (ret != NF_ACCEPT)
@@ -950,8 +953,9 @@ static int process_sdp(struct sk_buff *skb,
950 953
951 /* Update media connection address if present */ 954 /* Update media connection address if present */
952 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) { 955 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) {
953 ret = nf_nat_sdp_addr(skb, dptr, mediaoff, datalen, 956 ret = nf_nat_sdp_addr(skb, dataoff, dptr, datalen,
954 c_hdr, SDP_HDR_MEDIA, &rtp_addr); 957 mediaoff, c_hdr, SDP_HDR_MEDIA,
958 &rtp_addr);
955 if (ret != NF_ACCEPT) 959 if (ret != NF_ACCEPT)
956 return ret; 960 return ret;
957 } 961 }
@@ -961,14 +965,15 @@ static int process_sdp(struct sk_buff *skb,
961 /* Update session connection and owner addresses */ 965 /* Update session connection and owner addresses */
962 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook); 966 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook);
963 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK) 967 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
964 ret = nf_nat_sdp_session(skb, dptr, sdpoff, datalen, &rtp_addr); 968 ret = nf_nat_sdp_session(skb, dataoff, dptr, datalen, sdpoff,
969 &rtp_addr);
965 970
966 if (ret == NF_ACCEPT && i > 0) 971 if (ret == NF_ACCEPT && i > 0)
967 help->help.ct_sip_info.invite_cseq = cseq; 972 help->help.ct_sip_info.invite_cseq = cseq;
968 973
969 return ret; 974 return ret;
970} 975}
971static int process_invite_response(struct sk_buff *skb, 976static int process_invite_response(struct sk_buff *skb, unsigned int dataoff,
972 const char **dptr, unsigned int *datalen, 977 const char **dptr, unsigned int *datalen,
973 unsigned int cseq, unsigned int code) 978 unsigned int cseq, unsigned int code)
974{ 979{
@@ -978,13 +983,13 @@ static int process_invite_response(struct sk_buff *skb,
978 983
979 if ((code >= 100 && code <= 199) || 984 if ((code >= 100 && code <= 199) ||
980 (code >= 200 && code <= 299)) 985 (code >= 200 && code <= 299))
981 return process_sdp(skb, dptr, datalen, cseq); 986 return process_sdp(skb, dataoff, dptr, datalen, cseq);
982 else if (help->help.ct_sip_info.invite_cseq == cseq) 987 else if (help->help.ct_sip_info.invite_cseq == cseq)
983 flush_expectations(ct, true); 988 flush_expectations(ct, true);
984 return NF_ACCEPT; 989 return NF_ACCEPT;
985} 990}
986 991
987static int process_update_response(struct sk_buff *skb, 992static int process_update_response(struct sk_buff *skb, unsigned int dataoff,
988 const char **dptr, unsigned int *datalen, 993 const char **dptr, unsigned int *datalen,
989 unsigned int cseq, unsigned int code) 994 unsigned int cseq, unsigned int code)
990{ 995{
@@ -994,13 +999,13 @@ static int process_update_response(struct sk_buff *skb,
994 999
995 if ((code >= 100 && code <= 199) || 1000 if ((code >= 100 && code <= 199) ||
996 (code >= 200 && code <= 299)) 1001 (code >= 200 && code <= 299))
997 return process_sdp(skb, dptr, datalen, cseq); 1002 return process_sdp(skb, dataoff, dptr, datalen, cseq);
998 else if (help->help.ct_sip_info.invite_cseq == cseq) 1003 else if (help->help.ct_sip_info.invite_cseq == cseq)
999 flush_expectations(ct, true); 1004 flush_expectations(ct, true);
1000 return NF_ACCEPT; 1005 return NF_ACCEPT;
1001} 1006}
1002 1007
1003static int process_prack_response(struct sk_buff *skb, 1008static int process_prack_response(struct sk_buff *skb, unsigned int dataoff,
1004 const char **dptr, unsigned int *datalen, 1009 const char **dptr, unsigned int *datalen,
1005 unsigned int cseq, unsigned int code) 1010 unsigned int cseq, unsigned int code)
1006{ 1011{
@@ -1010,13 +1015,13 @@ static int process_prack_response(struct sk_buff *skb,
1010 1015
1011 if ((code >= 100 && code <= 199) || 1016 if ((code >= 100 && code <= 199) ||
1012 (code >= 200 && code <= 299)) 1017 (code >= 200 && code <= 299))
1013 return process_sdp(skb, dptr, datalen, cseq); 1018 return process_sdp(skb, dataoff, dptr, datalen, cseq);
1014 else if (help->help.ct_sip_info.invite_cseq == cseq) 1019 else if (help->help.ct_sip_info.invite_cseq == cseq)
1015 flush_expectations(ct, true); 1020 flush_expectations(ct, true);
1016 return NF_ACCEPT; 1021 return NF_ACCEPT;
1017} 1022}
1018 1023
1019static int process_bye_request(struct sk_buff *skb, 1024static int process_bye_request(struct sk_buff *skb, unsigned int dataoff,
1020 const char **dptr, unsigned int *datalen, 1025 const char **dptr, unsigned int *datalen,
1021 unsigned int cseq) 1026 unsigned int cseq)
1022{ 1027{
@@ -1031,7 +1036,7 @@ static int process_bye_request(struct sk_buff *skb,
1031 * signalling connections. The expectation is marked inactive and is activated 1036 * signalling connections. The expectation is marked inactive and is activated
1032 * when receiving a response indicating success from the registrar. 1037 * when receiving a response indicating success from the registrar.
1033 */ 1038 */
1034static int process_register_request(struct sk_buff *skb, 1039static int process_register_request(struct sk_buff *skb, unsigned int dataoff,
1035 const char **dptr, unsigned int *datalen, 1040 const char **dptr, unsigned int *datalen,
1036 unsigned int cseq) 1041 unsigned int cseq)
1037{ 1042{
@@ -1101,7 +1106,7 @@ static int process_register_request(struct sk_buff *skb,
1101 1106
1102 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook); 1107 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook);
1103 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK) 1108 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK)
1104 ret = nf_nat_sip_expect(skb, dptr, datalen, exp, 1109 ret = nf_nat_sip_expect(skb, dataoff, dptr, datalen, exp,
1105 matchoff, matchlen); 1110 matchoff, matchlen);
1106 else { 1111 else {
1107 if (nf_ct_expect_related(exp) != 0) 1112 if (nf_ct_expect_related(exp) != 0)
@@ -1117,7 +1122,7 @@ store_cseq:
1117 return ret; 1122 return ret;
1118} 1123}
1119 1124
1120static int process_register_response(struct sk_buff *skb, 1125static int process_register_response(struct sk_buff *skb, unsigned int dataoff,
1121 const char **dptr, unsigned int *datalen, 1126 const char **dptr, unsigned int *datalen,
1122 unsigned int cseq, unsigned int code) 1127 unsigned int cseq, unsigned int code)
1123{ 1128{
@@ -1127,7 +1132,7 @@ static int process_register_response(struct sk_buff *skb,
1127 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1132 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1128 union nf_inet_addr addr; 1133 union nf_inet_addr addr;
1129 __be16 port; 1134 __be16 port;
1130 unsigned int matchoff, matchlen, dataoff = 0; 1135 unsigned int matchoff, matchlen, coff = 0;
1131 unsigned int expires = 0; 1136 unsigned int expires = 0;
1132 int in_contact = 0, ret; 1137 int in_contact = 0, ret;
1133 1138
@@ -1154,7 +1159,7 @@ static int process_register_response(struct sk_buff *skb,
1154 while (1) { 1159 while (1) {
1155 unsigned int c_expires = expires; 1160 unsigned int c_expires = expires;
1156 1161
1157 ret = ct_sip_parse_header_uri(ct, *dptr, &dataoff, *datalen, 1162 ret = ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
1158 SIP_HDR_CONTACT, &in_contact, 1163 SIP_HDR_CONTACT, &in_contact,
1159 &matchoff, &matchlen, 1164 &matchoff, &matchlen,
1160 &addr, &port); 1165 &addr, &port);
@@ -1193,13 +1198,13 @@ static const struct sip_handler sip_handlers[] = {
1193 SIP_HANDLER("REGISTER", process_register_request, process_register_response), 1198 SIP_HANDLER("REGISTER", process_register_request, process_register_response),
1194}; 1199};
1195 1200
1196static int process_sip_response(struct sk_buff *skb, 1201static int process_sip_response(struct sk_buff *skb, unsigned int dataoff,
1197 const char **dptr, unsigned int *datalen) 1202 const char **dptr, unsigned int *datalen)
1198{ 1203{
1199 enum ip_conntrack_info ctinfo; 1204 enum ip_conntrack_info ctinfo;
1200 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1205 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1201 unsigned int matchoff, matchlen; 1206 unsigned int matchoff, matchlen, matchend;
1202 unsigned int code, cseq, dataoff, i; 1207 unsigned int code, cseq, i;
1203 1208
1204 if (*datalen < strlen("SIP/2.0 200")) 1209 if (*datalen < strlen("SIP/2.0 200"))
1205 return NF_ACCEPT; 1210 return NF_ACCEPT;
@@ -1213,7 +1218,7 @@ static int process_sip_response(struct sk_buff *skb,
1213 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1218 cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1214 if (!cseq) 1219 if (!cseq)
1215 return NF_DROP; 1220 return NF_DROP;
1216 dataoff = matchoff + matchlen + 1; 1221 matchend = matchoff + matchlen + 1;
1217 1222
1218 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1223 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1219 const struct sip_handler *handler; 1224 const struct sip_handler *handler;
@@ -1221,15 +1226,16 @@ static int process_sip_response(struct sk_buff *skb,
1221 handler = &sip_handlers[i]; 1226 handler = &sip_handlers[i];
1222 if (handler->response == NULL) 1227 if (handler->response == NULL)
1223 continue; 1228 continue;
1224 if (*datalen < dataoff + handler->len || 1229 if (*datalen < matchend + handler->len ||
1225 strnicmp(*dptr + dataoff, handler->method, handler->len)) 1230 strnicmp(*dptr + matchend, handler->method, handler->len))
1226 continue; 1231 continue;
1227 return handler->response(skb, dptr, datalen, cseq, code); 1232 return handler->response(skb, dataoff, dptr, datalen,
1233 cseq, code);
1228 } 1234 }
1229 return NF_ACCEPT; 1235 return NF_ACCEPT;
1230} 1236}
1231 1237
1232static int process_sip_request(struct sk_buff *skb, 1238static int process_sip_request(struct sk_buff *skb, unsigned int dataoff,
1233 const char **dptr, unsigned int *datalen) 1239 const char **dptr, unsigned int *datalen)
1234{ 1240{
1235 enum ip_conntrack_info ctinfo; 1241 enum ip_conntrack_info ctinfo;
@@ -1254,7 +1260,7 @@ static int process_sip_request(struct sk_buff *skb,
1254 if (!cseq) 1260 if (!cseq)
1255 return NF_DROP; 1261 return NF_DROP;
1256 1262
1257 return handler->request(skb, dptr, datalen, cseq); 1263 return handler->request(skb, dataoff, dptr, datalen, cseq);
1258 } 1264 }
1259 return NF_ACCEPT; 1265 return NF_ACCEPT;
1260} 1266}
@@ -1288,13 +1294,13 @@ static int sip_help(struct sk_buff *skb,
1288 return NF_ACCEPT; 1294 return NF_ACCEPT;
1289 1295
1290 if (strnicmp(dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) 1296 if (strnicmp(dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0)
1291 ret = process_sip_request(skb, &dptr, &datalen); 1297 ret = process_sip_request(skb, dataoff, &dptr, &datalen);
1292 else 1298 else
1293 ret = process_sip_response(skb, &dptr, &datalen); 1299 ret = process_sip_response(skb, dataoff, &dptr, &datalen);
1294 1300
1295 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1301 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1296 nf_nat_sip = rcu_dereference(nf_nat_sip_hook); 1302 nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
1297 if (nf_nat_sip && !nf_nat_sip(skb, &dptr, &datalen)) 1303 if (nf_nat_sip && !nf_nat_sip(skb, dataoff, &dptr, &datalen))
1298 ret = NF_DROP; 1304 ret = NF_DROP;
1299 } 1305 }
1300 1306