当前位置: 技术问答>linux和unix
在内核模块级缓冲UDP的问题(当然不是SOCKET编程了。)
来源: 互联网 发布时间:2015-03-04
本文导语: 毕设在写LINUX内核模块。现在碰到一个问题。 总目标:在一个截包函数中缓冲所有UDP包。 截包函数如下。 tatic unsigned int mipv6_intercept(//一个截包的函数 unsigned int hooknum, struct sk_buff **p_skb,//在/usr/src/...
毕设在写LINUX内核模块。现在碰到一个问题。
总目标:在一个截包函数中缓冲所有UDP包。
截包函数如下。
tatic unsigned int mipv6_intercept(//一个截包的函数
unsigned int hooknum,
struct sk_buff **p_skb,//在/usr/src/linux-2.4.20的linux目录下skbuff.h里定义,很好的一结构。在这里主要用它,具体结构见最后
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *skb = (p_skb) ? *p_skb : NULL;
struct ipv6hdr *ipv6h;
struct in6_addr *daddr, *saddr;
__u8 nexthdr;
int nhoff;
if(skb == NULL) return NF_ACCEPT;
ipv6h = skb->nh.ipv6h;
daddr = &ipv6h->daddr;
saddr = &ipv6h->saddr;
nexthdr = ipv6h->nexthdr;//第一个是IP6包头,nexthdr是下一个包头的类型。
//---------以下----有关ICMPV6包的----------可不管---------
if (ipv6_ext_hdr(nexthdr))
nhoff = ipv6_skip_exthdr(skb, nhoff, &nexthdr,
skb->len - sizeof(*ipv6h));
/*
* Possible ICMP packets are checked to ensure that all neighbor
* solicitations to MNs home address are handled by the HA.
*/
if (nexthdr == IPPROTO_ICMPV6) {
struct icmp6hdr *icmp6h;
int dest_type;
if (nhoff nh.raw[nhoff];
/* HA has to capture all unicast 单播neighbour solicitations in
order to check if it is acting as a proxy for the target
address. */
if ((dest_type & IPV6_ADDR_UNICAST) &&
icmp6h->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
ip6_input(skb);
return NF_STOLEN;
}
}
//---------以上----有关ICMPV6包的----可不管---------------
//---------以下为UDP包的外理-----------------------
if (nexthdr == 17)//17=0x11就是说这个是UDP包,我要缓冲它
{
printk("this is a udp packet n");
//之后我想打出这个UDP包的内容,缓冲这个UDP包等。
//怎么写???
我想随便打几个结构里的信息出来看看都说错。(模仿系统里UDP.c中的写法)
struct udphdr *uh;
printk("udphdr's source=%dn",uh->source);//在编译模块时说错:dereference pointer to incomplete type
//------------------以上为UDP包处理--------没完成-不会写了------
}
以下为SK_BUFF的结构,含有传输层,网络层,链路层 3层中各种协议的结构,巨好。
struct sk_buff {
/* These two members must be first. */
struct sk_buff * next; /* Next buffer in list */
struct sk_buff * prev; /* Previous buffer in list */
struct sk_buff_head * list; /* List we are on */
struct sock *sk; /* Socket we are owned by */
struct timeval stamp; /* Time we arrived */
struct net_device *dev; /* Device we arrived on/are leaving by */
/* Transport layer header */
union
{
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct spxhdr *spxh;
unsigned char *raw;
} h;
/* Network layer header */
union
{
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
struct ipxhdr *ipxh;
unsigned char *raw;
} nh;
/* Link layer header */
union
{
struct ethhdr *ethernet;
unsigned char *raw;
} mac;
struct dst_entry *dst;
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48];
unsigned int len; /* Length of actual data */
unsigned int data_len;
unsigned int csum; /* Checksum */
unsigned char __unused, /* Dead field, may be reused */
cloned, /* head may be cloned (check refcnt to be sure). */
pkt_type, /* Packet class */
ip_summed; /* Driver fed us an IP checksum */
__u32 priority; /* Packet queueing priority */
atomic_t users; /* User count - see datagram.c,tcp.c */
unsigned short protocol; /* Packet protocol from driver. */
unsigned short security; /* Security level of packet */
unsigned int truesize; /* Buffer size */
unsigned char *head; /* Head of buffer */
unsigned char *data; /* Data head pointer */
unsigned char *tail; /* Tail pointer */
unsigned char *end; /* End pointer */
void (*destructor)(struct sk_buff *); /* Destruct function */
#ifdef CONFIG_NETFILTER
/* Can be used for communication between hooks. */
unsigned long nfmark;
/* Cache info */
__u32 nfcache;
/* Associated connection, if any */
struct nf_ct_info *nfct;
#ifdef CONFIG_NETFILTER_DEBUG
unsigned int nf_debug;
#endif
#endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_HIPPI)
union{
__u32 ifield;
} private;
#endif
#ifdef CONFIG_NET_SCHED
__u32 tc_index; /* traffic control index */
#endif
};
总目标:在一个截包函数中缓冲所有UDP包。
截包函数如下。
tatic unsigned int mipv6_intercept(//一个截包的函数
unsigned int hooknum,
struct sk_buff **p_skb,//在/usr/src/linux-2.4.20的linux目录下skbuff.h里定义,很好的一结构。在这里主要用它,具体结构见最后
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *skb = (p_skb) ? *p_skb : NULL;
struct ipv6hdr *ipv6h;
struct in6_addr *daddr, *saddr;
__u8 nexthdr;
int nhoff;
if(skb == NULL) return NF_ACCEPT;
ipv6h = skb->nh.ipv6h;
daddr = &ipv6h->daddr;
saddr = &ipv6h->saddr;
nexthdr = ipv6h->nexthdr;//第一个是IP6包头,nexthdr是下一个包头的类型。
//---------以下----有关ICMPV6包的----------可不管---------
if (ipv6_ext_hdr(nexthdr))
nhoff = ipv6_skip_exthdr(skb, nhoff, &nexthdr,
skb->len - sizeof(*ipv6h));
/*
* Possible ICMP packets are checked to ensure that all neighbor
* solicitations to MNs home address are handled by the HA.
*/
if (nexthdr == IPPROTO_ICMPV6) {
struct icmp6hdr *icmp6h;
int dest_type;
if (nhoff nh.raw[nhoff];
/* HA has to capture all unicast 单播neighbour solicitations in
order to check if it is acting as a proxy for the target
address. */
if ((dest_type & IPV6_ADDR_UNICAST) &&
icmp6h->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
ip6_input(skb);
return NF_STOLEN;
}
}
//---------以上----有关ICMPV6包的----可不管---------------
//---------以下为UDP包的外理-----------------------
if (nexthdr == 17)//17=0x11就是说这个是UDP包,我要缓冲它
{
printk("this is a udp packet n");
//之后我想打出这个UDP包的内容,缓冲这个UDP包等。
//怎么写???
我想随便打几个结构里的信息出来看看都说错。(模仿系统里UDP.c中的写法)
struct udphdr *uh;
printk("udphdr's source=%dn",uh->source);//在编译模块时说错:dereference pointer to incomplete type
//------------------以上为UDP包处理--------没完成-不会写了------
}
以下为SK_BUFF的结构,含有传输层,网络层,链路层 3层中各种协议的结构,巨好。
struct sk_buff {
/* These two members must be first. */
struct sk_buff * next; /* Next buffer in list */
struct sk_buff * prev; /* Previous buffer in list */
struct sk_buff_head * list; /* List we are on */
struct sock *sk; /* Socket we are owned by */
struct timeval stamp; /* Time we arrived */
struct net_device *dev; /* Device we arrived on/are leaving by */
/* Transport layer header */
union
{
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct spxhdr *spxh;
unsigned char *raw;
} h;
/* Network layer header */
union
{
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
struct ipxhdr *ipxh;
unsigned char *raw;
} nh;
/* Link layer header */
union
{
struct ethhdr *ethernet;
unsigned char *raw;
} mac;
struct dst_entry *dst;
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48];
unsigned int len; /* Length of actual data */
unsigned int data_len;
unsigned int csum; /* Checksum */
unsigned char __unused, /* Dead field, may be reused */
cloned, /* head may be cloned (check refcnt to be sure). */
pkt_type, /* Packet class */
ip_summed; /* Driver fed us an IP checksum */
__u32 priority; /* Packet queueing priority */
atomic_t users; /* User count - see datagram.c,tcp.c */
unsigned short protocol; /* Packet protocol from driver. */
unsigned short security; /* Security level of packet */
unsigned int truesize; /* Buffer size */
unsigned char *head; /* Head of buffer */
unsigned char *data; /* Data head pointer */
unsigned char *tail; /* Tail pointer */
unsigned char *end; /* End pointer */
void (*destructor)(struct sk_buff *); /* Destruct function */
#ifdef CONFIG_NETFILTER
/* Can be used for communication between hooks. */
unsigned long nfmark;
/* Cache info */
__u32 nfcache;
/* Associated connection, if any */
struct nf_ct_info *nfct;
#ifdef CONFIG_NETFILTER_DEBUG
unsigned int nf_debug;
#endif
#endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_HIPPI)
union{
__u32 ifield;
} private;
#endif
#ifdef CONFIG_NET_SCHED
__u32 tc_index; /* traffic control index */
#endif
};
|
else if (nexthdr==17)
{
printk("tzh UDP :nexthdr=%d ",nexthdr);
printk("tzhbuf=%dn",tzhbuf);
//failed
//u32 ulen=0;
struct udphdr *udp6h;
int dest_type;
printk(" ##3#%d###",nhoff);
if (nhoff nh.raw[nhoff];
printk(" ##4#%d###",nhoff);
//printk("dup6h%dn",udp6h);
printk("tzh udphdr's source port =%un",ntohs(udp6h->source));
printk("tzh udphdr's dest port=%un",ntohs(udp6h->dest));
printk("tzh udphdr's length=%un",ntohs(udp6h->len));
printk("tzh udphdr's check=%un",ntohs(udp6h->check));
//__u16 * data=(__u16*)&skb->h.raw[sizeof(struct udphdr)];
__u16 * data=((__u16*)udp6h+sizeof(struct udphdr)/2);
int haha=sizeof(struct udphdr);
printk("data%dn",haha);
//data[14]='';
int i;
for(i=0;i