核心使用dev_add_pack一例(scu.edu difeijing)

來源:互聯網
上載者:User

下面的東西,假定你比較瞭解Linux核心的網路部分和LKM的一些 
 機制. 
   前面那篇kernel sniffer其實就是對函數dev_add_pack()的使用,這裡 
 再給一個核心中使用dev_add_pack()的例子,說出來大家應該都知道, 
 就是SOCK_PACKET類型的socket. 
 SOCK_PACKET的套介面能抓住各種類型的包,那它是怎麼實現的呢? 
 它在建立的時候用SOCK_PACKET這個參數告訴Linux,然後Linux會 
 有一些特別的操作,好了,start here. 
   
   
   從建立時開始,那就是sys_socketcall了,所有的跟socket有關的 
 操作都是用系統調用sys_socketcall. 
 OK,sys_socketcall()在socket.c中, 
 asmlinkage int sys_socketcall(int call, unsigned long *args) 
 在判斷操作的switch中看到下面這句話, 
 case SYS_SOCKET: 
                 err = sys_socket(a0,a1,a[2]); 
                 break; 
 那就去看看sys_socket()吧,它也在socket.c裡。 
 asmlinkage int sys_socket(int family, int type, int protocol) 
 下面這句,retval = sock_create(family, type, protocol, &sock), 
 原來它也是用別的函數呀,繼續。sock_create()也在socket.c裡面, 
 int sock_create(int family, int type, int protocol, struct socket 
 **res) 
 看下面的語句, 
 if ((i = net_families[family]->create(sock, protocol)) < 0) 
 { 
         sock_release(sock); 
         return i; 
 } 
 net_families是個全域變數,其定義為 
 /* 
  *      The protocol list. Each protocol is registered in here. 
  */ 
   
 struct net_proto_family *net_families[NPROTO]; 
 你注意到上面的注釋了嗎?原來大家集中到一起了。每個協議族都會到 
 這個數組裡註冊資訊,包括起建立常式,。。,下面是對結構 
 struct net_proto_family的定義: 
 struct net_proto_family 
 { 
         int     family; 
         int     (*create)(struct socket *sock, int protocol); 
         /* These are counters for the number of different methods of 
            each we support */ 
         short   authentication; 
         short   encryption; 
         short   encrypt_net; 
 }; 
 family值定義在socket.h中,象PF_INET,PF_IPX,IP_PACKET,...... 
 好了,現在知道要找的目標了,就是PF_PACKET協議族在net_families 
 裡註冊的建立常式,我找,找,找...終於找到了對net_families操作的 
 地方了,也是在socket.c中,函數ock_register()中,很簡單的操作, 
 int sock_register(struct net_proto_family *ops) 
 { 
         if (ops->family >= NPROTO) { 
                 printk(KERN_CRIT "protocol %d >= NPROTO(%d)/n", ops->fami 
 ly, NPROTO); 
   
                 return -ENOBUFS; 
         } 
         net_families[ops->family]=ops; 
         return 0; 
 } 
 從這裡可以看得出來這是各協議族用來註冊的,好,查一下有什麼地方用了這個 
 喊數。果然不出所料,用這個函數的檔案是下面這些, 
 Af_ax25.c (f:/linux-2.2.12/net/ax25):   sock_register(&ax25_family_ops); 
 Af_inet.c (f:/linux-2.2.12/net/ipv4):   (void) 
 sock_register(&inet_family_ops); 
 Af_inet6.c (f:/linux-2.2.12/net/ipv6):  (void) 
 sock_register(&inet6_family_ops); 
 Af_ipx.c (f:/linux-2.2.12/net/ipx):     (void) 
 sock_register(&ipx_family_ops); 
 Af_irda.c (f:/linux-2.2.12/net/irda):   sock_register(&irda_family_ops); 
 Af_netlink.c (f:/linux-2.2.12/net/netlink): 
         sock_register(&netlink_family_ops); 
 Af_netrom.c (f:/linux-2.2.12/net/netrom): 
         sock_register(&nr_family_ops); 
 Af_packet.c (f:/linux-2.2.12/net/packet): 
         sock_register(&packet_family_ops); 
 Af_rose.c (f:/linux-2.2.12/net/rose):   sock_register(&rose_family_ops); 
 Af_unix.c (f:/linux-2.2.12/net/unix):   sock_register(&unix_family_ops); 
 Af_x25.c (f:/linux-2.2.12/net/x25):     sock_register(&x25_family_ops); 
 Ddp.c (f:/linux-2.2.12/net/appletalk):  (void) 
 sock_register(&atalk_family_ops); 
 Econet.c (f:/linux-2.2.12/net/econet): 
         sock_register(&econet_family_ops); 
 現在清楚了,各協議族都用sock_register()來註冊一下自己,我們關心的是 
 packet,所以 
 去看檔案af_packet.c. 
 int init_module(void) 
 { 
         sock_register(&packet_family_ops); 
         register_netdevice_notifier(&packet_netdev_notifier); 
         return 0; 
 } 
 繼續向下,看看packet_family_ops的內容,它也是在af_packet.c裡。 
 static struct net_proto_family packet_family_ops = 
 { 
         PF_PACKET, 
         packet_create 
 }; 
 前面有struct net_proto_family的定義,我們知道packet_family_ops 
 的family值為PF_PACKET,建立常式為packet_create,馬上就要切入正題了。 
 packete_create()也是定義在af_packet.c中,這個函數還有點長,這裡就沒必要 
 全部 
 貼出來了。它前面一大段,是一些細節,許可權檢查,模組計數增加,對struct 
 sock和 
 struct socket的一些域的填充,下面幾句才是我們關心的。 
 /* 
  *      Attach a protocol block 
 */ 
         struct sock *sk; 
         sk->protinfo.af_packet->prot_hook.func = packet_rcv; 
             sk->protinfo.af_packet->prot_hook.data = (void *)sk; 
         if (protocol) { 
                 sk->protinfo.af_packet->prot_hook.type = protocol; 
                 dev_add_pack(&sk->protinfo.af_packet->prot_hook); 
                 sk->protinfo.af_packet->running = 1; 
         } 
   
 看見用dev_add_pack那句了吧! 
 其實SOCK_PACKET的實現就是用dev_add_pack()來的,我們現在還可以 
 知道它用的處理包的函數是packet_rcv(),hehe. 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.