home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / ipspy140.zip / iptest.c < prev    next >
C/C++ Source or Header  |  1998-05-31  |  14KB  |  464 lines

  1. //*****************************************************************************
  2. //***  NAME              : iptest.c                                         ***
  3. //***  PART OF           : IpSpy                                            ***
  4. //***  SHORT DESCRIPTION : tests the ipspy dll                              ***
  5. //--------------------------------------------------------------------------***
  6. //***  AUTHOR            : E.Buerkle                                        ***
  7. //***  CREATION DATE     : 15.01.97                                         ***
  8. //***  COPYRIGHT         : (C) 1997 E.Buerkle                               ***
  9. //*****************************************************************************
  10.  
  11. #define INCL_BASE
  12. #include <os2.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <stdarg.h>
  16. #include <stddef.h>
  17.  
  18.  
  19. #define  OS2
  20. #ifdef __EMX__
  21. #include <sys\types.h>
  22. #else
  23. #include <types.h>
  24. #endif
  25. #include <sys/socket.h>
  26. #include <netdb.h>
  27. #include <sys/ioctl.h>
  28. #include <sys/select.h>
  29. #include <sys/ioctl.h>
  30.  
  31. #include <net\if.h>
  32. #include <net\route.h>
  33. #include <netinet\in.h>
  34. #include <netinet\in_systm.h>
  35. #include <netinet\ip.h>
  36. #include <netinet\ip_icmp.h>
  37. #include <netinet\if_ether.h>
  38. #include <netinet\tcp.h>
  39. #ifdef __EMX__
  40. #include <arpa\inet.h>
  41. #endif
  42.  
  43. #include <ipspy.h>
  44.  
  45. ULONG  ulHandle;
  46. UCHAR  auchInterface[IFNAMSIZ+1];
  47. USHORT usOldMode;
  48.  
  49. //**************************************************************************
  50. //  Name       :  viewICMP
  51. //  Description:  view icmp packets
  52. //  Parameters :  ip  - pointer to ip packet
  53. //  Return     :  none
  54. //**************************************************************************
  55. VOID viewICMP(struct ip *ip)
  56. {
  57.    char               *type, line[96];
  58.    struct icmp        *icmp;
  59.    ULONG              headerLen,dataLen,len;
  60.  
  61.    headerLen = ip->ip_hl << 2;
  62.    len = ntohs(ip->ip_len) - headerLen;
  63.    if(len < ICMP_MINLEN)
  64.    {
  65.      printf("packet too short [%d bytes]\n", len);
  66.      return;
  67.    }
  68.    dataLen =  len - sizeof(struct icmp);
  69.    type = "";
  70.  
  71.    icmp = (struct icmp *)((UCHAR *) ip + headerLen);
  72.  
  73.    if (icmp->icmp_type == ICMP_UNREACH)
  74.    {
  75.      switch(icmp->icmp_code)
  76.      {
  77.        case ICMP_UNREACH_NET:
  78.          type = "Network unreachable";
  79.          break;
  80.        case ICMP_UNREACH_HOST:
  81.          type = "Host unreachable";
  82.          break;
  83.        case ICMP_UNREACH_PROTOCOL:
  84.          type = "Invalid protocol";
  85.          break;
  86.        case ICMP_UNREACH_PORT:
  87.          type = "Invalid port";
  88.          break;
  89.        case ICMP_UNREACH_NEEDFRAG:
  90.          type = "Need fragmenting";
  91.          break;
  92.        case ICMP_UNREACH_SRCFAIL:
  93.          type = "Source route failure";
  94.          break;
  95.        default:
  96.          sprintf(line, "Unknown code #%i", icmp->icmp_code);
  97.          type = line;
  98.          break;
  99.      }
  100.      printf(" *** ICMP Type: unreach, Code: %s ***\n", type);
  101.    }
  102.    else
  103.    {
  104.      switch(icmp->icmp_type)
  105.      {
  106.        case ICMP_ECHOREPLY:
  107.          type =  "echo reply";
  108.          break;
  109.        case ICMP_UNREACH:
  110.          type =  "dest unreachable, codes:";
  111.          break;
  112.        case ICMP_SOURCEQUENCH :
  113.          type =  "packet lost, slow down";
  114.          break;
  115.        case ICMP_REDIRECT:
  116.          type =  "shorter route, codes: ";
  117.          break;
  118.        case ICMP_ECHO:
  119.          type =     "echo service";
  120.          break;
  121.        case ICMP_TIMXCEED:
  122.          type =     "time exceeded, code:";
  123.          break;
  124.        case ICMP_PARAMPROB:
  125.          type =    "ip header bad";
  126.          break;
  127.        case ICMP_TSTAMP:
  128.          type =   "timestamp request";
  129.          break;
  130.        case ICMP_TSTAMPREPLY:
  131.          type =   "timestamp reply";
  132.          break;
  133.        case ICMP_IREQ:
  134.          type =   "information request";
  135.          break;
  136.        case ICMP_IREQREPLY:
  137.          type =  "information reply";
  138.          break;
  139.        case ICMP_MASKREQ:
  140.          type = "address mask request";
  141.          break;
  142.        case ICMP_MASKREPLY:
  143.          type = "address mask reply";
  144.          break;
  145.        default:
  146.          sprintf(line, "Unknown type #%i", icmp->icmp_type);
  147.          type = line;
  148.          break;
  149.      }
  150.  
  151.      printf("*** ICMP Type: %s, Code:%d ***\n", type, icmp->icmp_code);
  152.    }
  153.  
  154. //   printf("Icmp length:%d(0x%x)\n", dataLen, dataLen);
  155. //   if(dataLen > 0)
  156. //     dump( (PVOID) (ip + 1), dataLen);
  157.  
  158. }
  159.  
  160.  
  161. //**************************************************************************
  162. //  Name       :  filterICMP
  163. //  Description:  search icmp packets
  164. //  Parameters :  ip  - pointer to ip packet
  165. //  Return     :  TRUE if found
  166. //**************************************************************************
  167. BOOL filterICMP(struct ip *ip)
  168. {
  169.      BOOL fICMP = FALSE;
  170.  
  171.      printf("Protocol: ");
  172.      switch(ip->ip_p)
  173.      {
  174.        case IPPROTO_IP:
  175.          printf("IP\n");
  176.          break;
  177.        case IPPROTO_ICMP:
  178.          printf("ICMP\n");
  179.          fICMP = TRUE;         // hello Mr. Ping
  180.          break;
  181.        case IPPROTO_GGP:
  182.          printf("GGP\n");
  183.          break;
  184.        case IPPROTO_TCP:
  185.          printf("TCP\n");
  186.          break;
  187.        case IPPROTO_EGP:
  188.          printf("EGP\n");
  189.          break;
  190.        case IPPROTO_PUP:
  191.          printf("PUP\n");
  192.          break;
  193.        case IPPROTO_UDP:
  194.          printf("UDP\n");
  195.          break;
  196.        case IPPROTO_IDP:
  197.          printf("IDP\n");
  198.          break;
  199.        case IPPROTO_RAW:
  200.          printf("RAW IP\n");
  201.          break;
  202.        default:
  203.          printf("UNKOWN: #%d\n", ip->ip_p);
  204.          break;
  205.      }
  206. /********************************
  207.      printf("IP Header length %d\t\t Version %d\t\t Service %d\n",
  208.             ip->ip_hl << 2, ip->ip_v, ip->ip_tos);
  209.      printf("IP total Length %d\t\t ID %d\t\t Offset %d \n",
  210.             ntohs(ip->ip_len), ntohs(ip->ip_id), ntohs(ip->ip_off));
  211.      printf("Time to live %d\t\t checksum:%d\n",
  212.             ip->ip_ttl, ntohs(ip->ip_sum));
  213.      printf("service: %s\n", getservbyport(ip->ip_tos, &ip->ip_p));
  214. ********************************/
  215.      printf("Packet-Destination %s\t\t",
  216.             inet_ntoa(ip->ip_dst));
  217.      printf("Packet-Source %s\n",
  218.             inet_ntoa(ip->ip_src));
  219.  
  220.      return fICMP;
  221. }
  222.  
  223. //**************************************************************************
  224. //  Name       :  filterIP
  225. //  Description:  search ip packets
  226. //  Parameters :  type - packet type
  227. //                data - raw data
  228. //                ip   - return pointer to ip packet
  229. //  Return     :  TRUE if found
  230. //**************************************************************************
  231. BOOL filterIP(USHORT usType, PVOID data, struct ip **ip)
  232. {
  233.    UCHAR   *ptr;
  234.    USHORT  EtherType;
  235.  
  236.    printf("Packet Type: ");
  237.    switch(usType)
  238.    {
  239.         case IP_PACKET_TYPE:
  240.           printf("IP\n");
  241.           *ip = data;
  242.           return TRUE;
  243.         case ETHERNET_PACKET_TYPE: // DIX
  244.           printf("ETHERNET\n");
  245.           ptr = (UCHAR *) data;
  246.           EtherType=ntohs(((struct ether_header *)ptr)->ether_type);
  247.           if(EtherType != ETHERTYPE_IP)
  248.             return FALSE;
  249.           *ip = (struct ip *)(ptr + sizeof(struct ether_header));
  250.           return TRUE;
  251.         case IEEE_802_3_PACKET_TYPE:
  252.           printf("802.3\n");
  253.           return FALSE;
  254.         case IEEE_802_5_PACKET_TYPE:
  255.           printf("802.5\n");
  256.           ptr = (UCHAR *) data;
  257.           while(!(*ptr == HEAD_802_END && *(ptr+1) == HEAD_802_END))
  258.             ptr++;
  259.           EtherType = ntohs(*((USHORT *) (ptr+6)));
  260.           if(EtherType != ETHERTYPE_IP)
  261.             return FALSE;
  262.           *ip = (struct ip *) (ptr + 8);
  263.           return TRUE;
  264.         case SLIP_PACKET_TYPE:
  265.           printf("SLIP\n");
  266.           if(*((UCHAR *) data) == 0xC0 || *((UCHAR *) data) == 0xDB)
  267.           {
  268.             *ip = (struct ip *) ((UCHAR *)(data) + 1);
  269.             return TRUE;
  270.           }
  271.           printf("unknown SLIP Packet\n");
  272.           return FALSE;
  273.         case SOFTWARE_LB_PACKET_TYPE:          // PPP !!!
  274.         case PPP_PACKET_TYPE:
  275.           printf("PPP\n");
  276.           ptr = (UCHAR *) data;
  277.           if(*ptr == 0x7e)
  278.             ptr++;
  279.           // exclude LCP's and NCP'S
  280.           if(*ptr == 0x21)
  281.             *ip = (struct ip *) (ptr + 1);
  282.           else if(*ptr == 0xff &&
  283.                   *(ptr + 1) == 0x03 &&
  284.                   *(ptr + 2) <= 0x3f &&
  285.                   *(ptr + 3) == 0x21)
  286.             *ip = (struct ip *) (ptr + 4);
  287.           else if(*ptr == 0xff &&
  288.                   *(ptr + 1) == 0x7d &&
  289.                   *(ptr + 2) == 0x23 &&
  290.                   *(ptr + 3) <= 0x3f &&
  291.                   *(ptr + 4) == 0x21)
  292.             *ip = (struct ip *) (ptr + 5);
  293.           else
  294.             return FALSE;
  295.           return TRUE;
  296.         default:
  297.           printf("UNKNOWN %d\n", usType);
  298.           return FALSE;
  299.    }
  300. }
  301.  
  302. //**************************************************************************
  303. //  Name       :  writePacket
  304. //  Description:  write packet to local interface
  305. //  Parameters :  data        - pointer to raw packet
  306. //                usLength    - size of packet
  307. //                usType      - packet type
  308. //                ulTimeStamp - timestamp
  309. //                usUnknown   - unknown
  310. //  Return     :  VOID nothing
  311. //**************************************************************************
  312. VOID writePacket(VOID *data, USHORT usLength, USHORT usType, ULONG ulTimeStamp, USHORT usUnknown)
  313. {
  314.   ULONG  ulHandle;
  315.   APIRET rc;
  316.  
  317.   if((rc=IpSpy_Init(&ulHandle, "lo")) != RC_IPSPY_NOERROR)
  318.     printf("IpSpyInit Error: %d\n", rc);
  319.  
  320.   // throw the packet to local interface
  321.   if((rc=IpSpy_WriteRaw(ulHandle, data, usLength, usType, ulTimeStamp, usUnknown)) != RC_IPSPY_NOERROR)
  322.     printf("IpSpyWrite Error: %d\n", rc);
  323.  
  324.   if((rc=IpSpy_Exit(ulHandle)) != RC_IPSPY_NOERROR)
  325.     printf("IpSpyExit Error: %d\n", rc);
  326.  
  327. }
  328.  
  329. //**************************************************************************
  330. //  Name       :  IpExitProc
  331. //  Description:  close interface and reset adapter to normal mode
  332. //  Parameters :  usTermCode - termination info
  333. //  Return     :  none
  334. //**************************************************************************
  335. VOID APIENTRY IpExitProc(ULONG usTermCode)
  336. {
  337.   APIRET rc;
  338.  
  339.   fflush(NULL);
  340.  
  341.   // end monitor
  342.   if((rc=IpSpy_Exit(ulHandle)) != RC_IPSPY_NOERROR)
  343.     printf("IpSpyExit Error: %d\n", rc);
  344.  
  345.   // ip stack relexation
  346.   if((rc=IpSpy_SetReceiveMode(usOldMode,
  347.                               auchInterface,
  348.                               NULL)) != RC_IPSPY_NOERROR)
  349.     printf("IpSpy_SetReceiveMode Error: %d\n", rc);
  350.  
  351.   printf("Spy ends\n");
  352. }
  353.  
  354. //**************************************************************************
  355. //  Name       :  main
  356. //  Description:  read 10 raw inet packets and filter icmp
  357. //                and then send the last packet to "lo"
  358. //  Parameters :  argc argv env
  359. //  Return     :  none
  360. //**************************************************************************
  361. VOID main(ULONG argc, UCHAR **argv, UCHAR **env)
  362. {
  363.   APIRET rc;
  364.   UCHAR  auchData[2000], *pVersion, **pIFs;
  365.   USHORT usLength, usType, i;
  366.   ULONG  ulTimeStamp;
  367.   USHORT usUnknown;
  368.   struct ip *ip;
  369.   UCHAR  *pSocketError;
  370.   ULONG  ulSocketError;
  371.  
  372.   // query all available interfaces
  373.   if((rc=IpSpy_QueryInterfaces(&pIFs)) != RC_IPSPY_NOERROR)
  374.   {
  375.     printf("IpSpyQueryIF Error: %d\n", rc);
  376.     return;
  377.   }
  378.  
  379.   // check arguments
  380.   if(argc != 2 || IFNAMSIZ < strlen(argv[1]))
  381.   {
  382.     printf("usage: iptest [interface]\n");
  383.     printf(" where interface is one of:\n");
  384.     // show all available interfaces
  385.     if(pIFs != NULL)
  386.       for(i=0; pIFs[i] != 0; i++)
  387.         printf(" %s\n", pIFs[i]);
  388.  
  389.     return;
  390.   }
  391.  
  392.   strcpy(auchInterface, argv[1]);
  393.   printf("Spy [%s], quit with Ctrl-C\n", auchInterface);
  394.  
  395.   // view the version
  396.   if((rc=IpSpy_Version(&pVersion)) != RC_IPSPY_NOERROR)
  397.     printf("IpSpyVersion Error: %d\n", rc);
  398.   else
  399.     printf("IpSpy Version: %s\n", pVersion);
  400.  
  401.   // save receive mode
  402.   if((rc=IpSpy_QueryReceiveMode(&usOldMode, NULL)) != RC_IPSPY_NOERROR)
  403.     printf("IpSpy_QueryReceiveMode Error: %d\n", rc);
  404.  
  405.   // we want all packets
  406.   if((rc=IpSpy_SetReceiveMode(DIRECTED_MODE | BROADCAST_MODE | PROMISCUOUS_MODE,
  407.                               auchInterface,
  408.                               NULL)) != RC_IPSPY_NOERROR)
  409.   {
  410.     if(rc == RC_IPSPY_MODE_NOT_SUPPORTED)
  411.       printf("Promiscuous mode not supported\n");
  412.     else if(rc == RC_IPSPY_CANNOT_OPEN_DRIVER)
  413.       printf("IpSpy_SetReceiveMode Error: Cannot open ipspy.os2\n");
  414.     else
  415.       printf("IpSpy_SetReceiveMode Error: %d\n", rc);
  416.   }
  417.  
  418.  
  419.   // init monitor
  420.   if((rc=IpSpy_Init(&ulHandle, auchInterface)) != RC_IPSPY_NOERROR)
  421.   {
  422.     if(rc == RC_IPSPY_SOCKET_ERROR)
  423.     {
  424.       IpSpy_GetLastSocketError(&ulSocketError, &pSocketError);
  425.       printf("IpSpyInit SocketError: [%d] %s\n", ulSocketError, pSocketError);
  426.     }
  427.     else
  428.       printf("IpSpyInit Error: %d\n", rc);
  429.   }
  430.  
  431.   // good housekeeping
  432.   DosExitList(EXLST_ADD, IpExitProc);
  433.  
  434.  
  435.  
  436.   //
  437.   // process 10 packets
  438.   //
  439.  
  440.   for(i=1;i<=10;i++)
  441.   {
  442.     usLength = sizeof(auchData);
  443.     if((rc=IpSpy_ReadRaw(ulHandle, auchData, &usLength, &usType, &ulTimeStamp, &usUnknown)) != RC_IPSPY_NOERROR)
  444.       printf("IpSpyRead Error: %d\n", rc);
  445.     else
  446.     {
  447.        printf("\nPacket No. %d\n", i);
  448.        if(filterIP(usType, auchData, &ip ) == TRUE)
  449.        {
  450.          if(filterICMP(ip) == TRUE)
  451.            viewICMP(ip);
  452.  
  453.          // route the last packet to the local interface
  454.          if(i == 10)
  455.          {
  456.            ip->ip_dst = inet_makeaddr(127, 1);
  457.            writePacket(auchData, usLength, usType, ulTimeStamp, usUnknown);
  458.          }
  459.        }
  460.     }
  461.   }
  462.  
  463. }
  464.