home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz KrOnIcKLeZ 3 / HaCKeRz_KrOnIcKLeZ.iso / ircscripts / warirc / tcpmon.c < prev    next >
C/C++ Source or Header  |  1996-04-23  |  10KB  |  450 lines

  1. /*
  2.  * TCP Monitor (tcpmon) V1.0
  3.  * 
  4.  * cc tcpmon.c -o tcpmon -lresolv
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10.  
  11. #include <sys/time.h>
  12. #include <sys/file.h>
  13. #include <sys/stropts.h>
  14. #include <sys/signal.h>
  15. #include <netdb.h>
  16. #include <sys/types.h>
  17. #include <sys/socket.h>
  18. #include <sys/ioctl.h>
  19.  
  20. #include <net/if.h>
  21. #include <net/nit_if.h>
  22. #include <net/nit_buf.h>
  23. #include <net/if_arp.h>
  24.  
  25. #include <netinet/in.h>
  26. #include <netinet/if_ether.h>
  27. #include <netinet/in_systm.h>
  28. #include <netinet/ip.h>
  29. #include <netinet/udp.h>
  30. #include <netinet/ip_var.h>
  31. #include <netinet/udp_var.h>
  32. #include <netinet/in_systm.h>
  33. #include <netinet/tcp.h>
  34. #include <netinet/ip_icmp.h>
  35.  
  36. #include <netdb.h>
  37. #include <arpa/nameser.h>
  38. #include <resolv.h>
  39.  
  40. #define NIT_DEV         "/dev/nit"
  41. #define CHUNKSIZE       4096
  42. #define STREAM_NULL     (0)
  43. #define STREAM_STOD     (1)
  44. #define STREAM_DTOS     (2)
  45. #define STREAM_MAX      (3)
  46. #define ISeq(s,d)       ((s) == (d))
  47. #define ISneq(s,d)      ((s) != (d))
  48.  
  49. char *malloc (), *translate_host (), *device, *ProgName;
  50. int debug, translate;
  51.  
  52. int if_fd = -1;
  53. int Packet[CHUNKSIZE + 32], TCPport[10];
  54.  
  55.  
  56. void 
  57. Pexit (err, msg)
  58.   int err;
  59.   char *msg;
  60. {
  61.   perror (msg);
  62.   exit (err);
  63. }
  64.  
  65. void 
  66. Zexit (err, msg)
  67.   int err;
  68.   char *msg;
  69. {
  70.   fprintf (stderr, msg);
  71.   exit (err);
  72. }
  73.  
  74. #define DEBUGstk(Msg,Num,Seq) \
  75.   if(debug) { \
  76.     printf(Msg,Num,Seq); fflush(stdout); \
  77. }
  78.  
  79. #define IP          ((struct ip *)Packet)
  80. #define IP_OFFSET   (0x1FFF)
  81. #define SZETH       (sizeof(struct ether_header))
  82. #define IPLEN       (ntohs(ip->ip_len))
  83. #define IPHLEN      (ip->ip_hl)
  84. #define ADneq(s,t)  ((s).s_addr != (t).s_addr)
  85.  
  86. /*
  87.  * important part of the prog, determines if a packet is one we want, and
  88.  * performs sycnhing of sequence numbers
  89.  */
  90. void 
  91. filter (cp, pktlen)
  92.   char *cp;
  93.   u_int pktlen;
  94. {
  95.   int match = 0, i;
  96.   char *src, *dst, sp[15], dp[15];
  97.   register int Stream = STREAM_NULL;
  98.   register struct ip *ip;
  99.   struct in_addr Sipaddr;
  100.   struct in_addr Dipaddr;
  101.   struct servent *sv;
  102.   register struct tcphdr *tcph;
  103.   register u_long CurSEQ;
  104.   register u_char *p;
  105.   register u_short EtherType = ntohs (((struct ether_header *) cp)->ether_type);
  106.  
  107.   if (EtherType < 0x600)
  108.   {
  109.     EtherType = *(u_short *) (cp + SZETH + 6);
  110.     cp += 8;
  111.     pktlen -= 8;
  112.  
  113.     if (ISneq (EtherType, ETHERTYPE_IP))
  114.       return;
  115.   }
  116.   /* ugh, gotta do an alignment :-( */
  117.   bcopy (cp + SZETH, (char *) Packet, (int) (pktlen - SZETH));
  118.  
  119.   ip = (struct ip *) Packet;
  120.   if (ISneq (ip->ip_p, IPPROTO_TCP))
  121.     return;
  122.  
  123.   tcph = (struct tcphdr *) (Packet + IPHLEN);
  124.   CurSEQ = (ntohl (tcph->th_seq));
  125.  
  126.   if (debug)
  127.   {
  128.     printf ("SRC:%s(%d) ", inet_ntoa (ip->ip_src), tcph->th_sport);
  129.     printf ("DST:%s(%d)\n", inet_ntoa (ip->ip_dst), tcph->th_dport);
  130.   }
  131.   if (ip->ip_src.s_addr <= 0 || ip->ip_dst.s_addr <= 0)
  132.     return;
  133.  
  134.   for (i = 0; i < 10; i++)
  135.   {
  136.     if (!TCPport[i])
  137.       continue;
  138.     if (ISeq (tcph->th_sport, TCPport[i]) ||
  139.     ISeq (tcph->th_dport, TCPport[i]))
  140.       match = 1;
  141.   }
  142.  
  143.   if (!match)
  144.     return;
  145.  
  146.   {
  147.     register int length = ((IPLEN - (IPHLEN * 4)) - (tcph->th_off * 4));
  148.  
  149.     if (debug)
  150.       printf ("Seq=%08X,pl=%04X,dl=%04X,l=%04X,iph=%04X,ipl=%04X,tf=%04X\n",
  151.           CurSEQ, pktlen,
  152.        (IPLEN - (IPHLEN * 4)), length, ip->ip_hl, ip->ip_len, tcph->th_off);
  153.  
  154.     p = (u_char *) Packet;
  155.     p += ((ip->ip_hl * 4) + (tcph->th_off * 4));
  156.  
  157.     if (ip->ip_src.s_addr <= 0 || ip->ip_dst.s_addr <= 0)
  158.       return;
  159.  
  160.     if (translate)
  161.     {
  162.       src = translate_host (inet_ntoa (ip->ip_src));
  163.       dst = translate_host (inet_ntoa (ip->ip_dst));
  164.     } else
  165.     {
  166.       src = strdup (inet_ntoa (ip->ip_src));
  167.       dst = strdup (inet_ntoa (ip->ip_dst));
  168.     }
  169.  
  170.     sprintf (sp, "%d", tcph->th_sport);
  171.     sprintf (dp, "%d", tcph->th_dport);
  172.  
  173.     sv = getservbyport (tcph->th_sport, "tcp");
  174.     if (sv)
  175.       strcpy (sp, sv->s_name);
  176.  
  177.     sv = getservbyport (tcph->th_dport, "tcp");
  178.     if (sv)
  179.       strcpy (dp, sv->s_name);
  180.  
  181.     printf ("%s/%s %s/%s ", src, sp, dst, dp);
  182.  
  183.     while (length-- > 0)
  184.     {
  185.       fputc (*p, stdout);
  186.       if (*p == '\n' || *p == '\r')
  187.       {
  188.     printf ("\n%s/%d %s/%d ", inet_ntoa (ip->ip_src), tcph->th_sport,
  189.         inet_ntoa (ip->ip_dst), tcph->th_dport);
  190.       }
  191.       p++;
  192.       fflush (stdout);
  193.     }
  194.     printf ("\n");
  195.   }
  196. }
  197.  
  198. /*
  199.  * signal handler
  200.  */
  201. void 
  202. flushit ()
  203. {
  204.   printf ("\n\n[Terminating]\n");
  205.   fflush (stdout);
  206.   exit (1);
  207. }
  208.  
  209. /*
  210.  * opens network interface, performs ioctls and reads from it, passing data
  211.  * to filter function
  212.  */
  213. void 
  214. do_it ()
  215. {
  216.   int cc;
  217.   char *buf;
  218.   u_short sp_ts_len;
  219.  
  220.   if (!(buf = malloc (CHUNKSIZE)))
  221.     Pexit (1, "Eth: malloc");
  222.  
  223.   /* this /dev/nit initialization code pinched from etherfind */
  224.   {
  225.     struct strioctl si;
  226.     struct ifreq ifr;
  227.     struct timeval timeout;
  228.     u_int chunksize = CHUNKSIZE;
  229.     u_long if_flags = NI_PROMISC;
  230.  
  231.     if ((if_fd = open (NIT_DEV, O_RDONLY)) < 0)
  232.       Pexit (1, "Eth: nit open");
  233.  
  234.     if (ioctl (if_fd, I_SRDOPT, (char *) RMSGD) < 0)
  235.       Pexit (1, "Eth: ioctl (I_SRDOPT)");
  236.  
  237.     si.ic_timout = INFTIM;
  238.  
  239.     if (ioctl (if_fd, I_PUSH, "nbuf") < 0)
  240.       Pexit (1, "Eth: ioctl (I_PUSH \"nbuf\")");
  241.  
  242.     timeout.tv_sec = 1;
  243.     timeout.tv_usec = 0;
  244.     si.ic_cmd = NIOCSTIME;
  245.     si.ic_len = sizeof (timeout);
  246.     si.ic_dp = (char *) &timeout;
  247.     if (ioctl (if_fd, I_STR, (char *) &si) < 0)
  248.       Pexit (1, "Eth: ioctl (I_STR: NIOCSTIME)");
  249.  
  250.     si.ic_cmd = NIOCSCHUNK;
  251.     si.ic_len = sizeof (chunksize);
  252.     si.ic_dp = (char *) &chunksize;
  253.     if (ioctl (if_fd, I_STR, (char *) &si) < 0)
  254.       Pexit (1, "Eth: ioctl (I_STR: NIOCSCHUNK)");
  255.  
  256.     strncpy (ifr.ifr_name, device, sizeof (ifr.ifr_name));
  257.     ifr.ifr_name[sizeof (ifr.ifr_name) - 1] = '\0';
  258.     si.ic_cmd = NIOCBIND;
  259.     si.ic_len = sizeof (ifr);
  260.     si.ic_dp = (char *) 𝔦
  261.     if (ioctl (if_fd, I_STR, (char *) &si) < 0)
  262.       Pexit (1, "Eth: ioctl (I_STR: NIOCBIND)");
  263.  
  264.     si.ic_cmd = NIOCSFLAGS;
  265.     si.ic_len = sizeof (if_flags);
  266.     si.ic_dp = (char *) &if_flags;
  267.     if (ioctl (if_fd, I_STR, (char *) &si) < 0)
  268.       Pexit (1, "Eth: ioctl (I_STR: NIOCSFLAGS)");
  269.  
  270.     if (ioctl (if_fd, I_FLUSH, (char *) FLUSHR) < 0)
  271.       Pexit (1, "Eth: ioctl (I_FLUSH)");
  272.   }
  273.  
  274.   while ((cc = read (if_fd, buf, CHUNKSIZE)) >= 0)
  275.   {
  276.     register char *bp = buf, *bufstop = (buf + cc);
  277.  
  278.     while (bp < bufstop)
  279.     {
  280.       register char *cp = bp;
  281.       register struct nit_bufhdr *hdrp;
  282.  
  283.       hdrp = (struct nit_bufhdr *) cp;
  284.       cp += sizeof (struct nit_bufhdr);
  285.       bp += hdrp->nhb_totlen;
  286.       filter (cp, (u_long) hdrp->nhb_msglen);
  287.     }
  288.   }
  289.   Pexit ((-1), "Eth: read");
  290. }
  291.  
  292. int 
  293. GetPorts (p, Tp)
  294.   char *p;
  295.   int Tp;
  296. {
  297.  
  298.   /* get portname, conver from symbolic if needed */
  299.   if ((TCPport[Tp] = atoi (p)) == 0)
  300.   {
  301.     struct servent *sv = getservbyname (p, "tcp");
  302.     if (sv)
  303.       TCPport[Tp] = sv->s_port;
  304.     else
  305.     {
  306.       printf ("Unknown port: %s\n", p);
  307.       exit (-1);
  308.     }
  309.   }
  310.   return (1);
  311. }
  312.  
  313. void 
  314. Usage ()
  315. {
  316.   fprintf (stderr,
  317.        "Usage: %s [-i device] [-d] port ... \n", ProgName);
  318.   fprintf (stderr, "  -d         Debug\n");
  319.   fprintf (stderr, "  -i device  Logical ethernet interface\n");
  320.   fprintf (stderr, "  -t         Translate IP to Hostname\n");
  321.   fprintf (stderr, "  Port       Port name or number\n\n");
  322.   fprintf (stderr, "  Example:   %s -i le0 login finger 21\n",
  323.        ProgName);
  324.   exit (1);
  325. }
  326.  
  327.  
  328. void 
  329. main (argc, argv)
  330.   int argc;
  331.   char **argv;
  332. {
  333.   int s, ac = 1, i = 0, x = 0;
  334.   char cbuf[BUFSIZ];
  335.   struct ifconf ifc;
  336.   struct servent *sv;
  337.  
  338.   ProgName = argv[0];
  339.  
  340.   if (argc == 1)
  341.     Usage ();
  342.  
  343.   /* parse args */
  344.   device = NULL;
  345.   while (argv[ac][0] == '-')
  346.   {
  347.     register char ch = argv[ac++][1];
  348.     switch (toupper (ch))
  349.     {
  350.     case 'I':
  351.       device = argv[ac++];
  352.       break;
  353.     case 'D':
  354.       debug = 1;
  355.       break;
  356.     case 'T':
  357.       translate = 1;
  358.       break;
  359.     default:
  360.       Usage ();
  361.       break;
  362.     }
  363.   }
  364.  
  365.   while (argv[ac])
  366.   {
  367.     GetPorts (argv[ac++], i);
  368.     i++;
  369.   }
  370.  
  371.   /* if not a specified device, determine it */
  372.   if (!device)
  373.   {
  374.     if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
  375.       Pexit (1, "Eth: socket");
  376.  
  377.     ifc.ifc_len = sizeof (cbuf);
  378.     ifc.ifc_buf = cbuf;
  379.     if (ioctl (s, SIOCGIFCONF, (char *) &ifc) < 0)
  380.       Pexit (1, "Eth: ioctl");
  381.  
  382.     close (s);
  383.     device = ifc.ifc_req->ifr_name;
  384.   }
  385.   printf ("=> IP/TCP monitor\n");
  386.   printf ("=> Configured device %s [%s], %ssynching stream ...\n",
  387.       device, NIT_DEV, (debug) ? "(debug) " : "");
  388.   printf ("=> Scanning ports: ");
  389.   for (i = 0; i < 10; i++)
  390.   {
  391.     if (!TCPport[i])
  392.       continue;
  393.     sv = getservbyport (TCPport[i], "tcp");
  394.     if (sv)
  395.       printf ("%s ", sv->s_name);
  396.     else
  397.       printf ("%d ", TCPport[i]);
  398.   }
  399.   printf ("\n");
  400.  
  401.   fflush (stdout);
  402.  
  403.   signal (SIGINT, flushit);
  404.   signal (SIGTERM, flushit);
  405.  
  406.   do_it ();
  407.   /* NOT_REACHED */
  408. }
  409.  
  410. char *
  411. translate_host (s)
  412.   char s[18];
  413. {
  414.   int size = 0;
  415.   static char hostname[64];
  416.   char *h;
  417.   struct sockaddr_in sin;
  418.   struct hostent *host;
  419.  
  420.   h = hostname;
  421.  
  422.   bzero ((char *) &sin, sizeof (sin));
  423.   sin.sin_addr.s_addr = inet_addr (s);
  424.   if (sin.sin_addr.s_addr != -1 && sin.sin_addr.s_addr != 0)
  425.   {
  426.     sin.sin_family = AF_INET;
  427.     host = gethostbyaddr ((char *) &sin.sin_addr, sizeof (sin),
  428.               sin.sin_family);
  429.     if (host)
  430.     {
  431.       strcpy (hostname, host->h_name);
  432.       size = sizeof (hostname) - strlen (hostname);
  433.       if (!index (hostname, '.'))
  434.       {
  435.     if (!(_res.options & RES_INIT))
  436.       res_init ();
  437.     if (_res.defdname[0])
  438.     {
  439.       if (_res.defdname[strlen (_res.defdname) - 1] == '.')
  440.         _res.defdname[strlen (_res.defdname) - 1] = 0;
  441.       strncat (hostname, ".", size);
  442.       strncat (hostname, _res.defdname, size - 2);
  443.     }
  444.       }
  445.       return (h);
  446.     }
  447.   }
  448.   return (s);
  449. }
  450.