#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <errno.h> #include <string.h> #include <arpa/inet.h> //for htons #include <linux/if_ether.h> //for ETH_P_ARP ETH_P_IP ... #include <sys/ioctl.h> #include <linux/if.h> //for IFF_PROMISC #include <getopt.h> //for getopt_long #define _GUN_SOURCE //for getopt_long
#define OUTPUT_ETH_NONE 0x0000 #define OUTPUT_ETH_IP 0x0001 #define OUTPUT_ETH_ARP 0x0002 #define OUTPUT_ETH_RARP 0x0004 #define OUTPUT_IP_ICMP 0x0008 #define OUTPUT_IP_IGMP 0x0010 #define OUTPUT_IP_TCP 0x0020 #define OUTPUT_IP_UDP 0x0040 #define OUTPUT_ETH_ALL 0xFFFF
#define IP_P_NONE 0x00 #define IP_P_ICMP 0x01 #define IP_P_IGMP 0x02 #define IP_P_TCP 0x06 #define IP_P_UDP 0x11
#define BUF_LEN 1516
//#define NEW_PF_PACKET
#define OLD_SOCK_PACKET
void output_pkg(ssize_t n, unsigned char *buf, unsigned short int eth_type, unsigned char ip_type) { unsigned short int src_port; unsigned short int dst_port; char src_ip_addr[16] = {0}; char dst_ip_addr[16] = {0}; printf("%d\t%02x:%02x:%02x:%02x:%02x:%02x > %02x:%02x:%02x:%02x:%02x:%02x\t0x%04x\t", n, buf[6]&0xFF, buf[7]&0xFF, buf[8]&0xFF, buf[9]&0xFF, buf[10]&0xFF, buf[11]&0xFF, buf[0]&0xFF, buf[1]&0xFF, buf[2]&0xFF, buf[3]&0xFF, buf[4]&0xFF, buf[5]&0xFF, eth_type); if(eth_type == ETH_P_ARP) { printf("\n"); } else if(eth_type == ETH_P_RARP) { printf("\n"); } else if(eth_type == ETH_P_IP) { if(ip_type == IP_P_ICMP) { strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26]))))); strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30]))))); printf("0x%02x\t%s > %s\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr); } else if(ip_type == IP_P_IGMP) { strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26]))))); strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30]))))); printf("0x%02x\t%s > %s\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr); } else if(ip_type == IP_P_TCP) { strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26]))))); strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30]))))); src_port = ntohs(*((unsigned short int *)(buf+34))); dst_port = ntohs(*((unsigned short int *)(buf+36))); printf("0x%02x\t%s > %s\t%d>%d\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr, src_port, dst_port); } else if(ip_type == IP_P_UDP) { strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26]))))); strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30]))))); src_port = ntohs(*((unsigned short int *)(buf+34))); dst_port = ntohs(*((unsigned short int *)(buf+36))); printf("0x%02x\t%s > %s\t%d>%d\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr, src_port, dst_port); } else { printf("0x%02x\t", ip_type & 0xFF); } printf("\n"); } else { printf("\n"); } }
#ifdef NEW_PF_PACKET int set_promisc_mode(int fd, char *ifname) { struct ifreq req; struct packet_mreq mreq;
bzero(&req, sizeof(req)); bzero(&mreq, sizeof(mreq));
strcpy(req.ifr_name, ifname); if(ioctl(fd, SIOCGIFINDEX, &req) == -1) { return -1; }
mreq.mr_ifindex = req.ifr_ifindex; mreq.mr_type = PACKET_MR_PROMISC; if(setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { return -1; }
return 0; } #endif
#ifdef OLD_SOCK_PACKET int set_promisc_mode(int fd, char *ifname) { struct ifreq req;
strcpy(req.ifr_name, ifname); if(ioctl(fd, SIOCGIFFLAGS, &req) == -1) { return -1; } req.ifr_flags |= IFF_PROMISC; if(ioctl(fd, SIOCSIFFLAGS, &req) == -1) { return -1; } return 0; } #endif
/***************************************************** *options: * i:ip, a:arp, r:rarp, g: igmp, c:icmp, t:tcp, u:udp * * * **************************************************/
int main(int argc, char **argv) { int fd, opt, opt_promisc = 0; char *if_name = "eth0"; ssize_t n; unsigned short int pkg_to_output = OUTPUT_ETH_NONE; unsigned short int eth_pkg_type = 0x0000; unsigned short int src_port = 0; unsigned short int dst_port = 0; unsigned short int monitor_port = 0; unsigned char ip_pkg_type = 0x00; unsigned char buf[BUF_LEN] = {0};
int optidx; static struct option long_options[] = { {"ip", 0, 0, 'i'}, {"arp", 0, 0, 'a'}, {"rarp", 0, 0, 'r'}, {"icmp", 0, 0, 'c'}, {"igmp", 0, 0, 'g'}, {"tcp", 2, 0, 't'}, {"udp", 2, 0, 'u'}, {"version", 0, 0, 'v'}, {"promisc", 1, 0, 'p'}, {0, 0, 0, 0}, }; while((opt = getopt_long(argc, argv, "iargct::u::p:v", long_options, &optidx)) != -1) { switch(opt) { case 'i': { pkg_to_output |= OUTPUT_ETH_IP; break; } case 'a': { pkg_to_output |= OUTPUT_ETH_ARP; break; } case 'r': { pkg_to_output |= OUTPUT_ETH_RARP; break; } case 'g': { pkg_to_output |= OUTPUT_ETH_IP; pkg_to_output |= OUTPUT_IP_IGMP; break; } case 'c': { pkg_to_output |= OUTPUT_ETH_IP; pkg_to_output |= OUTPUT_IP_ICMP; break; } case 't': { pkg_to_output |= OUTPUT_ETH_IP; pkg_to_output |= OUTPUT_IP_TCP; if(optarg != NULL) { monitor_port = (unsigned short int)atoi(optarg); } break; } case 'u': { pkg_to_output |= OUTPUT_ETH_IP; pkg_to_output |= OUTPUT_IP_UDP; if(optarg != NULL) { monitor_port = (unsigned short int)atoi(optarg); }break; } case 'v': { printf("version 1.0\n"); exit(0); } case 'p': { opt_promisc = 1; if_name = optarg; break; } default: { printf("useage: rawsocket [-i] [-r] [-a] [-g] [-c] [-v] [-t [port]] [-u [port]] [-p ifname]\n"); return 0; } } }
if (pkg_to_output == OUTPUT_ETH_NONE) { pkg_to_output = OUTPUT_ETH_ALL; } /*************************************** *Argument 2: * SOCK_RAW: The packet includes the link layer header. * SOCK_DGRAM: The packet don`t includes the link layer header. *Argument 3: * ETH_P_IP(0x0800): ip * ETH_P_RARP(0x0806): arp * ETH_P_ARP(0x8035): rarp * *************************************/ if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { printf("create socket failed: %s\n", strerror(errno)); return 0; }
if(opt_promisc == 1) { if(set_promisc_mode(fd, if_name) == -1) { printf("set promisc mode failed!\n"); exit(0); } }
while(1) { if((n = read(fd, buf, BUF_LEN)) == -1) { if(errno == EINTR) { continue; } else { printf("read error: %s\n", strerror(errno)); exit(0); } }
eth_pkg_type = ntohs((*(unsigned short int *)(buf+12)))&0xFFFF; if((eth_pkg_type == ETH_P_ARP) && (pkg_to_output & OUTPUT_ETH_ARP)) //ARP:0x0806
{ output_pkg(n, buf, eth_pkg_type, IP_P_NONE); } else if((eth_pkg_type == ETH_P_RARP) && (pkg_to_output & OUTPUT_ETH_RARP)) //RARP:0x8035
{ output_pkg(n, buf, eth_pkg_type, IP_P_NONE); } else if((eth_pkg_type == ETH_P_IP) && (pkg_to_output & OUTPUT_ETH_IP)) //IP:0x0800
{ ip_pkg_type = buf[23]; if(((pkg_to_output & OUTPUT_IP_ICMP) && ip_pkg_type == IP_P_ICMP) || //ICMP:0x01
((pkg_to_output & OUTPUT_IP_IGMP) && ip_pkg_type == IP_P_IGMP)) //IGMP:0x02
{ output_pkg(n, buf, eth_pkg_type, ip_pkg_type); } else if((pkg_to_output & OUTPUT_IP_TCP) && ip_pkg_type == IP_P_TCP) //TCP:0x06
{ src_port = ntohs(*((unsigned short int *)(buf+34))); dst_port = ntohs(*((unsigned short int *)(buf+36))); if(monitor_port == dst_port || monitor_port == 0) { output_pkg(n, buf, eth_pkg_type, ip_pkg_type); } } else if((pkg_to_output & OUTPUT_IP_UDP) && ip_pkg_type == IP_P_UDP) //UDP:0x11
{ src_port = ntohs(*((unsigned short int *)(buf+34))); dst_port = ntohs(*((unsigned short int *)(buf+36))); if(monitor_port == dst_port || monitor_port == 0) { output_pkg(n, buf, eth_pkg_type, ip_pkg_type); } } else //unknown ip pakage
{ if((pkg_to_output == OUTPUT_ETH_ALL) || (pkg_to_output == OUTPUT_ETH_IP)) { output_pkg(n, buf, eth_pkg_type, ip_pkg_type); } } } else //unknown eth pakage
{ if(pkg_to_output == OUTPUT_ETH_ALL) { output_pkg(n, buf, eth_pkg_type, IP_P_NONE); } } } }
|