- 论坛徽章:
- 0
|
如下图所示,设备收到该报文,如何去掉隧道头部,将原报文发送给协议栈列?
我在LCAOL_IN加了一个钩子函数,做了如下动作
代码中用到的结构体:
typedef struct st_Ether
{
uint8_t dest[6];
uint8_t src[6];
uint16_t proto;
uint8_t data[0];
} tEther;
struct vxlan_header {
uint32_t flags;
uint32_t vni;
uint8_t data[0];
};
typedef struct st_Ip
{
uint8_t hlen;
uint8_t tos;
uint16_t len;
uint16_t ipid;
uint16_t fragoff;
uint8_t ttl;
uint8_t proto;
uint16_t cksum;
union {
uint32_t src;
uint8_t src1[4];
};
union {
uint32_t dest;
uint8_t dest1[4];
};
uint8_t data[0];
} tIp;
typedef struct st_Udp
{
uint16_t sport;
uint16_t dport;
uint16_t len;
uint16_t cksum;
char data[0];
} tUdp;
typedef struct st_Tcp
{
uint16_t sport;
uint16_t dport;
uint32_t seq;
uint32_t ack;
uint8_t offset;
uint8_t code;
uint16_t window;
uint16_t cksum;
uint16_t urg;
char data[0];
} tTcp;
代码如下:
static int del_tunnel_vxlan(struct sk_buff *skb)
{
UINT1 buff[1514] ={0};
tEther* peth =NULL;
tIp* pIp=(tIp*)ip_hdr(skb);
tUdp* pudp = (tUdp*)pIp->data;
struct vxlan_header* pvxlan = (struct vxlan_header*)pudp->data;
UINT1 *p;
int pkt_len = skb->len - 50+14;//原报文长度(74)
int data_len = pkt_len-sizeof(struct iphdr)-sizeof(struct ethhdr);
int ip_len = data_len + sizeof(struct iphdr);
printk(KERN_ALERT "skb->len:%d,pkt_len:%d;data_len:%d\n",skb->len,pkt_len,data_len);
memcpy(buff,pvxlan->data,data_len); 将原报文拷贝到buff中
peth = (tEther*)buff;
if(peth->proto != ntohs(ETH_P_IP))
return 1;
pIp = (tIp*)peth->data;
skb_reserve(skb,skb->len +2);
p = skb_push(skb,data_len);
memcpy(p,pIp->data,data_len);
skb_reset_transport_header(skb);
p = skb_push(skb,sizeof(struct iphdr));
memcpy(p,peth->data,sizeof(struct iphdr));
skb_reset_network_header(skb);
p = skb_push(skb,sizeof(struct ethhdr));
memcpy(p,buff,sizeof(struct ethhdr));
skb_reset_mac_header(skb);
return 0;
}
static unsigned int nf_hook_in(unsigned int hooknum,struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff*))
{
struct sk_buff *sb = skb;
struct tcphdr *tcph = NULL;
tIp* pIp = (tIp*)ip_hdr(sb);
tTcp* ptcp = NULL;
unsigned int src_ip = pIp->src;
switch(pIp->proto)
{
case IPPROTO_UDP:
{
tUdp* pudp =(tUdp*)pIp->data;
if(pIp->src == in_aton("172.16.3.40") && pIp->dest == in_aton("172.16.3.38"))
{
if(pudp->sport == ntohs(4789)&& pudp->dport == ntohs(4789))
{
del_tunnel_vxlan(skb);
printk(KERN_ALERT "del_tunnel_vxlan ok\n");
return NF_ACCEPT;
}
}
}
break;
default:
break;
}
return NF_ACCEPT; //í
}
但是并没有抓到去隧道之后的报文或者回复报文;
|
|