static int mangle_content_len(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, struct ip_conntrack *ct, const char *dptr) { unsigned int dataoff, matchoff, matchlen; char buffer[sizeof("65536")]; int bufflen; dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); /* Get actual SDP lenght */ if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff, &matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) { /* since ct_sip_get_info() give us a pointer passing 'v=' we need to add 2 bytes in this count. */ int c_len = (*pskb)->len - dataoff - matchoff + 2; /* Now, update SDP lenght */ if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff, &matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) { bufflen = sprintf(buffer, "%u", c_len); return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, matchoff, matchlen, buffer, bufflen); } } return 0; }
static int mangle_content_len(struct sk_buff *skb, enum ip_conntrack_info ctinfo, struct nf_conn *ct, const char *dptr) { unsigned int dataoff, matchoff, matchlen; char buffer[sizeof("65536")]; int bufflen; dataoff = ip_hdrlen(skb) + sizeof(struct udphdr); /* Get actual SDP length */ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff, &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. */ int c_len = skb->len - dataoff - matchoff + 2; /* Now, update SDP length */ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff, &matchlen, POS_CONTENT) > 0) { bufflen = sprintf(buffer, "%u", c_len); return nf_nat_mangle_udp_packet(skb, ct, ctinfo, matchoff, matchlen, buffer, bufflen); } } return 0; }
static int map_sip_addr(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, struct nf_conn *ct, const char **dptr, size_t dlen, enum sip_header_pos pos, struct addr_map *map) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); unsigned int matchlen, matchoff, addrlen; char *addr; if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0) return 1; if ((matchlen == map->addr[dir].srciplen || matchlen == map->addr[dir].srclen) && strncmp(*dptr + matchoff, map->addr[dir].src, matchlen) == 0) { addr = map->addr[!dir].dst; addrlen = map->addr[!dir].dstlen; } else if ((matchlen == map->addr[dir].dstiplen || matchlen == map->addr[dir].dstlen) && strncmp(*dptr + matchoff, map->addr[dir].dst, matchlen) == 0) { addr = map->addr[!dir].src; addrlen = map->addr[!dir].srclen; } else return 1; if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo, matchoff, matchlen, addr, addrlen)) return 0; *dptr = (*pskb)->data + ip_hdrlen(*pskb) + sizeof(struct udphdr); return 1; }
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) { unsigned int matchlen, matchoff; if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0) return 0; if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo, matchoff, matchlen, buffer, bufflen)) return 0; /* We need to reload this. Thanks Patrick. */ *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); return 1; }
static unsigned int mangle_sip_packet(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, struct nf_conn *ct, const char **dptr, size_t dlen, char *buffer, int bufflen, enum sip_header_pos pos) { unsigned int matchlen, matchoff; if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0) return 0; if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo, matchoff, matchlen, buffer, bufflen)) return 0; /* We need to reload this. Thanks Patrick. */ *dptr = (*pskb)->data + ip_hdrlen(*pskb) + sizeof(struct udphdr); return 1; }