static unsigned int mangle_sdp(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, struct ip_conntrack *ct, u_int32_t newip, u_int16_t port, const char *dptr) { char buffer[sizeof("nnn.nnn.nnn.nnn")]; unsigned int dataoff, bufflen; dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); /* 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])) return 0; if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, buffer, bufflen, &ct_sip_hdrs[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])) return 0; return mangle_content_len(pskb, ctinfo, ct, dptr); }
static unsigned int mangle_sdp(struct sk_buff *skb, enum ip_conntrack_info ctinfo, struct nf_conn *ct, __be32 newip, u_int16_t port, const char *dptr) { char buffer[sizeof("nnn.nnn.nnn.nnn")]; unsigned int dataoff, bufflen; dataoff = ip_hdrlen(skb) + sizeof(struct udphdr); /* Mangle owner and contact info. */ bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip)); if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff, buffer, bufflen, POS_OWNER_IP4)) return 0; if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff, buffer, bufflen, POS_CONNECTION_IP4)) return 0; /* Mangle media port. */ bufflen = sprintf(buffer, "%u", port); if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff, buffer, bufflen, POS_MEDIA)) return 0; return mangle_content_len(skb, ctinfo, ct, dptr); }
static unsigned int ip_nat_sip(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, struct ip_conntrack *ct, const char **dptr) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; unsigned int bufflen, dataoff; u_int32_t ip; u_int16_t port; dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); ip = ct->tuplehash[!dir].tuple.dst.ip; port = ct->tuplehash[!dir].tuple.dst.u.udp.port; bufflen = sprintf(buffer, "%u.%u.%u.%u:%u", NIPQUAD(ip), ntohs(port)); /* short packet ? */ if (((*pskb)->len - dataoff) < (sizeof("SIP/2.0") - 1)) return 0; /* Basic rules: requests and responses. */ if (memcmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) == 0) { const char *aux; if ((ctinfo) < IP_CT_IS_REPLY) { mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff, buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]); return 1; } if (!mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff, buffer, bufflen, &ct_sip_hdrs[POS_VIA])) return 0; /* This search should ignore case, but later.. */ aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1, (*pskb)->len - dataoff); if (!aux) return 0; if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"), ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff))) return 1; return mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff, buffer, bufflen, &ct_sip_hdrs[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])) 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]); 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]); }