netfilter: nf_conntrack_sip: add T.38 FAX support
Patrick McHardy [Thu, 11 Feb 2010 11:30:21 +0000 (12:30 +0100)]
Signed-off-by: Patrick McHardy <kaber@trash.net>

include/linux/netfilter/nf_conntrack_sip.h
include/net/netfilter/nf_conntrack.h
net/netfilter/nf_conntrack_sip.c

index cd84d6f..ff8cfbc 100644 (file)
@@ -14,6 +14,7 @@ enum sip_expectation_classes {
        SIP_EXPECT_SIGNALLING,
        SIP_EXPECT_AUDIO,
        SIP_EXPECT_VIDEO,
+       SIP_EXPECT_IMAGE,
        __SIP_EXPECT_MAX
 };
 #define SIP_EXPECT_MAX (__SIP_EXPECT_MAX - 1)
index 5043d61..5b7d883 100644 (file)
@@ -70,7 +70,7 @@ union nf_conntrack_help {
 struct nf_conntrack_helper;
 
 /* Must be kept in sync with the classes defined by helpers */
-#define NF_CT_MAX_EXPECT_CLASSES       3
+#define NF_CT_MAX_EXPECT_CLASSES       4
 
 /* nf_conn feature for connections that have a helper */
 struct nf_conn_help {
index 3bb3aaf..fbe8ff5 100644 (file)
@@ -907,6 +907,7 @@ err1:
 static const struct sdp_media_type sdp_media_types[] = {
        SDP_MEDIA_TYPE("audio ", SIP_EXPECT_AUDIO),
        SDP_MEDIA_TYPE("video ", SIP_EXPECT_VIDEO),
+       SDP_MEDIA_TYPE("image ", SIP_EXPECT_IMAGE),
 };
 
 static const struct sdp_media_type *sdp_media_type(const char *dptr,
@@ -932,7 +933,6 @@ static int process_sdp(struct sk_buff *skb, unsigned int dataoff,
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
-       struct nf_conn_help *help = nfct_help(ct);
        unsigned int matchoff, matchlen;
        unsigned int mediaoff, medialen;
        unsigned int sdpoff;
@@ -1024,9 +1024,6 @@ static int process_sdp(struct sk_buff *skb, unsigned int dataoff,
                ret = nf_nat_sdp_session(skb, dataoff, dptr, datalen, sdpoff,
                                         &rtp_addr);
 
-       if (ret == NF_ACCEPT && i > 0)
-               help->help.ct_sip_info.invite_cseq = cseq;
-
        return ret;
 }
 static int process_invite_response(struct sk_buff *skb, unsigned int dataoff,
@@ -1077,6 +1074,22 @@ static int process_prack_response(struct sk_buff *skb, unsigned int dataoff,
        return NF_ACCEPT;
 }
 
+static int process_invite_request(struct sk_buff *skb, unsigned int dataoff,
+                                 const char **dptr, unsigned int *datalen,
+                                 unsigned int cseq)
+{
+       enum ip_conntrack_info ctinfo;
+       struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+       struct nf_conn_help *help = nfct_help(ct);
+       unsigned int ret;
+
+       flush_expectations(ct, true);
+       ret = process_sdp(skb, dataoff, dptr, datalen, cseq);
+       if (ret == NF_ACCEPT)
+               help->help.ct_sip_info.invite_cseq = cseq;
+       return ret;
+}
+
 static int process_bye_request(struct sk_buff *skb, unsigned int dataoff,
                               const char **dptr, unsigned int *datalen,
                               unsigned int cseq)
@@ -1257,7 +1270,7 @@ flush:
 }
 
 static const struct sip_handler sip_handlers[] = {
-       SIP_HANDLER("INVITE", process_sdp, process_invite_response),
+       SIP_HANDLER("INVITE", process_invite_request, process_invite_response),
        SIP_HANDLER("UPDATE", process_sdp, process_update_response),
        SIP_HANDLER("ACK", process_sdp, NULL),
        SIP_HANDLER("PRACK", process_sdp, process_prack_response),
@@ -1473,6 +1486,11 @@ static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1
                .max_expected   = 2 * IP_CT_DIR_MAX,
                .timeout        = 3 * 60,
        },
+       [SIP_EXPECT_IMAGE] = {
+               .name           = "image",
+               .max_expected   = IP_CT_DIR_MAX,
+               .timeout        = 3 * 60,
+       },
 };
 
 static void nf_conntrack_sip_fini(void)