📄 nspy.c
字号:
/* * \brief kernal-mode net spy in to monitor packets being transmitted * * Net spy work to supplement the function Tcpdump. * U can use Tcpdump to gain well parsed packet information and * view kernal log of Net Spy to check detail values of some packet fields. */#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#ifndef __OPTIMIZE__#define __OPTIMIZE__ /*use optimized ntohs*/#endif#include <asm/byteorder.h>#include <asm/uaccess.h>//#include <asm/checksum.h>/*misc checksums func*/#include <linux/byteorder/generic.h>#include <linux/config.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/in.h> /*IP_PROTO*/#include <linux/netdevice.h> /* struct device, and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/if_arp.h> /*struct arphdr */#include <linux/ip.h> /*struct iphdr */#include <linux/icmp.h> /*struct icmphdr*/#include <linux/tcp.h> /*struct tcphdr */#include <linux/udp.h> /*struct udphdr */#include <linux/skbuff.h>#include "nspy.h"//...................................................................///To surport 2.4 kernel,///we don't use format_addr(),in net-sysfs.cstatic void _format_addr( char str[], size_t strl, const char addr[], size_t addrl, const char * fmt ){ int offs = 0; unsigned i; for(i = 0; i < addrl; i ++) { offs += snprintf( &str[offs], strl-offs, fmt, (0xFF & addr[i]) ); }}//...................................................................int spy_eth(struct ethhdr *hdr){ char saddr[ETH_ALEN*4]; char daddr[ETH_ALEN*4]; _format_addr( saddr, sizeof(saddr), hdr->h_source, sizeof(hdr->h_source), "%x "); _format_addr( daddr, sizeof(daddr), hdr->h_dest, sizeof(hdr->h_dest), "%x "); printk("ethernet frame header,\n" "destine mac address: %s\n" "source mac address: %s\n" "upper layer protocal: 0x%x\n", daddr, saddr, ntohs(hdr->h_proto)); return ntohs(hdr->h_proto)&0xFFFF; // check if_ether.h}//...................................................................struct etharp { struct arphdr hdr; char ar_sha[ETH_ALEN];// sender hardware address char ar_sip[4]; // sender IP address char ar_tha[ETH_ALEN];// target hardware address char ar_tip[4]; // target IP address };static char *arops[] = { "", "ARPOP_REQUEST", "ARPOP_REPLY", "ARPOP_RREQUEST", "ARPOP_RREPLY", "", "", "", "ARPOP_InREQUEST", "ARPOP_InREPLY", "ARPOP_NAK" };void spy_arp(struct arphdr *hdr){ char sha[ETH_ALEN*4]; char tha[ETH_ALEN*4]; char sip[20]; char tip[20]; if( (ARPHRD_ETHER != hdr->ar_hrd) && (ETH_P_IP != ntohs(hdr->ar_pro)) && (ETH_ALEN != hdr->ar_hln) && (4 != hdr->ar_pln) ) { printk("unknown ARP packet,not IP over ethernet.\n" "hardware id: 0x%x\n" "protocol id: 0x%x\n", ntohs(hdr->ar_hrd), ntohs(hdr->ar_pro) ); return; } unsigned short ar_op = ntohs(hdr->ar_op); if( ar_op >= sizeof(arops)/sizeof(char *) ) { printk("ar_op = 0x%x\n",hdr->ar_op); printk("invlid op code!\n"); return; // this won't ever happen } struct etharp *pkt = (struct etharp *)hdr; _format_addr( sha, sizeof(sha), pkt->ar_sha, sizeof(pkt->ar_sha), "%x "); _format_addr( sip, sizeof(sip), pkt->ar_sip, sizeof(pkt->ar_sip), "%d "); _format_addr( tha, sizeof(tha), pkt->ar_tha, sizeof(pkt->ar_tha), "%x "); _format_addr( tip, sizeof(tip), pkt->ar_tip, sizeof(pkt->ar_tip), "%d "); printk("ARP packet, \n" "operation: %s\n" "sender's hardware address: %s\n" "sender's ip address: %s\n" "target's hardware address: %s\n" "target's ip address: %s\n", arops[ar_op], sha, sip, tha, tip );}//...................................................................int spy_ip(struct iphdr *hdr){ char saddr[40]; char daddr[40]; _format_addr( saddr, sizeof(saddr), (const char *)&hdr->saddr, sizeof(hdr->saddr), "%d "); _format_addr( daddr, sizeof(daddr), (const char *)&hdr->daddr, sizeof(hdr->daddr), "%d ");#define DF(frag_off) ((frag_off >> 14) & 0x01)#define MF(frag_off) ((frag_off >>13) & 0x01)#define OFFS(frag_off) (frag_off & ((1 << 13)-1)) uint16_t frag_off = ntohs(hdr->frag_off); printk("ip packet header,\n" "ip version: %d\n" "ip header length: %d\n" "type of service: 0x%x\n" "total ip packet length: %d\n" "ip packet id: %d\n" "DF bit: %d\n" "MF bit: %d\n" "fragment offset: %d\n" "ip packet TTL : %d\n" "upper layer protocol: 0x%x\n" "header checksum: 0x%x\n" "source ip address: %s\n" "destine ip address: %s\n", hdr->version, hdr->ihl << 2, hdr->tos, //no further parse due to its limited use hdr->tot_len, hdr->id, DF(frag_off), MF(frag_off), OFFS(frag_off), hdr->ttl, hdr->protocol, hdr->check, saddr, daddr ); return hdr->protocol & 0xFF; // check in.h}//...................................................................int spy_icmp(struct icmphdr *hdr){ return 0; }//...................................................................//void spy_psdudp(struct)//{//}//...................................................................int spy_udp(struct udphdr *hdr){ return 0;}//...................................................................int spy_tcp(struct tcphdr *hdr){ return 0;}//...................................................................void spy_all(struct sk_buff *skb){ unsigned char *data = skb->data; int proto; struct sk_buff *spyb = skb_clone(skb, GFP_KERNEL); // ethernet layer(L2) proto = spy_eth((struct ethhdr *)data); data = skb_pull(spyb, sizeof(struct ethhdr)); switch(proto) { case ETH_P_IP: proto = spy_ip((struct iphdr *)data); data = skb_pull(spyb, ((struct iphdr *)data)->ihl << 2); break; case ETH_P_ARP: proto = -1; spy_arp((struct arphdr *)data); break; default: printk("unknown frame\n"); proto = -1; break; } if( -1 == proto ) { return ; } // ip layer(L3) switch(proto) { case IPPROTO_ICMP: break; case IPPROTO_IGMP: break; case IPPROTO_TCP: break; case IPPROTO_UDP: break; default: break; } kfree_skb(spyb);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -