Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d5b8baa authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: sip conntrack: minor cleanup



- Use enum for header field enumeration
- Use numerical value instead of pointer to header info structure to
  identify headers, unexport ct_sip_hdrs
- group SIP and SDP entries in header info structure
- remove double forward declaration of ct_sip_get_info

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 337fbc41
Loading
Loading
Loading
Loading
+10 −18
Original line number Diff line number Diff line
@@ -5,23 +5,15 @@
#define SIP_PORT	5060
#define SIP_TIMEOUT	3600

#define POS_VIA		0
#define POS_CONTACT	1
#define POS_CONTENT	2
#define POS_MEDIA	3
#define POS_OWNER	4
#define POS_CONNECTION	5
#define POS_REQ_HEADER	6
#define POS_SDP_HEADER	7

struct sip_header_nfo {
	const char	*lname;
	const char	*sname;
	const char	*ln_str;
	size_t		lnlen;
	size_t		snlen;
	size_t		ln_strlen;
	int		(*match_len)(const char *, const char *, int *);
enum sip_header_pos {
	POS_REQ_HEADER,
	POS_VIA,
	POS_CONTACT,
	POS_CONTENT,
	POS_MEDIA,
	POS_OWNER,
	POS_CONNECTION,
	POS_SDP_HEADER,
};

extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
@@ -36,7 +28,7 @@ extern unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
extern int ct_sip_get_info(const char *dptr, size_t dlen,
			   unsigned int *matchoff,
			   unsigned int *matchlen,
			   struct sip_header_nfo *hnfo);
			   enum sip_header_pos pos);
extern int ct_sip_lnlen(const char *line, const char *limit);
extern const char *ct_sip_search(const char *needle, const char *haystack,
                                 size_t needle_len, size_t haystack_len);
+32 −28
Original line number Diff line number Diff line
@@ -52,20 +52,32 @@ unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
				const char *dptr);
EXPORT_SYMBOL_GPL(ip_nat_sdp_hook);

int ct_sip_get_info(const char *dptr, size_t dlen,
				unsigned int *matchoff,
				unsigned int *matchlen,
				struct sip_header_nfo *hnfo);
EXPORT_SYMBOL_GPL(ct_sip_get_info);


static int digits_len(const char *dptr, const char *limit, int *shift);
static int epaddr_len(const char *dptr, const char *limit, int *shift);
static int skp_digits_len(const char *dptr, const char *limit, int *shift);
static int skp_epaddr_len(const char *dptr, const char *limit, int *shift);

struct sip_header_nfo ct_sip_hdrs[] = {
	{ 	/* Via header */
struct sip_header_nfo {
	const char	*lname;
	const char	*sname;
	const char	*ln_str;
	size_t		lnlen;
	size_t		snlen;
	size_t		ln_strlen;
	int		(*match_len)(const char *, const char *, int *);
};

static struct sip_header_nfo ct_sip_hdrs[] = {
	[POS_REQ_HEADER] = { 	/* SIP Requests headers */
		.lname		= "sip:",
		.lnlen		= sizeof("sip:") - 1,
		.sname		= "sip:",
		.snlen		= sizeof("sip:") - 1, /* yes, i know.. ;) */
		.ln_str		= "@",
		.ln_strlen	= sizeof("@") - 1,
		.match_len	= epaddr_len
	},
	[POS_VIA] = { 		/* SIP Via header */
		.lname		= "Via:",
		.lnlen		= sizeof("Via:") - 1,
		.sname		= "\r\nv:",
@@ -74,7 +86,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.ln_strlen	= sizeof("UDP ") - 1,
		.match_len	= epaddr_len,
	},
	{ 	/* Contact header */
	[POS_CONTACT] = { 	/* SIP Contact header */
		.lname		= "Contact:",
		.lnlen		= sizeof("Contact:") - 1,
		.sname		= "\r\nm:",
@@ -83,7 +95,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.ln_strlen	= sizeof("sip:") - 1,
		.match_len	= skp_epaddr_len
	},
	{ 	/* Content length header */
	[POS_CONTENT] = { 	/* SIP Content length header */
		.lname		= "Content-Length:",
		.lnlen		= sizeof("Content-Length:") - 1,
		.sname		= "\r\nl:",
@@ -92,7 +104,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.ln_strlen	= sizeof(":") - 1,
		.match_len	= skp_digits_len
	},
	{	/* SDP media info */
	[POS_MEDIA] = {		/* SDP media info */
		.lname		= "\nm=",
		.lnlen		= sizeof("\nm=") - 1,
		.sname		= "\rm=",
@@ -101,7 +113,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.ln_strlen	= sizeof("audio ") - 1,
		.match_len	= digits_len
	},
	{ 	/* SDP owner address*/
	[POS_OWNER] = { 	/* SDP owner address*/
		.lname		= "\no=",
		.lnlen		= sizeof("\no=") - 1,
		.sname		= "\ro=",
@@ -110,7 +122,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.ln_strlen	= sizeof("IN IP4 ") - 1,
		.match_len	= epaddr_len
	},
	{ 	/* SDP connection info */
	[POS_CONNECTION] = { 	/* SDP connection info */
		.lname		= "\nc=",
		.lnlen		= sizeof("\nc=") - 1,
		.sname		= "\rc=",
@@ -119,16 +131,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.ln_strlen	= sizeof("IN IP4 ") - 1,
		.match_len	= epaddr_len
	},
	{ 	/* Requests headers */
		.lname		= "sip:",
		.lnlen		= sizeof("sip:") - 1,
		.sname		= "sip:",
		.snlen		= sizeof("sip:") - 1, /* yes, i know.. ;) */
		.ln_str		= "@",
		.ln_strlen	= sizeof("@") - 1,
		.match_len	= epaddr_len
	},
	{ 	/* SDP version header */
	[POS_SDP_HEADER] = { 	/* SDP version header */
		.lname		= "\nv=",
		.lnlen		= sizeof("\nv=") - 1,
		.sname		= "\rv=",
@@ -138,7 +141,6 @@ struct sip_header_nfo ct_sip_hdrs[] = {
		.match_len	= digits_len
	}
};
EXPORT_SYMBOL_GPL(ct_sip_hdrs);

/* get line lenght until first CR or LF seen. */
int ct_sip_lnlen(const char *line, const char *limit)
@@ -263,8 +265,9 @@ static int skp_epaddr_len(const char *dptr, const char *limit, int *shift)
int ct_sip_get_info(const char *dptr, size_t dlen,
		    unsigned int *matchoff,
		    unsigned int *matchlen,
		    struct sip_header_nfo *hnfo)
		    enum sip_header_pos pos)
{
	struct sip_header_nfo *hnfo = &ct_sip_hdrs[pos];
	const char *limit, *aux, *k = dptr;
	int shift = 0;

@@ -298,6 +301,7 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
	DEBUGP("%s header not found.\n", hnfo->lname);
	return 0;
}
EXPORT_SYMBOL_GPL(ct_sip_get_info);

static int set_expected_rtp(struct sk_buff **pskb,
			    struct ip_conntrack *ct,
@@ -393,7 +397,7 @@ static int sip_help(struct sk_buff **pskb,
	}
	/* Get ip and port address from SDP packet. */
	if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
	                    &ct_sip_hdrs[POS_CONNECTION]) > 0) {
	                    POS_CONNECTION) > 0) {

		/* We'll drop only if there are parse problems. */
		if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr,
@@ -402,7 +406,7 @@ static int sip_help(struct sk_buff **pskb,
			goto out;
		}
		if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
		                    &ct_sip_hdrs[POS_MEDIA]) > 0) {
		                    POS_MEDIA) > 0) {

			port = simple_strtoul(dptr + matchoff, NULL, 10);
			if (port < 1024) {
+13 −17
Original line number Diff line number Diff line
@@ -29,18 +29,16 @@ MODULE_DESCRIPTION("SIP NAT helper");
#define DEBUGP(format, args...)
#endif

extern struct sip_header_nfo ct_sip_hdrs[];

static unsigned int mangle_sip_packet(struct sk_buff **pskb,
				      enum ip_conntrack_info ctinfo,
				      struct ip_conntrack *ct,
				      const char **dptr, size_t dlen,
				      char *buffer, int bufflen,
				      struct sip_header_nfo *hnfo)
				      enum sip_header_pos pos)
{
	unsigned int matchlen, matchoff;

	if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0)
	if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, pos) <= 0)
		return 0;

	if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
@@ -80,14 +78,13 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
		if ((ctinfo) < IP_CT_IS_REPLY) {
			mangle_sip_packet(pskb, ctinfo, ct, dptr,
			                  (*pskb)->len - dataoff,
			                  buffer, bufflen,
			                  &ct_sip_hdrs[POS_CONTACT]);
			                  buffer, bufflen, POS_CONTACT);
			return 1;
		}

		if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
				       (*pskb)->len - dataoff,
		                       buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
		                       buffer, bufflen, POS_VIA))
			return 0;

		/* This search should ignore case, but later.. */
@@ -102,25 +99,24 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,

		return mangle_sip_packet(pskb, ctinfo, ct, dptr,
					 (*pskb)->len - dataoff,
		                         buffer, bufflen,
					 &ct_sip_hdrs[POS_CONTACT]);
		                         buffer, bufflen, POS_CONTACT);
	}
	if ((ctinfo) < IP_CT_IS_REPLY) {
		if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
				       (*pskb)->len - dataoff,
		                       buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
		                       buffer, bufflen, POS_VIA))
			return 0;

		/* Mangle Contact if exists only. - watch udp_nat_mangle()! */
		mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
		                  buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
		                  buffer, bufflen, POS_CONTACT);
		return 1;
	}
	/* This mangle requests headers. */
	return mangle_sip_packet(pskb, ctinfo, ct, dptr,
	                         ct_sip_lnlen(*dptr,
				              *dptr + (*pskb)->len - dataoff),
	                         buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
	                         buffer, bufflen, POS_REQ_HEADER);
}

static int mangle_content_len(struct sk_buff **pskb,
@@ -136,7 +132,7 @@ static int mangle_content_len(struct sk_buff **pskb,

	/* Get actual SDP lenght */
	if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
	                    &matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) {
	                    &matchlen, POS_SDP_HEADER) > 0) {

		/* since ct_sip_get_info() give us a pointer passing 'v='
		   we need to add 2 bytes in this count. */
@@ -144,7 +140,7 @@ static int mangle_content_len(struct sk_buff **pskb,

		/* Now, update SDP lenght */
		if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
		                    &matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) {
		                    &matchlen, POS_CONTENT) > 0) {

			bufflen = sprintf(buffer, "%u", c_len);

@@ -170,17 +166,17 @@ static unsigned int mangle_sdp(struct sk_buff **pskb,
	/* Mangle owner and contact info. */
	bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
	                       buffer, bufflen, &ct_sip_hdrs[POS_OWNER]))
	                       buffer, bufflen, POS_OWNER))
		return 0;

	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
	                       buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION]))
	                       buffer, bufflen, POS_CONNECTION))
		return 0;

	/* Mangle media port. */
	bufflen = sprintf(buffer, "%u", port);
	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
	                       buffer, bufflen, &ct_sip_hdrs[POS_MEDIA]))
	                       buffer, bufflen, POS_MEDIA))
		return 0;

	return mangle_content_len(pskb, ctinfo, ct, dptr);