Chinaunix首页 | 论坛 | 博客
  • 博客访问: 288138
  • 博文数量: 67
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 802
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:23
文章分类
文章存档

2011年(4)

2010年(18)

2009年(32)

2008年(13)

我的朋友

分类: LINUX

2008-11-25 16:58:47

本文主要是对《Linux内核和用户空间通信的方法(二)— 使用netlink》一文中谈到到imp2的源码,进行简单的流程分析及其执行结果的显示。
 
该源码是从http://www-128.ibm.com/developerworks/cn/linux/l-netlink/imp2.tar.gz下载的。本人在RH9(2.4.20.-8)上进行编译。读者可以自行下载,本文并不会贴出源码。
 
一、imp2源码
 
整个源码包含三个文件:imp2_k.c, imp2_u.c和imp2.h. 其中imp2_k.c为内核模块的源代码,imp2_u.c为应用程序,即测试代码,imp2.h为两个源文件都需要引用的头文件。其整体的功能是:注册一种新的netlink协议,并注册一个新的NF hook函数。当有ping包发往当前主机或者经过当前主机转发时,内核向用户发送ping包的源IP和目的IP。各个文件的简单分析见下文。
 
1. imp2.h
 
该文件主要是定义了一种新的Netlink协议类型NL_IMP2(31)。新的协议类型的选值不能和当前内核中已经定义的netlink协议类型重复。定义了基于该协议类型的消息类型,内核根据接收到消息的不同类型,进行不同的处理:IMP2_U_PID和IMP2_CLOSE分别为请求和关闭。IMP2_K_MSG代表内核空间发送的消息。
该头文件的源码如下:
 
 

2. imp2_k.c

 

该程序为内核模块程序。其完成的功能如下:

 

(1)创建一种新的Netlink协议NL_IMP2,并注册该协议的回调函数kernel_receive。但用户空间通过建立且协议类型为NL_IMP2socket套接字并调用sendtosendmsg函数发送数据时,传送到内核空间的数据由kernel_receive进行处理。该函数主要是记录用户进程的ID用于随后发送数据的时候指定目的。

 

(2)NetfilterhookNF_IP_PRE_ROUTING注册hook函数get_icmp,对经过该hookping包进行处理。get_icmp首先判断是否是ping包,如果不是,直接Accept。如果是,则记录该包的源IP和目的IP,然后调用send_to_user,将记录的信息发送给kernel_recieve函数中记录的用户进程ID。

该文件的源码如下:

 

3. imp2_u.c

 

该程序为用户空间的测试程序。该程序包括以下功能:

(1)生成NL_IMP2协议的socket.然后通过调用sendto发送IMP2_U_PID类型的请求信息给内核。然后等待接受内核发回的信息。记住:仅当有ping包经过内核的NF时,内核才会向用户进程发送信息。

(2)当用户进程通过Ctrl+C来结束该程序时,调用信号处理函数sig_int,向内核发送IMP2_CLOSE的消息,结束socket。

该文件的源码如下:

 

二、编译和测试

1. 整个源文件编译的Makefile如下:

 

 
all:
        gcc -O2 -DMODULE -D__KERNEL__ -W  -Wstrict-prototypes -Wmissing-prototypes -isystem /lib/modules/`uname -r`/build/include -c -o imp2_k.o  imp2_k.c
        gcc imp2_u.c -o imp2_u
install:
        insmod imp2_k.o
uninstall:
        rmmod imp2_k
clean:
        rm -f imp2_k.o  imp2_u
 
2. 加载内核模块,并执行测试程序。
#make install
#./imp2_u
当没有ping包时,终端一直处于等待输出状态。通过另一台主机(192.168.1.100)向当前主机(192.168.1.101)发送ping包,则终端已经有输出:
#./imp2_u

[root@localhost imp2]# ./imp2_u

src: 192.168.1.100, dest: 192.168.1.101

src: 192.168.1.100, dest: 192.168.1.101

src: 192.168.1.100, dest: 192.168.1.101

src: 192.168.1.100, dest: 192.168.1.101

 

 

 

阅读(2570) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

Godbach2009-03-20 16:05:25

恩,因为这个直接使用别人提供的例程,跑在2.4的内核中。2.6的内核相关API发生了一些变化。如果想在2.6上运行的话,需要自己调整一下代码。

luoxingao2009-03-20 09:01:00

不好意思,看到了

luoxingao2009-03-20 09:00:18

请问这个是在linux哪个内核版本测试的