Browse Source

convert existing code to be (somewhat) address family agnostic

git.mgm/mediaproxy-ng/2.0
Richard Fuchs 14 years ago
parent
commit
eacef0b5c6
2 changed files with 97 additions and 25 deletions
  1. +84
    -19
      kernel-module/xt_MEDIAPROXY.c
  2. +13
    -6
      kernel-module/xt_MEDIAPROXY.h

+ 84
- 19
kernel-module/xt_MEDIAPROXY.c View File

@ -27,6 +27,26 @@ MODULE_LICENSE("GPL");
#define MAX_ID 64 /* - 1 */ #define MAX_ID 64 /* - 1 */
#define MIPF "%i:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x:%u"
#define MIPP(x) (x).family, \
(x).all[0], \
(x).all[1], \
(x).all[2], \
(x).all[3], \
(x).all[4], \
(x).all[5], \
(x).all[6], \
(x).all[7], \
(x).all[8], \
(x).all[9], \
(x).all[10], \
(x).all[11], \
(x).all[12], \
(x).all[13], \
(x).all[14], \
(x).all[15], \
(x).port
#if 0 #if 0
#define DBG(x...) printk(KERN_DEBUG x) #define DBG(x...) printk(KERN_DEBUG x)
#else #else
@ -668,6 +688,31 @@ static int table_del_target(struct mediaproxy_table *t, u_int16_t port) {
static int is_valid_address(struct mp_address *mpa) {
switch (mpa->family) {
case AF_INET:
if (!mpa->ipv4)
return 0;
break;
case AF_INET6:
if (!memcmp(mpa->ipv6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
return 0;
break;
default:
return 0;
}
if (!mpa->port)
return 0;
return 1;
}
static int table_new_target(struct mediaproxy_table *t, struct mediaproxy_target_info *i, int update) { static int table_new_target(struct mediaproxy_table *t, struct mediaproxy_target_info *i, int update) {
unsigned char hi, lo; unsigned char hi, lo;
@ -679,13 +724,11 @@ static int table_new_target(struct mediaproxy_table *t, struct mediaproxy_target
if (!i->target_port) if (!i->target_port)
return -EINVAL; return -EINVAL;
if (!i->src_ip)
return -EINVAL;
if (!i->dst_ip)
if (!is_valid_address(&i->src_addr))
return -EINVAL; return -EINVAL;
if (!i->src_port)
if (!is_valid_address(&i->dst_addr))
return -EINVAL; return -EINVAL;
if (!i->dst_port)
if (i->src_addr.family != i->dst_addr.family)
return -EINVAL; return -EINVAL;
DBG(KERN_DEBUG "Creating new target\n"); DBG(KERN_DEBUG "Creating new target\n");
@ -961,7 +1004,7 @@ err:
static int send_proxy_packet(struct sk_buff *skb, u_int32_t sip, u_int16_t sport, u_int32_t dip, u_int16_t dport, unsigned char tos) {
static int send_proxy_packet4(struct sk_buff *skb, struct mp_address *src, struct mp_address *dst, unsigned char tos) {
struct iphdr *ih; struct iphdr *ih;
struct udphdr *uh; struct udphdr *uh;
int datalen; int datalen;
@ -971,16 +1014,16 @@ static int send_proxy_packet(struct sk_buff *skb, u_int32_t sip, u_int16_t sport
datalen = ntohs(uh->len); datalen = ntohs(uh->len);
ih->saddr = sip;
ih->daddr = dip;
ih->saddr = src->ipv4;
ih->daddr = dst->ipv4;
ih->tos = tos; ih->tos = tos;
uh->source = htons(sport);
uh->dest = htons(dport);
uh->source = htons(src->port);
uh->dest = htons(dst->port);
uh->check = 0; uh->check = 0;
skb->csum_start = skb_transport_header(skb) - skb->head; skb->csum_start = skb_transport_header(skb) - skb->head;
skb->csum_offset = offsetof(struct udphdr, check); skb->csum_offset = offsetof(struct udphdr, check);
uh->check = csum_tcpudp_magic(sip, dip, datalen, IPPROTO_UDP, csum_partial(uh, datalen, 0));
uh->check = csum_tcpudp_magic(src->ipv4, dst->ipv4, datalen, IPPROTO_UDP, csum_partial(uh, datalen, 0));
if (uh->check == 0) if (uh->check == 0)
uh->check = CSUM_MANGLED_0; uh->check = CSUM_MANGLED_0;
@ -1005,11 +1048,33 @@ drop:
static int send_proxy_packet(struct sk_buff *skb, struct mp_address *src, struct mp_address *dst, unsigned char tos) {
if (src->family != dst->family)
goto drop;
switch (src->family) {
case AF_INET:
return send_proxy_packet4(skb, src, dst, tos);
break;
default:
goto drop;
}
drop:
kfree_skb(skb);
return -1;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
static unsigned int mediaproxy(struct sk_buff *oskb, const struct xt_target_param *par) {
static unsigned int mediaproxy4(struct sk_buff *oskb, const struct xt_target_param *par) {
#else #else
static unsigned int mediaproxy(struct sk_buff *oskb, const struct xt_action_param *par) {
static unsigned int mediaproxy4(struct sk_buff *oskb, const struct xt_action_param *par) {
#endif #endif
const struct xt_mediaproxy_info *pinfo = par->targinfo; const struct xt_mediaproxy_info *pinfo = par->targinfo;
struct sk_buff *skb; struct sk_buff *skb;
@ -1041,12 +1106,12 @@ static unsigned int mediaproxy(struct sk_buff *oskb, const struct xt_action_para
if (!g) if (!g)
goto skip2; goto skip2;
DBG(KERN_DEBUG "target found, src %08x -> dst %08x\n", g->target.src_ip, g->target.dst_ip);
DBG(KERN_DEBUG "target found, src "MIPF" -> dst "MIPF"\n", MIPP(g->target.src_addr), MIPP(g->target.dst_addr));
if (g->target.mirror_ip && g->target.mirror_port) {
DBG(KERN_DEBUG "sending mirror packet to dst %08x\n", g->target.mirror_ip);
if (is_valid_address(&g->target.mirror_addr)) {
DBG(KERN_DEBUG "sending mirror packet to dst "MIPF"\n", MIPP(g->target.mirror_addr));
skb2 = skb_copy(skb, GFP_ATOMIC); skb2 = skb_copy(skb, GFP_ATOMIC);
err = send_proxy_packet(skb2, g->target.src_ip, g->target.src_port, g->target.mirror_ip, g->target.mirror_port, g->target.tos);
err = send_proxy_packet(skb2, &g->target.src_addr, &g->target.mirror_addr, g->target.tos);
if (err) { if (err) {
spin_lock_irqsave(&g->lock, flags); spin_lock_irqsave(&g->lock, flags);
g->stats.errors++; g->stats.errors++;
@ -1054,7 +1119,7 @@ static unsigned int mediaproxy(struct sk_buff *oskb, const struct xt_action_para
} }
} }
err = send_proxy_packet(skb, g->target.src_ip, g->target.src_port, g->target.dst_ip, g->target.dst_port, g->target.tos);
err = send_proxy_packet(skb, &g->target.src_addr, &g->target.dst_addr, g->target.tos);
spin_lock_irqsave(&g->lock, flags); spin_lock_irqsave(&g->lock, flags);
if (err) if (err)
@ -1123,7 +1188,7 @@ static struct xt_target xt_mediaproxy_regs[] = {
{ {
.name = "MEDIAPROXY", .name = "MEDIAPROXY",
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.target = mediaproxy,
.target = mediaproxy4,
.targetsize = sizeof(struct xt_mediaproxy_info), .targetsize = sizeof(struct xt_mediaproxy_info),
.table = "filter", .table = "filter",
.hooks = (1 << NF_INET_LOCAL_IN), .hooks = (1 << NF_INET_LOCAL_IN),


+ 13
- 6
kernel-module/xt_MEDIAPROXY.h View File

@ -11,16 +11,23 @@ struct mediaproxy_stats {
u_int64_t errors; u_int64_t errors;
}; };
struct mp_address {
int family;
union {
unsigned char all[16];
unsigned char ipv6[16];
u_int32_t ipv4;
};
u_int16_t port;
};
struct mediaproxy_target_info { struct mediaproxy_target_info {
u_int16_t target_port; u_int16_t target_port;
u_int32_t src_ip;
u_int32_t dst_ip;
u_int16_t src_port;
u_int16_t dst_port;
struct mp_address src_addr;
struct mp_address dst_addr;
u_int32_t mirror_ip;
u_int16_t mirror_port;
struct mp_address mirror_addr;
unsigned char tos; unsigned char tos;
}; };


Loading…
Cancel
Save