netlink编程注意事项
2011-05-05 17:20
405 查看
最近用了一下netlink,比较方便。特将netlink编程中的注意事项列下:
1、选一个没有用到的
协议类型
,
注意要避开netlink.h中已经定义好的类型。注意保证内核层和用户层的协议类类型的一致。也就是说内核层创建netlink函数
netlink_kernel_create的第一个参数和用户层创建socket的socket函数的第三个参数要一致。否则是不能建立连接的。
2、版本问题。
如
果你在网上搜到一个帖子说netlink代码保证可用,你满心欢喜把代码贴到自己机器上,八成是不能用。因为netlink在linux2.6.XX的版
本中变化的太快了。在内核态,大致有这么几个地方会随着版本的变化而变化:
a)netlink_kernel_create函数的原型;b)nlmsg_put/NLMSG_PUT的原型。
贴一下我的代码,估计也不是很全面:
a) netlink_kernel_create函数的原型:
//init_net是一个内核变量
#if LINUX_VERSION_CODE >= 0x020618
fspwfd = netlink_kernel_create(&init_net
,NETLINK_TYPE, 0, yourHandler, NULL,THIS_MODULE);
#elif LINUX_VERSION_CODE >= 0x020616
fspwfd = netlink_kernel_create(NETLINK_TYPE, 0, yourHandler, NULL,THIS_MODULE);
#elif LINUX_VERSION_CODE >= 0x020610
fspwfd = netlink_kernel_create(NETLINK_TYPE, 0, yourHandler,THIS_MODULE);
#else
fspwfd = netlink_kernel_create(NETLINK_TYPE, yourHandler);
#endif
b)内核像应用层单播时:
#if LINUX_VERSION_CODE >=0x020616
nlhdr = nlmsg_put(skb,0,0,0,(NLMSG_SPACE(1024)-sizeof(struct nlmsghdr)),0);
#else
nlhdr = NLMSG_PUT(skb,0,0,0,(NLMSG_SPACE(1024)-sizeof(struct nlmsghdr)));
#endif
//当内核版本小于0x020616时,还需要做一个出错时的跳转标签
#if LINUX_VERSION_CODE < 0x020616
nlmsg_failure:
#endif
C)
yourHandler
的原型:
#if LINUX_VERSION_CODE >= 0x02061B
:
Handle
原型为:
void handler(struct sk_buff *__skb)
通过
skb = skb_get(__skb);
得到实际数据
#else
:
yourHandler
原型为:
void handler (struct sock *sk, int len)
通过
skb = skb_dequeue(&sk->sk_receive_queue)
得到实际数据。
#endif
3、NLMSG_DATA(nlhdr)内存空间是交给socket来处理的。
4、一个进程中多个线程使用netlink
。此时用进程id无法唯一的确定一个netlink通信。需要把表示号设为pthread_self() << 16 | getpid();
原文链接:http://blog.csdn.net/sealyao/archive/2009/10/02/4628141.aspx
1、选一个没有用到的
协议类型
,
注意要避开netlink.h中已经定义好的类型。注意保证内核层和用户层的协议类类型的一致。也就是说内核层创建netlink函数
netlink_kernel_create的第一个参数和用户层创建socket的socket函数的第三个参数要一致。否则是不能建立连接的。
2、版本问题。
如
果你在网上搜到一个帖子说netlink代码保证可用,你满心欢喜把代码贴到自己机器上,八成是不能用。因为netlink在linux2.6.XX的版
本中变化的太快了。在内核态,大致有这么几个地方会随着版本的变化而变化:
a)netlink_kernel_create函数的原型;b)nlmsg_put/NLMSG_PUT的原型。
贴一下我的代码,估计也不是很全面:
a) netlink_kernel_create函数的原型:
//init_net是一个内核变量
#if LINUX_VERSION_CODE >= 0x020618
fspwfd = netlink_kernel_create(&init_net
,NETLINK_TYPE, 0, yourHandler, NULL,THIS_MODULE);
#elif LINUX_VERSION_CODE >= 0x020616
fspwfd = netlink_kernel_create(NETLINK_TYPE, 0, yourHandler, NULL,THIS_MODULE);
#elif LINUX_VERSION_CODE >= 0x020610
fspwfd = netlink_kernel_create(NETLINK_TYPE, 0, yourHandler,THIS_MODULE);
#else
fspwfd = netlink_kernel_create(NETLINK_TYPE, yourHandler);
#endif
b)内核像应用层单播时:
#if LINUX_VERSION_CODE >=0x020616
nlhdr = nlmsg_put(skb,0,0,0,(NLMSG_SPACE(1024)-sizeof(struct nlmsghdr)),0);
#else
nlhdr = NLMSG_PUT(skb,0,0,0,(NLMSG_SPACE(1024)-sizeof(struct nlmsghdr)));
#endif
//当内核版本小于0x020616时,还需要做一个出错时的跳转标签
#if LINUX_VERSION_CODE < 0x020616
nlmsg_failure:
#endif
C)
yourHandler
的原型:
#if LINUX_VERSION_CODE >= 0x02061B
:
Handle
原型为:
void handler(struct sk_buff *__skb)
通过
skb = skb_get(__skb);
得到实际数据
#else
:
yourHandler
原型为:
void handler (struct sock *sk, int len)
通过
skb = skb_dequeue(&sk->sk_receive_queue)
得到实际数据。
#endif
3、NLMSG_DATA(nlhdr)内存空间是交给socket来处理的。
4、一个进程中多个线程使用netlink
。此时用进程id无法唯一的确定一个netlink通信。需要把表示号设为pthread_self() << 16 | getpid();
原文链接:http://blog.csdn.net/sealyao/archive/2009/10/02/4628141.aspx
相关文章推荐
- netlink编程注意事项
- 使用windows API进行编程时候的注意事项
- PHP编程注意事项
- Windows实时扩展RTX下编程的一些注意事项
- Android摄像头编程及注意事项
- Linux Socket编程注意事项
- C语言编程注意事项
- SQL编程之高级查询(子查询)以及注意事项
- GPGPU OpenCL/CUDA 高性能编程的10大注意事项
- 29点注意事项造就编程高手!
- [百度空间] [原]跨平台编程注意事项(三): window 到 android 的 移植
- 鼠标在编程中的一些注意事项
- 利用多个开源库进行编程中应注意的事项
- JNI编程注意事项
- 初学C#编程的注意事项
- WIN网络编程-IOCP服务程序设计注意事项
- SQL编程之子查询及注意事项
- C语言嵌入式系统编程注意事项
- IOCP编程注意事项
- windows7编程注意事项与兼容性