Advertisement
yorath

raw socket monitoring

Apr 14th, 2014
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.10 KB | None | 0 0
  1. //
  2. //  Id: lsniff_main.cpp
  3. //
  4. //  Author: Ciro
  5. //
  6. //  Demonstrates how to put a socket in promiscuos mode
  7. //
  8. //  Usage: lsniff [ICMP|TCP]
  9. //
  10. //  Refers to:
  11. //  http://www.ietf.org/rfc/rfc1700.txt?number=1700
  12. //
  13.  
  14. #pragma warning(disable : 4996)
  15.  
  16. #include <winsock2.h>
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21.  
  22. #pragma comment(lib, "ws2_32.lib")  // linker must use this lib for sockets
  23.  
  24. // *** Prototypes
  25. void translate_ip(DWORD _ip, char *_cip);
  26. void decode_tcp(char *_packet);
  27. void decode_icmp(char *_packet);
  28. void get_this_machine_ip(char *_retIP);
  29.  
  30. // *** Defines and Typedefs
  31.  
  32. #define LS_HI_PART(x) ((x >> 4) & 0x0F)
  33. #define LS_LO_PART(x) ((x) & 0x0F)
  34.  
  35. #define LS_MAX_PACKET_SIZE 65535
  36.  
  37. #ifndef SIO_RCVALL
  38. #define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1)
  39. #endif
  40.  
  41. typedef struct _IP_HEADER_ {
  42.   BYTE ver_ihl;          // Version (4 bits) and Internet Header Length (4 bits)
  43.   BYTE type;             // Type of Service (8 bits)
  44.   WORD length;           // Total size of packet (header + data)(16 bits)
  45.   WORD packet_id;        // (16 bits)
  46.   WORD flags_foff;       // Flags (3 bits) and Fragment Offset (13 bits)
  47.   BYTE time_to_live;     // (8 bits)
  48.   BYTE protocol;         // (8 bits)
  49.   WORD hdr_chksum;       // Header check sum (16 bits)
  50.   DWORD source_ip;       // Source Address (32 bits)
  51.   DWORD destination_ip;  // Destination Address (32 bits)
  52. } IPHEADER;
  53.  
  54. typedef struct _TCP_HEADER_ {
  55.   WORD source_port;       // (16 bits)
  56.   WORD destination_port;  // (16 bits)
  57.   DWORD seq_number;       // Sequence Number (32 bits)
  58.   DWORD ack_number;       // Acknowledgment Number (32 bits)
  59.   WORD info_ctrl;  // Data Offset (4 bits), Reserved (6 bits), Control bits (6
  60.                    // bits)
  61.   WORD window;     // (16 bits)
  62.   WORD checksum;   // (16 bits)
  63.   WORD urgent_pointer;  // (16 bits)
  64. } TCPHEADER;
  65.  
  66. typedef struct _ICMP_HEADER_ {
  67.   BYTE type;      // (8 bits)
  68.   BYTE code;      // (8 bits)
  69.   WORD checksum;  // (16 bits)
  70. } ICMPHEADER;
  71.  
  72. // *********************************************************************
  73. //                               main
  74. // *********************************************************************
  75. int main(int _argc, char *_argv[]) {
  76.   struct sockaddr_in sock_sniff;
  77.   SOCKET sniff_socket = -1;
  78.   WSAData sa_data;
  79.   WORD ver;
  80.   IPHEADER *ip_header = NULL;
  81.   int optval = 1;
  82.   DWORD dwLen = 0;
  83.   char packet[LS_MAX_PACKET_SIZE];
  84.   int iRet = 0;
  85.   int ip_header_size = 0;
  86.   char ipSrc[20], ipDest[20], thisIP[20];
  87.   BOOL bShowTCP = TRUE, bShowICMP = TRUE;
  88.  
  89.   // Check arguments
  90.   if (_argc > 1) {
  91.     if (!_stricmp(_argv[1], "icmp"))
  92.       bShowTCP = FALSE;
  93.     else if (!_stricmp(_argv[1], "tcp"))
  94.       bShowICMP = FALSE;
  95.     else {
  96.       printf("\nUsage lsniff [ICMP|TCP]\n");
  97.       exit(0);
  98.     }
  99.   }
  100.  
  101.   // Init Windows sockets version 2.2
  102.   ver = MAKEWORD(2, 2);
  103.   WSAStartup(ver, &sa_data);
  104.  
  105.   // Get a socket in RAW mode
  106.   sniff_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
  107.   if (sniff_socket == SOCKET_ERROR) {
  108.     printf("Error: socket = %ld\n", WSAGetLastError());
  109.     exit(-1);
  110.   }
  111.  
  112.   // Bind it
  113.   memset(thisIP, 0x00, sizeof(thisIP));
  114.   get_this_machine_ip(thisIP);
  115.  
  116.   sock_sniff.sin_family = AF_INET;
  117.   sock_sniff.sin_port = htons(0);
  118.   // If your machine has more than one IP you might put another one instead
  119.   // thisIP value
  120.   sock_sniff.sin_addr.s_addr = inet_addr(thisIP);
  121.  
  122.   if (bind(sniff_socket, (struct sockaddr *)&sock_sniff, sizeof(sock_sniff)) ==
  123.       SOCKET_ERROR) {
  124.     printf("Error: bind = %ld\n", WSAGetLastError());
  125.     exit(-2);
  126.   }
  127.  
  128.   // Set socket to promiscuous mode
  129.   // setsockopt wont work ... dont even try it
  130.   if (WSAIoctl(sniff_socket, SIO_RCVALL, &optval, sizeof(optval), NULL, 0,
  131.                &dwLen, NULL, NULL) == SOCKET_ERROR) {
  132.     printf("Error: WSAIoctl  = %ld\n", WSAGetLastError());
  133.     exit(-3);
  134.   }
  135.  
  136.   while (TRUE) {
  137.     (void)memset(packet, 0x00, sizeof(packet));
  138.  
  139.     iRet = recv(sniff_socket, packet, LS_MAX_PACKET_SIZE, 0);
  140.     if (iRet < sizeof(IPHEADER)) continue;
  141.  
  142.     ip_header = (IPHEADER *)packet;
  143.  
  144.     // I only want IPv4 not IPv6
  145.     if (LS_HI_PART(ip_header->ver_ihl) != 4) continue;
  146.  
  147.     ip_header_size = LS_LO_PART(ip_header->ver_ihl);
  148.     ip_header_size *= sizeof(DWORD);  // size in 32 bits words
  149.  
  150.     // Checks the protocol IP is encapsulating
  151.     memset(ipSrc, 0x00, sizeof(ipSrc));
  152.     memset(ipDest, 0x00, sizeof(ipDest));
  153.     translate_ip(ip_header->source_ip, ipSrc);
  154.     translate_ip(ip_header->destination_ip, ipDest);
  155.  
  156.     // Read http://www.ietf.org/rfc/rfc1700.txt?number=1700
  157.     switch (ip_header->protocol) {
  158.       case 1:  // ICMP
  159.         if (bShowICMP) {
  160.           printf("\n -------------------- // -------------------- ");
  161.           printf("\n IP Header:");
  162.           printf("\n   Source      IP: %s", ipSrc);
  163.           printf("\n   Destination IP: %s", ipDest);
  164.           printf("\n      ICMP Header:");
  165.  
  166.           decode_icmp(&packet[ip_header_size]);
  167.         }
  168.         break;
  169.  
  170.       case 6:  // TCP
  171.         if (bShowTCP) {
  172.           printf("\n -------------------- // -------------------- ");
  173.           printf("\n IP Header:");
  174.           printf("\n   Source      IP: %s", ipSrc);
  175.           printf("\n   Destination IP: %s", ipDest);
  176.           printf("\n      TCP Header:");
  177.  
  178.           decode_tcp(&packet[ip_header_size]);
  179.         }
  180.         break;
  181.  
  182.       case 17:  // UPD
  183.         break;
  184.  
  185.       default:
  186.         break;
  187.     }
  188.  
  189.   }  // end-while
  190.  
  191.   return 0;
  192. }
  193.  
  194. void get_this_machine_ip(char *_retIP) {
  195.   char host_name[128];
  196.   struct hostent *hs;
  197.   struct in_addr in;
  198.  
  199.   memset(host_name, 0x00, sizeof(host_name));
  200.   gethostname(host_name, 128);
  201.   hs = gethostbyname(host_name);
  202.  
  203.   memcpy(&in, hs->h_addr, hs->h_length);
  204.   strcpy(_retIP, inet_ntoa(in));
  205. }
  206.  
  207. void translate_ip(DWORD _ip, char *_cip) {
  208.   struct in_addr in;
  209.  
  210.   in.S_un.S_addr = _ip;
  211.   strcpy(_cip, inet_ntoa(in));
  212. }
  213.  
  214. void decode_tcp(char *_packet) {
  215.   TCPHEADER *tcp_header = (TCPHEADER *)_packet;
  216.   BYTE flags = (ntohs(tcp_header->info_ctrl) & 0x003F);
  217.  
  218.   printf("\n         source port      : %ld", htons(tcp_header->source_port));
  219.   printf("\n         destination port : %ld",
  220.          htons(tcp_header->destination_port));
  221.   printf("\n         control bits     : ");
  222.  
  223.   if (flags & 0x01)  // FIN
  224.     printf("FIN ");
  225.  
  226.   if (flags & 0x02)  // SYN
  227.     printf("SYN ");
  228.  
  229.   if (flags & 0x04)  // RST
  230.     printf("RST ");
  231.  
  232.   if (flags & 0x08)  // PSH
  233.     printf("PSH ");
  234.  
  235.   if (flags & 0x10)  // ACK
  236.     printf("ACK ");
  237.  
  238.   if (flags & 0x20)  // URG
  239.     printf("URG ");
  240.  
  241.   printf("\n         sequence number  : %lu", ntohl(tcp_header->seq_number));
  242. }
  243.  
  244. void decode_icmp(char *_packet) {
  245.   ICMPHEADER *icmp_header = (ICMPHEADER *)_packet;
  246.  
  247.   printf("\n         type: %d", icmp_header->type);
  248.  
  249.   switch (icmp_header->type) {
  250.     case 0:
  251.       printf(" (echo reply)");
  252.       break;
  253.  
  254.     case 8:
  255.       printf(" (echo request)");
  256.       break;
  257.  
  258.     default:
  259.       break;
  260.   }
  261.  
  262.   printf("\n         code: %d", icmp_header->code);
  263.   printf("\n         code: %ld", icmp_header->checksum);
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement