|
|
最基本的,在linux i386上
//netdump.c #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ;
void die(char *why, int n) { perror(why); exit(n); }
int do_promisc(char *nif, int sock ) { struct ifreq ifr; strncpy(ifr.ifr_name, nif,strlen(nif)+1); if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { die("ioctl", 2); } ifr.ifr_flags |= IFF_PROMISC; if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) { die("ioctl", 3); } }
char buf[2*32767];
main() { struct sockaddr_in addr; struct iphdr *ip; struct tcphdr *tcp; int sock, r, len; char *data; char ss[32], dd[32];
if((sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1) die("socket", 1); do_promisc("eth0", sock); for(;;) { len = sizeof(addr); r = recvfrom(sock,(char *)buf,sizeof(buf),0,(struct sockaddr *)&addr,&len); buf[r] = 0; ip = (struct iphdr *)buf; tcp = (struct tcphdr *)(buf + sizeof(struct iphdr));
printf("PktSize: %d IPLEN %d PROT %d %s:%d-->;%s:%d %d \n", r, ip->;tot_len, ip->;protocol, strcpy(ss, inet_ntoa(*(struct in_addr*)&(ip->;saddr))), ntohs(tcp->;source), strcpy(dd, inet_ntoa(*(struct in_addr*)&(ip->;daddr))), ntohs(tcp->;dest), tcp->;doff ); data = (char*)tcp + 4*tcp->;doff; printf("data = %s\n", data); }
}
改进后的:
#include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; #include ;
void die(char *why, int n) { perror(why); exit(n); }
int do_promisc(char *nif, int sock ) { struct ifreq ifr; strncpy(ifr.ifr_name, nif,strlen(nif)+1); if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { die("ioctl", 2); } ifr.ifr_flags |= IFF_PROMISC; if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) { die("ioctl", 3); }
}
char buf[2*32767];
main() { struct sockaddr_in addr; struct ethhdr *peth; struct iphdr *pip; struct tcphdr *ptcp; struct udphdr *pudp; /*add more protocol head here....*/ int sock, r, len; char *data; char *ptemp; char ss[32], dd[32]; int i;
if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) die("socket", 1);
do_promisc("eth0", sock); for(;;) { len = sizeof(addr); r = recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len); buf[r] = 0; ptemp = buf; /*which can get source mac address and destnation address, and which network packet, here is OSI-2, link layer*/ peth = (struct ethhdr *)ptemp; ptemp += sizeof(struct ethhdr); /*which get IP layer informations, includes which transport protocol, source and destnation IP address...*/ pip = (struct iphdr *)ptemp;
/* * which can get transport layer informations, such as: transport socket port, transport layer includes * TCP, UDP, ICMP, IGMP......, can get which transport protocol from IP header */ ptemp += sizeof(struct iphdr); switch(pip->;protocol) { case IPPROTO_TCP: ptcp = (struct tcphdr *)ptemp; printf("TCP pkt:\n"); /* * and your service code.... */ break;
case IPPROTO_UDP: pudp = (struct udphdr *)ptemp; printf("UDP pkt:\n len:%d payload len:%d from %s:%d to %s:%d\n", r, ntohs(pudp->;len), strcpy(ss, inet_ntoa(*(struct in_addr*)&(pip->;saddr))), ntohs(pudp->;source), strcpy(dd, inet_ntoa(*(struct in_addr*)&(pip->;daddr))), ntohs(pudp->;dest) ); /* * and your service code.... */ break;
case IPPROTO_ICMP: printf("ICMP pkt:\n"); break; case IPPROTO_IGMP: printf("IGMP pkt:\n"); break;
/* . . . . . */ default: printf("Unkown pkt, protocl:%d\n", pip->;protocol); break; } } } | | | |