请教:sk_buff和ethhdr结构体中怎么获得源mac地址?并将类型转换?

andy_ker 2014-12-29 04:56:11
[code=c请教各位大神,写的这段代码功能没有实现,求指教!
static size_t _format_mac_addr(char *buf, int buflen,const unsigned char *addr, int len)//mac地址转换函数,转为 aa:aa:aa:aa:aa:aa 这类
{
int i;
char *cp = buf;
for (i = 0; i < len; i++) {
cp += scnprintf(cp, buflen - (cp - buf), "%02x", addr[i]);
if (i == len - 1)
break;
cp += scnprintf(cp, buflen - (cp - buf), ":");
}
return cp - buf;
}
unsigned int hook_func(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *))//获取源mac地址并和本机mac地址对比
{
char buffer[20];
u8 haddr[20];
struct ethhdr *eth;
eth=(struct ethhdr *)skb_mac_header(skb);
memcpy(haddr,eth->h_source,6);
_format_mac_addr(buffer, 18, haddr, 6);
if(strcmp(buffer,"b8:88:e3:72:31:44")==0)
return NF_ACCEPT;
else
return NF_DROP;
}][/code]
...全文
1362 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zuxi 2014-12-30
  • 打赏
  • 举报
回复
引用 8 楼 andy_ker 的回复:
[quote=引用 7 楼 wangzuxi 的回复:] [quote=引用 6 楼 andy_ker 的回复:] [quote=引用 5 楼 wangzuxi 的回复:] [quote=引用 2 楼 andy_ker 的回复:] [quote=引用 1 楼 wangzuxi 的回复:] 获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。
1、我是想比较本机发出去的数据包和本机MAC是否匹配,以为向纺织本机对网管的欺骗,所以我将hook发生在LOCAL_OUT阶段。2、MAC往skb里写内容和发生阶段有关系吗?不是很明白,怎么判断是否写了呢?[/quote] LOCAL_OUT阶段在POST_ROUTING阶段之前,都还没开始路由呢,应该还没有MAC头,所以你应该拿不到MAC信息。 你可以试试在POST_ROUTING阶段试试。 [/quote]您好,感谢您再次回复。关于LOCAL_OUT还是POSTROUTING的问题我有考虑过,也都实践了一遍,但是加载模块后都断网了,也就是说mac获取不正确。这就让我很纳闷了![/quote] 首先得先从原理上讲得通,是吧,程序有问题再调试,在LOCAL_OUT阶段内核还没写入MAC头,肯定得不得MAC信息。在POST_ROUTING阶段也不一定得到MAC头,这得你自己去试。其次你说的获取不正确是MAC为空还是MAC为其他主机的还是MAC为乱码? 你printk出来看一下就知道了。[/quote]是的,元里还不能讲得通,打印出来的mac是随机的,各个都不同。我在拼命查阅资料+调试。[/quote] 我没时间帮你看内核是怎么实现的了,能帮的就这么多了,建议你下载内核代码看看,比找资料来得快。 有时间我再看看吧。
andy_ker 2014-12-30
  • 打赏
  • 举报
回复
引用 7 楼 wangzuxi 的回复:
[quote=引用 6 楼 andy_ker 的回复:] [quote=引用 5 楼 wangzuxi 的回复:] [quote=引用 2 楼 andy_ker 的回复:] [quote=引用 1 楼 wangzuxi 的回复:] 获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。
1、我是想比较本机发出去的数据包和本机MAC是否匹配,以为向纺织本机对网管的欺骗,所以我将hook发生在LOCAL_OUT阶段。2、MAC往skb里写内容和发生阶段有关系吗?不是很明白,怎么判断是否写了呢?[/quote] LOCAL_OUT阶段在POST_ROUTING阶段之前,都还没开始路由呢,应该还没有MAC头,所以你应该拿不到MAC信息。 你可以试试在POST_ROUTING阶段试试。 [/quote]您好,感谢您再次回复。关于LOCAL_OUT还是POSTROUTING的问题我有考虑过,也都实践了一遍,但是加载模块后都断网了,也就是说mac获取不正确。这就让我很纳闷了![/quote] 首先得先从原理上讲得通,是吧,程序有问题再调试,在LOCAL_OUT阶段内核还没写入MAC头,肯定得不得MAC信息。在POST_ROUTING阶段也不一定得到MAC头,这得你自己去试。其次你说的获取不正确是MAC为空还是MAC为其他主机的还是MAC为乱码? 你printk出来看一下就知道了。[/quote]是的,元里还不能讲得通,打印出来的mac是随机的,各个都不同。我在拼命查阅资料+调试。
zuxi 2014-12-30
  • 打赏
  • 举报
回复
引用 6 楼 andy_ker 的回复:
[quote=引用 5 楼 wangzuxi 的回复:] [quote=引用 2 楼 andy_ker 的回复:] [quote=引用 1 楼 wangzuxi 的回复:] 获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。
1、我是想比较本机发出去的数据包和本机MAC是否匹配,以为向纺织本机对网管的欺骗,所以我将hook发生在LOCAL_OUT阶段。2、MAC往skb里写内容和发生阶段有关系吗?不是很明白,怎么判断是否写了呢?[/quote] LOCAL_OUT阶段在POST_ROUTING阶段之前,都还没开始路由呢,应该还没有MAC头,所以你应该拿不到MAC信息。 你可以试试在POST_ROUTING阶段试试。 [/quote]您好,感谢您再次回复。关于LOCAL_OUT还是POSTROUTING的问题我有考虑过,也都实践了一遍,但是加载模块后都断网了,也就是说mac获取不正确。这就让我很纳闷了![/quote] 首先得先从原理上讲得通,是吧,程序有问题再调试,在LOCAL_OUT阶段内核还没写入MAC头,肯定得不得MAC信息。在POST_ROUTING阶段也不一定得到MAC头,这得你自己去试。其次你说的获取不正确是MAC为空还是MAC为其他主机的还是MAC为乱码? 你printk出来看一下就知道了。
andy_ker 2014-12-30
  • 打赏
  • 举报
回复
引用 5 楼 wangzuxi 的回复:
[quote=引用 2 楼 andy_ker 的回复:] [quote=引用 1 楼 wangzuxi 的回复:] 获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。
1、我是想比较本机发出去的数据包和本机MAC是否匹配,以为向纺织本机对网管的欺骗,所以我将hook发生在LOCAL_OUT阶段。2、MAC往skb里写内容和发生阶段有关系吗?不是很明白,怎么判断是否写了呢?[/quote] LOCAL_OUT阶段在POST_ROUTING阶段之前,都还没开始路由呢,应该还没有MAC头,所以你应该拿不到MAC信息。 你可以试试在POST_ROUTING阶段试试。 [/quote]您好,感谢您再次回复。关于LOCAL_OUT还是POSTROUTING的问题我有考虑过,也都实践了一遍,但是加载模块后都断网了,也就是说mac获取不正确。这就让我很纳闷了!
zuxi 2014-12-30
  • 打赏
  • 举报
回复
引用 2 楼 andy_ker 的回复:
[quote=引用 1 楼 wangzuxi 的回复:] 获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。
1、我是想比较本机发出去的数据包和本机MAC是否匹配,以为向纺织本机对网管的欺骗,所以我将hook发生在LOCAL_OUT阶段。2、MAC往skb里写内容和发生阶段有关系吗?不是很明白,怎么判断是否写了呢?[/quote] LOCAL_OUT阶段在POST_ROUTING阶段之前,都还没开始路由呢,应该还没有MAC头,所以你应该拿不到MAC信息。 你可以试试在POST_ROUTING阶段试试。
andy_ker 2014-12-30
  • 打赏
  • 举报
回复
引用 3 楼 YuZhiHui_No1 的回复:
你好,首先回答你在我博文下的提问。“skb_reset_mac_header(skb);//该函数的实现skb->mac_header = skb->data; ”这个是没有错的,因为执行这个函数时skb数据包是在二层的,所以skb->data指向的就是mac地址;然后我看了下你的程序,获取Mac地址是没有错的,但是就像第一个评论回复的那样,关键要看你是在哪里截取到的skb?如果你在二层以上截取的,那么Mac地址肯定是空的。但是具体在哪一步截取skb,Mac地址才会有呢,我不是很清楚,推测是在进入网卡驱动时才会调用相应函数添上该网卡的Mac地址,所以最好是在调用该函数后你再截取skb才是有效的。
您好!很感谢您的回复!我对层的这个概念还是不太理解,因为是新手,查了资料还是没能形成完整的架构。我给您贴出我的完整代码,烦请您帮我看一下。我的最终目的就是获取本机发出去的数据包的原mac地址,和本机mac地址进行比较,不一样的话就丢弃以防止本机ARP欺骗。恳请您!谢谢了!#include<linux/module.h> #include<linux/init.h> #include<linux/kernel.h> #include<linux/netfilter.h> #include<linux/netfilter_ipv4.h> #include<linux/ip.h> #include<net/ip.h> #include<linux/udp.h> #include<linux/in.h> #include<linux/skbuff.h> #include<linux/netdevice.h> #include<linux/if_ether.h> #include<linux/if.h> //static size_t _format_mac_addr(char *buf, int buflen,const unsigned char *addr, int len) //{ // int i; // char *cp = buf; // for (i = 0; i < len; i++) { // cp += scnprintf(cp, buflen - (cp - buf), "%02x", addr[i]); // if (i == len - 1) // break; // cp += scnprintf(cp, buflen - (cp - buf), ":"); // } // return cp - buf; //} unsigned int hook_func(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *)) { char buffer[20]; u8 haddr[20]; struct ethhdr *eth; eth=(struct ethhdr *)skb_mac_header(skb); memcpy(haddr,eth->h_source,6); sprintf(buffer,"%02x:%02x:%02x:%02x:%02x:%02x",haddr[0],haddr[1],haddr[2],haddr[3],haddr[4],haddr[5]); printk("love %x\n",buffer); // _format_mac_addr(buffer, 18, haddr, 6); if(strcmp(buffer,"b8:88:e3:72:31:44")==0) return NF_ACCEPT; else return NF_DROP; } static struct nf_hook_ops nfho={ .hook=hook_func, .pf=PF_INET, .hooknum=NF_INET_LOCAL_OUT, .priority=NF_IP_PRI_FIRST, .owner=THIS_MODULE, }; static int __init hook_init(void) { if (nf_register_hook(&nfho)) { printk(KERN_ERR"<0>nf_register_hook() failed\n"); return -1; } return 0; } static void __exit hook_fini(void) { nf_unregister_hook(&nfho); } module_init(hook_init); module_exit(hook_fini); MODULE_LICENSE("GPL");
庾志辉 2014-12-30
  • 打赏
  • 举报
回复
你好,首先回答你在我博文下的提问。“skb_reset_mac_header(skb);//该函数的实现skb->mac_header = skb->data; ”这个是没有错的,因为执行这个函数时skb数据包是在二层的,所以skb->data指向的就是mac地址;然后我看了下你的程序,获取Mac地址是没有错的,但是就像第一个评论回复的那样,关键要看你是在哪里截取到的skb?如果你在二层以上截取的,那么Mac地址肯定是空的。但是具体在哪一步截取skb,Mac地址才会有呢,我不是很清楚,推测是在进入网卡驱动时才会调用相应函数添上该网卡的Mac地址,所以最好是在调用该函数后你再截取skb才是有效的。
andy_ker 2014-12-30
  • 打赏
  • 举报
回复
引用 1 楼 wangzuxi 的回复:
获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。
1、我是想比较本机发出去的数据包和本机MAC是否匹配,以为向纺织本机对网管的欺骗,所以我将hook发生在LOCAL_OUT阶段。2、MAC往skb里写内容和发生阶段有关系吗?不是很明白,怎么判断是否写了呢?
andy_ker 2014-12-30
  • 打赏
  • 举报
回复
引用 10 楼 YuZhiHui_No1 的回复:
static struct nf_hook_ops nfho={ .hook=hook_func, .pf=PF_INET, .hooknum=NF_INET_LOCAL_OUT, .priority=NF_IP_PRI_FIRST, .owner=THIS_MODULE, };中“.hooknum=NF_INET_LOCAL_OUT”有这么个检查点吗?(NF_IP_LOCAL_OUT:是本机进程的数据包离开本机的过程中的一个检查点 )你试试用NF_IP_POST_ROUTING(这是离开本机到进入网络之前的一个检查点) 看看,我也是上午刚查了下资料。
用IP的话报错,我也是在网上查了资料,内核版本2.6之后的都改为NET了. 因为我只想抓取ARP报文,所以我参考网上一篇文章把程序修改了一下,可是压根没抓到ARP数据包,真是不明白。#include<linux/module.h> #include<linux/init.h> #include<linux/kernel.h> #include<linux/netfilter.h> #include<linux/netfilter_ipv4.h> #include<linux/ip.h> #include<net/ip.h> #include<netinet/if_ether.h> #include<linux/udp.h> #include<linux/in.h> #include<linux/skbuff.h> #include<linux/netdevice.h> #include<linux/if_ether.h> #include<linux/if.h> #include<linux/if_arp.h> #include<linux/netfilter_arp.h> unsigned int hook_func(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *)) { char buffer[20]; u8 haddr[20]; struct ether_arp *eth; eth=(struct ether_arp *)skb_mac_header(skb); printk("hehe:%x\n",eth->arp_sha); memcpy(haddr,eth->arp_sha,6); sprintf(buffer,"%02x:%02x:%02x:%02x:%02x:%02x",haddr[0],haddr[1],haddr[2],haddr[3],haddr[4],haddr[5]); //printk("love: %s\n",buffer); if(strcmp(buffer,"dc:0e:a1:e8:94:d6")==0) return NF_ACCEPT; else return NF_DROP; } static struct nf_hook_ops nfho={ .hook=hook_func, .pf=NF_ARP, .hooknum=NF_ARP_OUT, //.priority=NF_IP_PRI_FIRST, .owner=THIS_MODULE, }; static int __init hook_init(void) { if (nf_register_hook(&nfho)) { printk(KERN_ERR"<0>nf_register_hook() failed\n"); return -1; } return 0; } static void __exit hook_fini(void) { nf_unregister_hook(&nfho); } module_init(hook_init); module_exit(hook_fini); MODULE_LICENSE("GPL");
庾志辉 2014-12-30
  • 打赏
  • 举报
回复
static struct nf_hook_ops nfho={ .hook=hook_func, .pf=PF_INET, .hooknum=NF_INET_LOCAL_OUT, .priority=NF_IP_PRI_FIRST, .owner=THIS_MODULE, };中“.hooknum=NF_INET_LOCAL_OUT”有这么个检查点吗?(NF_IP_LOCAL_OUT:是本机进程的数据包离开本机的过程中的一个检查点 )你试试用NF_IP_POST_ROUTING(这是离开本机到进入网络之前的一个检查点) 看看,我也是上午刚查了下资料。
zuxi 2014-12-29
  • 打赏
  • 举报
回复
获取MAC的方法没有问题,但是不管是你本机主动发送的数据包还是转发的数据包,源MAC都是发出去那个网卡的MAC,所以strcmp(buffer,"b8:88:e3:72:31:44")==0这句应该一直为true。 另外你也要看hook_func这个netfilter勾子是在哪个阶段,看内核把MAC往skb里写了没有,如果还没有写入的话,你也是拿不到MAC的。

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧