其实,我觉得这两种模式没什么区别。 但是,按照目前内核本身的这个结构(VLAN的),TAG是在“网卡驱动”中压入的。也就是在vlan的虚拟网卡中处理的。这也就是在协议栈之后了。 2种方法 1:在netfilter的时候,选择一个对应tag的正确的出接口 2:在netfilter的时候,给skb做个标记,在vlan的vlan_dev_hard_start_xmit中的skb = __vlan_put_tag(skb, veth_TCI);传入标记,取代veth_TCI。
IPv6头部的设计是一个简洁的基本头部后面根据需要加上多种不同类型的扩展头部,这种设计可以将不常用的功能通过选择性的添加不同的扩展头部实现,从而在保证了基本头部的简洁和处理的快速性。以Linux2628版本内核为例,IPv6扩展首部的定义在Linux-2628/include/linux/in6h和linux-2628/include/net/ipv6h两个目录下,我们以添加一种IPPROTO_MY类型的扩展头为例:
1、在头文件中添加新类型扩展头的定义,在linux-2628/include/linux/in6h中
/
NextHeader field of IPv6 header
/
#define NEXTHDR_HOP 0 / Hop-by-hop option header /
#define NEXTHDR_TCP 6 / TCP segment /
#define NEXTHDR_UDP 17 / UDP message /
#define NEXTHDR_IPV6 41 / IPv6 in IPv6 /
#define NEXTHDR_ROUTING 43 / Routing header /
#define NEXTHDR_FRAGMENT 44 / Fragmentation/reassembly header /
#define NEXTHDR_ESP 50 / Encapsulating security payload /
#define NEXTHDR_AUTH 51 / Authentication header /
#define NEXTHDR_ICMP 58 / ICMP for IPv6 /
#define NEXTHDR_NONE 59 / No next header /
#define NEXTHDR_DEST 60 / Destination options header /
#define NEXTHDR_MOBILITY 135 / Mobility header /
#define IPPROTO_MY 200 /自己定义的头部类型 /
2、在linux-2628/include/net/ipv6h中定义结构体
/
IPV6 extension headers
/
#define IPPROTO_HOPOPTS 0 / IPv6 hop-by-hop options /
#define IPPROTO_ROUTING 43 / IPv6 routing header /
#define IPPROTO_FRAGMENT 44 / IPv6 fragmentation header /
#define IPPROTO_ICMPV6 58 / ICMPv6 /
#define IPPROTO_NONE 59 / IPv6 no next header /
#define IPPROTO_DSTOPTS 60 / IPv6 destination options /
#define IPPROTO_MH 135 / IPv6 mobility header /
自己定义新的扩展头类型如:
#define NEXTHDR_INDEX 200 /IPv6 next header /
自己定义新的扩展头类型:
struct index_hdr{ /index扩展头结构/
__u8 nexthdr;
__u8 hdrlen;
__u16 reserved;
__u32 skb_index;
};
3、在需要添加头部和删除头部的源文件中添加添加和删除函数,届时直接调用这两个函数即可
static void ip6_index_add(struct sk_buff skb,unsigned char data,unsigned int len)
{
struct ipv6hdr tmp_hdr;
struct ipv6hdr old_hdr;
struct index_hdr ih;
u8 prevhdr;
unsigned int hlen;
unsigned int ilen;
ilen=sizeof(struct index_hdr);
hlen=sizeof(struct ipv6hdr);
old_hdr=skb_network_header(skb);
prevhdr=old_hdr->nexthdr;
if(prevhdr!=200){
old_hdr->nexthdr=NEXTHDR_INDEX;
tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
__skb_pull(skb, hlen); /使data指针下移hlen长度,将ipv6头部去掉/
ih = (struct index_hdr)__skb_push(skb, ilen); /上移data指针,将index头部添加进去/
__skb_push(skb, hlen); /继续上移data指针,将原来的ipv6头部加进去/
skb_reset_network_header(skb);
memcpy(skb_network_header(skb), tmp_hdr, hlen);
/为index扩展头赋值/
ih->nexthdr = prevhdr;
ih->hdrlen = 8;
ih->reserved = 0;
ih->skb_index = htonl(skb->xfrm_index);
skb->truesize += ilen;
ipv6_hdr(skb)->payload_len += ilen;
data = skb->data;
len = skb->len;
kfree(tmp_hdr);
}
}
static void ip6_index_del(struct sk_buff skb,unsigned char data,unsigned int len)
{
struct ipv6hdr tmp_hdr;
struct ipv6hdr old_hdr;
struct index_hdr ih;
u8 prevhdr;
unsigned int hlen;
unsigned int ilen;
ilen=sizeof(struct index_hdr);
hlen=sizeof(struct ipv6hdr);
if(ipv6_hdr(skb)->nexthdr == 200){
tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); /保存ipv6头/
__skb_pull(skb, hlen); /下移data指针,去掉ipv6头/
skb_reset_network_header(skb);
ih=(struct index_hdr )skb_network_header(skb);
prevhdr = ih->nexthdr;
tmp_hdr->nexthdr = prevhdr;
__skb_pull(skb, ilen); /下移data指针,去掉index扩展头/
__skb_push(skb, hlen); /上移data指针,将原来的ipv6头添加回去/
skb_reset_network_header(skb);
memcpy(skb_network_header(skb), tmp_hdr, hlen);
skb_reset_network_header(skb);
skb->truesize -= ilen;
ipv6_hdr(skb)->payload_len -= ilen;
kfree(tmp_hdr);
}
}
嵌入式linux,linux系统编程要去做网络安全防火墙开发,是不是两个不同的方向?都研二了,有必要去学习网络安全的netfilter/iptables等东西吗?这个对网络编程提高有很大的用处没?
你正好是做这方面的,麻烦都我回答一下,谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)