Friday, 20 May 2011

Mengintip Strobe,Code Protokol yang diciptakan Julian Assange.

Apa yang anda fikirkan ketika mendengar kata strobe, mungkin akan lebih familiar dan menggairahkan strobe adalah strowbery, warnanya merah yang mempesona dan rasanya yang khas kuat asamnya setengah lidah gak berasa dan mati rasa ketika mencicipi buah ini, strobe bisa dikatakan jus mengkudu, rasanya pahit dan bau busuk. Entah kenapa Julian Assange penemu wikileaks menamakan protokol yang dia ciptakan dinamai strobe, apa karena strobery warnanya merah  mempesona sehingga Julian menamainya strobe atau malah ini adalah berupa imajinasinya, mungkin saja strobery banyak di kebun belakang rumahnya sehingga tidak susah cari kata, assange juga merilis dalam code yang dibuatnya yang sudah lama dan jadul banget itu dalam repositorynya, ayo ikut saya…

97-06-16 : 1.04 : bug fixes (all sockets are always active).
                  timeval_subtract() rewritten, minor optimisations
                  fixed bug with always scanning port 1 when "-S file -f" .
    spelling police
95-11-24 : 1.03 : bug fixes mainly relating to timeouts. new single port flag,
                  bind port flag, bind address flag, read hostnames from stdin
95-03-09 : 1.02 : compat fix. remalloc(NULL, length) broke under versions of sunos,
                  causing Srealloc() to hang. <select.h> included for IRIX FD_*
95-03-07 : 1.01 : bug fix. 'b' missing from getopt()
95-03-07 : 1.00 : many trivial changes, some bug fixes.
95-02-28 : 0.93 : char c; -> int c; in main() as char c caused problems with
                  getopt() on systems such as IRIX which had unsigned char by default.
95-02-27 : 0.92 : Initial public release.

Dari release code yang sang jagoan tulis, dari diterbitkan sampai menghasilkan strobe bisa bekerja lamanya 2 tahun, wow 2 tahun bukan waktu yang sebentar boo, doski mampu menciptakan protokol sendiri dengan menulis code program untuk mencari bocoran kawat media di seluruh penjuru dunia yang menghebohkan dunia alam galaxy ini. assange juga mampu menciptakan replikasi server di dalam gunung yang diselimuti salju dingin yang tak seorangpun sangka kalau itu adalah, markas lalulintas data seluruh per-dunia-an  informasi manusia. entah kenapa assange menemukan wikileaks, mungkin doski bisa disebut professor penemu wikileaks yang sangat pro kontra di pemerintahan di alam jagad per-dunia-an manusia ini,beda hal dengan Mark Zuckerberg penemu facebook, kenapa facebook banyak sekali penduduknya bahkan tercatat hampir 600 Juta warga facebook saat ini, dan itupun terus menerus meningkat tiap detiknya, sementara assange dengan wikileaks malah diserang dari berbagai penjuru planet bumi agar servernya padam alias tidak ada, apa sebetulnya yang menarik dari wikileaks, secara saya orang awam tidak mengerti berita politik dan mungkin ini adalah berita seseorang dimana, kenapa dia begitu, video umat manusia yang tak henti-hentinya berperang, menciptakan senjata untuk berperang, atau seseorang ingin naik pangkat terus melakukan tindakan-tindakan tidak terpuji,yang akhirnya wikileaks datang untuk menceritakan informasi seseorang itu secara objektif sampai banyak yang kebakaran jenggotnya. Rasanya tidak baik bicara kesana-kemari yang tidak penting, secara saya orang awam akan menulis kembali code strobe yang diciptakan Jullian assange, dan tentunya code ini adalah code yang sudah lama sekali alias jadul, dan sekarang jaman sudah berganti kulit dan duniapun sudah berubah, apa mungkin code ini masih dipakai, sepertinya tidak penting, penulis hanya tertarik mengupas saja, tanpa ada muatan untuk mengajari pengunjung untuk berlaku tidak baik apalagi merugikan orang lain dengan code ini. baik kita mulai mengintip codenya, perhatikan dengan seksama :
Seperti biasa untuk mengawali umumnya dibuat definisi fungsi :

#define VERSION "1.05"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#ifdef _AIX
#  include <sys/select.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <strings.h>
#include <errno.h>

Nampak jelas kalau definisi fungsi yang ditulis Assange adalah protokol untuk membuka gerbang, selanjutnya didefinisikan juga codenya bisa hidup dan berjalan leluasa dimana saja, adalah :

#if defined(solaris) || defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__GCC__) || defined(__GNUC__)
#  define fvoid void
#else
#  define fvoid
extern int optind;
extern char *optarg;
#endif
#define bool int
#define FALSE 0
#define TRUE  1

Kemudian menentukan alamat yang jelas,

#ifndef INADDR_NONE
#  define INADDR_NONE ((unsigned long)-1)
#endif

Menentukan pintu mana saja yang bisa masuki dengan bekal kunci yang ada,

#define port_t (unsigned short)

/*
 * the below should be set via the Makefile, but if not...
 */

Assange juga mencarikan siapa aja pelayan yang bisa membuka pintu itu, dan tentunya dibantu oleh buah strobery untuk pelicin tenggorokan dan pemanis bibir.

#ifndef ETC_SERVICES
#  define ETC_SERVICES "/etc/services"
#endif
#ifndef STROBE_SERVICES
#  define STROBE_SERVICES "strobe.services"
#endif
#ifndef LIB_STROBE_SERVICES
#  define LIB_STROBE_SERVICES "/usr/local/lib/strobe.services"
#endif

Kapan buah strobery itu bisa memberikan kemanisan buat pelayan dan penghuni di dalam rumah, yang pintunya ditunggu oleh pelayan cakep yang suka buah strobery itu.

int a_timeout = 20;
int a_data_timeout = 30;
char *a_output = NULL;
char *a_services = "strobe.services";
char *a_input = NULL;
/* char *a_prescan = NULL; */
int a_start = 1;
int a_end = 65535;
int a_sock_max = 64;
int a_abort = 0;
int a_bindport = 0;
int a_capture = 1024;
int a_wrap = 79;
int a_lines = 1;
char *a_bindaddr = NULL;
char *a_dircap = NULL;
char *a_views = "all,hosts,networks,ports";
struct in_addr bindaddr;
bool f_linear = 0;
bool f_verbose = 0;
bool f_verbose_stats = 0;
bool f_fast = 0;
bool f_stats = 0;
bool f_quiet = 0;
bool f_delete_dupes = 0;
bool f_minimise = 0;
bool f_dontgetpeername = 0;
bool f_hexdump = 0;

int connects = 0;
int hosts_done = 0;
int attempts_done = 0;
int attempts_outstanding = 0;
struct timeval time_start;

fd_set set_sel_check_r;
fd_set set_sel_check_w;
fd_set set_sel_r;
fd_set set_sel_w;

int host_n;
int Argc;
char **Argv;

Buah strobery dikemas dalam berbagai menu, disini disajikan berupa buah segar siap saji.

FILE *fh_input;

char *capture_buf;

#define HO_ACTIVE 1
#define HO_ABORT 2
#define HO_COMPLETING 4

Menu buah strobery juga ditata dan dikemas dengan berbagai rasa, agar buah segar ini, tahu buat host/pemiliki rumah mana aja yang cocok, yang punya darah tinggi dan kolesterol tentu kadarnya beda-beda, diyakini strobery disukai anak kecil

struct hosts_s
{
    char *name;
    struct in_addr in_addr;
    int port;
    int *portlist;
    int portlist_n,portlist_alloc;
    int portlist_ent;
    struct timeval time_used;
    struct timeval time_start;
    int attempts;
    int attempts_done;
    int attempts_highest_done;
    int connects;
    time_t notice_abort;
    int status;
};
struct hosts_s ho_initial; /* the null template */
struct hosts_s *hosts;

Disamping menyajikan berbagai menu, strobery juga dibuat kadaluarsa sampai kapan buah ini tidak akan basi.

#define HT_SOCKET 1
#define HT_CONNECTING 2
#define HT_CONNECTED 4

menu buah ini juga, disajikan berdasarkan golongan usia, anak kecil, perempuan, sampai manula.

struct htuple_s
{
    char *name;
    struct in_addr in_addr;
    int port;
    int sfd;
    int status;
    struct timeval sock_start;
    int timeout;
    struct hosts_s *host;
    int data_lines;
    int data_len;
    u_char *data;
    int send_pos;
    int send_len;
    u_char *send;
};

struct htuple_s ht_initial;
struct htuple_s *attempt;

struct port_desc_s
{
    int port;
    char *name;
    char *portname;
    struct port_desc_s *next;
    struct port_desc_s *next_port;
};

struct port_desc_s **port_descs;

int *portlist = NULL;
int portlist_n = 0;

void display_port_sw (struct htuple_s *h);

Tidak mungkin keracunan makan strobery akan tertidur pulas, namun kalau kekenyangan pasti akan tertidur dengan sendirinya, alamiah deh…

char *
Srealloc (ptr, len)
  char *ptr;
  int len;
{
    char *p;
    int retries = 10;
    while (!(p = ptr? realloc (ptr, len): malloc(len)))
    {
        if (!--retries)
        {
        perror("malloc");
        exit(1);
    }
    if (!f_quiet)
       fprintf(stderr, "Smalloc: couldn't allocate %d bytes...sleeping\n", len);
    sleep (2);
    }
    return p;
}

char *
Smalloc (len)
  int len;
{
   return Srealloc (NULL, len);
}

fvoid
sock_block (sfd)
  int sfd;
{
    int flags;
    flags = (~O_NONBLOCK) & fcntl (sfd, F_GETFL);
    fcntl (sfd, F_SETFL, flags);
}

fvoid
sock_unblock (sfd)
  int sfd;
{
    int flags;
    flags = O_NONBLOCK | fcntl (sfd, F_GETFL);
    fcntl (sfd, F_SETFL, flags);
}

int
timeval_subtract (result, x, y) /* why not floating point?  */
  struct timeval *result, *x, *y;
{
  result->tv_usec = x->tv_usec - y->tv_usec;
  result->tv_sec = x->tv_sec - y->tv_sec;
  if (result->tv_usec<0)
  {
    result->tv_usec+=1000000;
    result->tv_sec --;
  }
/* Return 1 if result is negative. */
return result->tv_sec < 0;
}

fvoid
attempt_clear (h)
  struct htuple_s *h;
{
    if (h->status & HT_CONNECTED)
        display_port_sw (h);
    if (h->status & HT_SOCKET)
    {
    struct timeval tv1, tv2;
    gettimeofday(&tv1, NULL);
    timeval_subtract(&tv2, &tv1, &(h->sock_start));
    h->host->time_used.tv_sec+=tv2.tv_sec;
    if ((h->host->time_used.tv_usec+=tv2.tv_usec) >= 1000000)
    {
        h->host->time_used.tv_usec -= 1000000;
        h->host->time_used.tv_sec++;
    }
        attempts_done++;
    h->host->attempts_done++;
    if (h->port > h->host->attempts_highest_done)
        h->host->attempts_highest_done=h->port;
    sock_unblock (h->sfd);
/*    shutdown (h->sfd, 2); */
    close (h->sfd);
        if ( (FD_ISSET(h->sfd, &set_sel_check_r)) || (FD_ISSET(h->sfd, &set_sel_check_w)) )
    {
         FD_CLR (h->sfd, &set_sel_check_r);
             FD_CLR (h->sfd, &set_sel_check_w);
         attempts_outstanding--;
    }
    }
    if (h->data)
        free(h->data);
    *h = ht_initial;
}

Menceritakan kembali fungsi-fungsi, kenapa strobery ini disajikan melalui pintu dengan pelayan secara rahasia.

fvoid
clear_all ()
{
    int n;
    for (n = 0; n < a_sock_max; n++)
    attempt_clear (&attempt[n]);
}

fvoid
attempt_init ()
{
    int n;
    for (n = 0; n < a_sock_max; n++)
    attempt[n] = ht_initial;
}

fvoid
hosts_init ()
{
    int n;
    for (n = 0; n < a_sock_max; n++)
    hosts[n] = ho_initial;
}

fvoid
fdsets_init ()
{
    FD_ZERO(&set_sel_r); /* yes, we have to do this, despite the later */
    FD_ZERO(&set_sel_w); /* assisgnments */
    FD_ZERO(&set_sel_check_r);
    FD_ZERO(&set_sel_check_w);
}

Strobery juga dikemas disamping untuk berbagai kalangan usia, juga untuk berapa lama kesegaran buah itu terasa manisnya di bibir.

int
sc_connect (h)
  struct htuple_s *h;
{
    struct sockaddr_in sa_in;
    int sopts1 = 1;
    struct linger slinger;
    if ((h->sfd = socket (PF_INET, SOCK_STREAM, 0)) == -1)
    return 0;
    memset(&sa_in, 0, sizeof(sa_in));
    h->status |= HT_SOCKET;
    gettimeofday(&(h->sock_start), NULL);
    sock_unblock (h->sfd);
    setsockopt (h->sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sopts1, sizeof (sopts1));
    setsockopt (h->sfd, SOL_SOCKET, SO_OOBINLINE, (char *) &sopts1, sizeof (sopts1));
    slinger.l_onoff = 0;    /* off */
    setsockopt (h->sfd, SOL_SOCKET, SO_LINGER, (char *) &slinger, sizeof (slinger));
    sa_in.sin_family = AF_INET;
    if (a_bindport)
        sa_in.sin_port = a_bindport;
    if (a_bindaddr)
        sa_in.sin_addr = bindaddr;
    if (a_bindaddr || a_bindport)
        if (bind (h->sfd, (struct sockaddr *)&sa_in, sizeof(sa_in)) == -1)
        {
        fprintf(stderr, "couldn't bind %s : %d  ", a_bindaddr? a_bindaddr: "0.0.0.0", ntohs(a_bindport));
        perror("");
        if (errno == EACCES)
            exit(1);
        return 0;
    }
    sa_in.sin_addr = h->in_addr;
    sa_in.sin_port = htons (h->port);

    h->host->attempts++;
    if (connect (h->sfd, (struct sockaddr *) &sa_in, sizeof (sa_in)) == -1)
    {
    switch (errno)
    {
    case EINPROGRESS:
    case EWOULDBLOCK:
        break;
    case ETIMEDOUT:
    case ECONNREFUSED:
    case EADDRNOTAVAIL:
        if (f_verbose)
        {
        fprintf(stderr, "%s:%d ", h->name, h->port);
        perror("");
        }
        attempt_clear (h);
        return 0;
    default:
        if (!f_quiet)
        {
            fprintf(stderr, "%s:%d ", h->name, h->port);
            perror ("");
        }
        attempt_clear (h);
        return 0;
    }
    }
    h->status |= HT_CONNECTING;
    sock_block (h->sfd);
    FD_SET(h->sfd, &set_sel_check_r);
    FD_SET(h->sfd, &set_sel_check_w);
    attempts_outstanding++;
    return 1;
}

Pengantar strobery menggunakan pintu sederhana agar pesanannya sampai ke tuan rumah.

void
gen_port_simple (h, buf)
  struct htuple_s *h;
  char *buf;
{
    sprintf (buf, "%.128s %5d", h->name, h->port);
}

Caranya, adalah mengintip di bilik rumah, siapa aja yang ada di dalam rumah

int
display_port_simple (h, fh)
  struct htuple_s *h;
  FILE *fh;
{
    char buf[256];
    gen_port_simple(h, buf);
    fputs(buf, fh);
    return strlen(buf);
}

Kemudian, mengintip juga pintu lain yang bisa dimasuki dengan membawa buah strobery yang lebih banyak.

void
display_port (h, fh)
  struct htuple_s *h;
  FILE *fh;
{
    int ds_len;
    ds_len = display_port_simple(h, fh);
    if (f_minimise)
    fputc('\n', fh);
    else
    {
        struct port_desc_s *pd;
        if ((pd = port_descs[h->port]))
        {
            fprintf (fh, " %-12s %s\n", pd->portname, pd->name);
        while (!f_delete_dupes && (pd=pd->next))
            fprintf (fh, "%*s %-12s %s\n", ds_len, "", pd->portname, pd->name);
        }
        else
            fprintf (fh, " %-12s %s\n", "unassigned", "unknown");
    }
}

u_char *
conv_char(c, c2)
u_char c;
u_char c2;
{
        static u_char b[8];
    bzero(b, sizeof b);
    if (c=='\\')
    {
        b[0] = c;
        b[1] = c;
    } else
    if (c>=32 && c<127)
    {
        b[0] = c;
    } else
    if (c == '\r')
    {
        b[0] = '\\';
        b[1] = 'r';
    } else
    if (c == '\n')
    {
        b[0] = '\\';
        b[1] = 'n';
    } else
    if (c == '\t')
    {
        b[0] = '\\';
        b[1] = 't';
    } else
    if (c == 8)
    {
        b[0] = '\\';
        b[1] = 'b';
    } else
    if (c<32 || c >= 127)
    {
        /* remove possible ambiguity \n or \nn then digit */
        if (c<100 && isdigit(c2))
            sprintf (b, "\\%03d", (int)c);
        else
            sprintf (b, "\\%d", (int)c);
    } else
    {
        fprintf (stderr, "internal error in print_char");
    }
    return b;
}

Buah2 yang manis dan segar, yang dibawa dari luar, kira2 busuk apa tidak ketika sudah di rumah dengan sekian waktu menunggu, apakah tuan rumah masih tertarik mencicipi buah apa tidak. maka buah dikemas
sesegar mungkin dengan tidak menggunakan pengawet tapi menggunakan ascii yaitu, keranjang yang sudah diciptakan para ahli agar strobery tidak busuk apalagi berubah wujud.

void
asciidump (h, fh)
  struct htuple_s *h;
  FILE *fh;
{
    int n;
    int col = 0;
    char buf[256];
    int buf_len;
    char *p=h->data;
    gen_port_simple(h, buf);
    buf_len = strlen(buf);
    for (n=0; n<h->data_len; n++) {
        if (col == 0)
    {
        if (!a_dircap)
        {
            if (f_minimise)
        {
            fputs(buf, fh);
            col = buf_len;
            }
        else
        {
            fprintf(fh, "%*s->", buf_len+1, "");
        }
        fputc(' ', fh);
        }
    }
        fputs(conv_char(p[n], (n==h->data_len-1)? '': p[n+1]), fh);
    col++;
    if (a_wrap)
    {
        if (col >= a_wrap)
        {
            fputc('\n', fh);
        col = 0;
        }
        else
        {
        switch (p[n])
        {
         case '':
         case '\n':
            fputc('\n', fh);
            col = 0;
        }
            }
       }
    }
   if (col !=0)
       fputc('\n', fh);
}

Jumlah keranjang juga ditulis-tulis di luar kemasanya, agar tidak salah makan apalagi salah buka, kemasan ditulis dengan angka hexadecimal dimana strobery rasanya tetep asem.

void
hexdump(h, fh)
  struct htuple_s *h;
  FILE *fh;
{
    int n;
    char buf[256];
    int buf_len;
    gen_port_simple(h, buf);
    buf_len = strlen(buf);
    for (n = 0; n < h->data_len; n+=12)
    {
        int y;
        if (!a_dircap)
        {
        if (f_minimise)
        {
            fputs(buf, fh);
        }
        else
        {
            fprintf(fh, "%*s->", buf_len+1, "");
        }
        fputc(' ', fh);
        }
        for (y=0; y<12; y++)
        {
            if (y+n< h->data_len)
                fprintf(fh, "%02X ", h->data[n+y]);
            else
                fputs("   ", fh);
            if (y%4==3 && y!=11)
                fputc(' ', fh);
        }
        fputs(": ", fh);
        for (y=0; y<12; y++)
        {
            if (y+n< h->data_len)
                fprintf(fh, "%c", isprint(h->data[n+y])? h->data[n+y]: '.');
            else
                fputc(' ', fh);
        }
        fputc('\n', fh);
    }
    fputc('\n', fh);
}

char *
trslash (s)
  char *s;
{
    char *p=s;
    for (;*s; s++)
        if (*s == '/')
        *s = ',';
    return p;
}

/*
 * recursively build directory hierarchy, starting at leaf
 */

Strobery yang didalam keranjang antik itu, kemudian dibuka dan disajikan dalam  direktori berupa piring kerajaan yang berisi beberapa buah segar dan ditulis, waktu petik dan siapa aja yang boleh makan.

bool
blddir (name)
  char *name;
{
    char *p;

    if ((p = strrchr (name, '/')) == NULL)
        return FALSE;
    *p = '';
    if (mkdir (name, (mode_t) 0775) == -1)
        if (!blddir (name))
        {
            *p = '/';
            return FALSE;
        }
    if (mkdir (name, (mode_t) 0775) == -1)
    {
        if (errno != EEXIST)
        {
            fprintf(stderr, "error building directory hierarchy %s", name);
            *p = '/';
            return FALSE;
        }
    }
    *p = '/';
    return TRUE;
}

bool
makeln (char *from, char *to)
{
    if (link(from, to) !=0)
    {
        blddir(to);
    if (link(from, to) !=0)
    {
        perror(to);
        return FALSE;
    }
    }
    return TRUE;
}

Buah yang dipiringi, akan disantap bilamana, tuan rumah sudah tahu kalau buah itu segar, merah dan manis.

void
display_port_sw (h)
  struct htuple_s *h;
{
    char master[1024];
    FILE *fh = stdout;

    if (a_dircap)
    {
        char buf[2048];
    char in[64];
    char *p;
        struct port_desc_s *pd;
    sprintf(master, "%.512s/strobe.%d", a_dircap, (int)getpid());
    fh = fopen(master, "w");
    if (!fh)
    {
        blddir(master);
        fh = fopen(master, "w");
        if (!fh)
        {
            perror(master);
        return;
        }
    }
    strcpy(in, inet_ntoa(h->host->in_addr));
    for (p=in; *p; p++)
        if (*p == '.')
            *p = '/';
        pd = port_descs[h->port];
    if (strstr(a_views, "networks"))
    {
            if (f_minimise)
            sprintf(buf, "%.512s/networks/%s/%s-%.256s/%05d", a_dircap, in, inet_ntoa(h->host->in_addr),
                    h->host->name, h->port);
        else
            sprintf(buf, "%.512s/networks/%s/%s-%.256s/%05d-%.200s-%.200s", a_dircap, in, inet_ntoa(h->host->in_addr),
                    h->host->name, h->port, pd? port_descs[h->port]->portname: "unknown", pd? trslash(port_descs[h->port]->name): "");
        makeln(master, buf);
    }
    if (strstr(a_views, "hosts"))
    {
            if (f_minimise)
            sprintf(buf, "%.512s/hosts/%s-%.256s/%05d", a_dircap, inet_ntoa(h->host->in_addr),
                    h->host->name, h->port);
        else
            sprintf(buf, "%.512s/hosts/%s-%.256s/%05d-%.200s-%.200s", a_dircap, inet_ntoa(h->host->in_addr),
                    h->host->name, h->port, pd? port_descs[h->port]->portname: "unknown", pd? trslash(port_descs[h->port]->name): "");
        makeln(master, buf);
    }
    if (strstr(a_views, "all"))
    {
            if (f_minimise)
            sprintf(buf, "%.512s/all/%.64s-%.200s-%05d", a_dircap, inet_ntoa(h->host->in_addr),
                h->host->name, h->port);
        else
            sprintf(buf, "%.512s/all/%.64s-%.200s-%05d-%.200s-%.200s", a_dircap, inet_ntoa(h->host->in_addr),
                h->host->name, h->port, pd? port_descs[h->port]->portname: "unknown", pd? trslash(port_descs[h->port]->name): "");
        makeln(master, buf);
    }
    if (strstr(a_views, "ports"))
    {
            if (f_minimise)
            sprintf(buf, "%.512s/ports/%05d/%s-%.200s", a_dircap, h->port, inet_ntoa(h->host->in_addr),
                h->host->name);
        else
            sprintf(buf, "%.512s/ports/%05d-%.200s-%.200s/%.64s-%.200s", a_dircap, h->port,
                pd? port_descs[h->port]->portname: "unknown", pd? trslash(port_descs[h->port]->name): "",
                inet_ntoa(h->host->in_addr), h->host->name);
        makeln(master, buf);
    }
    }
    if (h->status&HT_CONNECTED)
    {
        if (!f_minimise && !a_dircap)
            display_port(h, fh);
        if (h->data_len>0)
        {
            if (f_hexdump)
            hexdump(h, fh);
            else
            asciidump(h, fh);
        }
    }
    if (a_dircap)
    {
        fclose(fh);
        unlink(master);
    }
    if (!(h->status&HT_CONNECTED))
        display_port(h,fh);
}

Buah yang benar2 segar itupun tidak saja, dikirim lewat pintu utama namun dikirim dari berbagai pintu semisal pintu tcp

void
init_capture_tcp (h)
  struct htuple_s *h;
{
    h->status&=~HT_CONNECTING;
    h->status|=HT_CONNECTED;
    FD_CLR (h->sfd, &set_sel_check_w);
}

void
capture_tcp (h)
  struct htuple_s *h;
{
    int cc;
    bool f_drop = 0;
    cc = recv(h->sfd, capture_buf, a_capture, 0);
    if (cc == 0)
    {
        attempt_clear (h);
    return;
    }
    if (cc < 0)
    {
        switch (errno)
    {
     case EAGAIN:
     case EINTR:
        break;
     default:
        attempt_clear (h);
    }
    return;
    }
    if (h->data_len+cc>a_capture)
    {
        cc = a_capture - h->data_len;
    f_drop = 1;
    }
    if (a_lines)
    {
        int n;
    for (n=0; n<cc; n++)
        if (capture_buf[n] == '\n' ||
            capture_buf[n] == '')
            h->data_lines++;
    }
    h->data_len+=cc;
    if (h->data)
        h->data = Srealloc(h->data, h->data_len);
    else
        h->data = Smalloc(h->data_len);
    memcpy(h->data+h->data_len-cc, capture_buf, cc);
    if (f_drop || h->data_lines >= a_lines)
        attempt_clear (h);
}

int
gatherer_tcp (h)
  struct htuple_s *h;
{
    h->host->connects++;
    connects++;
    if (a_capture)
        init_capture_tcp (h);
    else
    {
        display_port_sw (h);
    attempt_clear (h);
    }
    return 1;
}

int
gather (timeout_secs)
  int timeout_secs;
{
    struct timeval timeout;
    struct htuple_s *h;
    int n;
    int last = -1;
    int selected;
    time_t tim;

    if (!attempts_outstanding) return 1;
    set_sel_r=set_sel_check_r;
    set_sel_w=set_sel_check_w;

    if (timeout_secs)
    {
        timeout.tv_sec = timeout_secs;
        timeout.tv_usec = 0;
    }
    else
    {
        timeout.tv_sec = 0;
        timeout.tv_usec = 250000; /* 1/4 of a second */
    }

    selected = select (FD_SETSIZE, &set_sel_r, &set_sel_w, 0, &timeout);
    if (selected<0)
    perror ("select");

    tim = time (NULL);
    for ( n = 0 ; n < a_sock_max; n++ )
    {
        h = &attempt[n];
        if (h->status & HT_CONNECTED)
        {
            if (!FD_ISSET(h->sfd,&set_sel_r))
            {
              if ( (tim - h->sock_start.tv_sec) >= h->timeout)
              {
                attempt_clear(h);
              }
              continue;
            }
        }
    if (selected>0 && h->status & (HT_CONNECTING|HT_CONNECTED))
    {
        if (FD_ISSET (h->sfd, &set_sel_r) ||
                FD_ISSET (h->sfd, &set_sel_w))
        {
        struct sockaddr_in in;
        int len = sizeof (in);
        selected--;

                /* select() lies occasionaly
                 */
        if (!f_dontgetpeername) /* but solaris2.3 crashes occasionally ;-| */
        {
            if (getpeername (h->sfd, (struct sockaddr *) &in, &len) == 0)
            {
                if ((h->status & HT_CONNECTED) && FD_ISSET (h->sfd, &set_sel_r))
                                capture_tcp (h);
                else
                        gatherer_tcp (h);
                }
            else
                    attempt_clear (h);
        }
        else
        {
            if ((h->status & HT_CONNECTED) &&
            FD_ISSET (h->sfd, &set_sel_r))
            capture_tcp (h);
            else
            gatherer_tcp (h);
        }
        }
        last = n;
    } else
    {
        if ((h->status & HT_SOCKET) &&
            ((h->sock_start.tv_sec + h->timeout) < tim))
        {
            attempt_clear (h);
        last = n;
        }
    }
    }
    return last;
}

Tidak sedikit mengirim buah itu, disediakan juga cadangan atau stok bilamana buah habis dan menu buah strobery ditambah lagi jumlahnya.

bool
add_attempt (add)
  struct htuple_s *add;
{
    struct htuple_s *h;
    static time_t oldtime;
    int ret;
    for (;;)
    {
     int n;
        int last;
    for (n=0; n < a_sock_max; n++)
    {
        h = &attempt[n];
        if (!h->status)
        goto foundfree;
    }
    last = gather (a_timeout);
    oldtime = time(NULL);
    if (last != -1) {
       h = &attempt[last];
       goto foundfree;
    }
    }
    foundfree:
    *h = *add;
    ret = sc_connect (h);
    if (oldtime+1<time(NULL)) {
    if (oldtime > 0)
        gather (0);
    oldtime = time(NULL);
    }
    return ret;
}

Memberikan buah segar kepada beberapa penghuni rumah, dengan mencicipinya.
int
scatter (host, timeout)
struct hosts_s *host;
int timeout;
{
static struct htuple_s add;
add = ht_initial;
add.host = host;
add.name = host->name;
add.in_addr = host->in_addr;
add.port = host->port;
add.timeout = timeout;
if (f_verbose)
fprintf (stderr, “attempting port=%d host=%s\n”, add.port, add.name);
add_attempt (&add);
return 1;
}
Malah, ada yang berkata, tunggu buah itu dimakan harus oleh pengawal dulu, bisa diyakini buah itu tidak manis dan jebakan semata.
fvoid
wait_end (t)
int t;
{
time_t st;
st = time (NULL);
while ((st + t) > time (NULL))
{
gather (a_timeout);
if (attempts_outstanding<1) break;
}
}
Akhirnya si buah strobery itu dikunyah oleh pengawal dan pengawal berkata, wah buah ini memang segar dan menyehatkan lhoooo…

struct in_addr
resolve (name)
  char *name;
{
    static struct in_addr in;
    unsigned long l;
    struct hostent *ent;
    if ((l = inet_addr (name)) != INADDR_NONE)
    {
    in.s_addr = l;
    return in;
    }
    if (!(ent = gethostbyname (name)))
    {
    perror (name);
    in.s_addr = INADDR_NONE;
    return in;
    }
    return *(struct in_addr *) ent->h_addr;
}

Testimoni itu tidak selesai, kemudian buah segar itu dibagi-bagi ke penghuni lainnya, agar penghuni bisa merasakan bukan hanya katanya saja.

char *
next_host ()
{
    static char lbuf[512];
    if (a_input)
    {
    int n;
reread:
    if (!fgets (lbuf, sizeof (lbuf), fh_input))
    {
        fclose (fh_input);
            a_input = NULL;
        return next_host();
    }
    if (strchr("# \t\n\r", lbuf[0])) goto reread;
    n = strcspn (lbuf, " \t\n\r");
    if (n)
        lbuf[n] = '';
        hosts_done++;
    return lbuf;
    }
    if ( host_n >= Argc )
      return NULL;

    hosts_done++;
    return Argv[host_n++];
}

Diyakini buah strobery memberikan kesehatan dan warnanya yang mempesona, maka punggawa membagikan ke pintu lainnya adalah pintu para mentri dan jajaran stafnya.

int
next_port (h)
struct hosts_s *h;
{
    int n;
    if (f_fast)
        return (++h->portlist_ent>portlist_n)?-1:portlist[h->portlist_ent-1];
    else if (h->portlist)
    {
        return (++h->portlist_ent>h->portlist_n)?-1:h->portlist[h->portlist_ent-1];
    }
    else
    {
        for (n = h->port; ++n <= a_end;)
        {
            return n;
        }
    }
    return -1;
}

Pasokan kebutuhan buah sangat diminati, sehingga membuka pintu lain agar strobery bisa terdistribusi dengan cepat.

int
add_port(h,p)
  struct hosts_s *h;
  int p;
{
    if (!p)
        return 0;
    if (h->portlist_n == h->portlist_alloc)
    {
        h->portlist_alloc += 20;
        h->portlist=(int *)Srealloc(h->portlist,h->portlist_alloc*sizeof(int));
    }
    h->portlist[h->portlist_n++]=p;
    return p;
}

Banyak testimoni yang bercerita, kalo buah strobery memang merah dan manis.

bool
host_init (h, name, nocheck)
  struct hosts_s *h;
  char *name;
  bool nocheck;
{
    int n;
    char *ports;

    *h=ho_initial;
    if ((ports=strchr(name,':')))
    {
        char *pstart, *minus;
        int i, stopnow=0;
        int lastport;

        *ports=0;
        pstart=++ports;
        while(!stopnow)
        {
            switch(*ports)
            {
                case '':
                    stopnow=1;
                    /* FALL THROUGH */
                case ',':
                case ':':
                    *ports=0;
                    if ((minus=strchr(pstart,'-')))
                    {
                        *minus=0;
                        lastport=atoi(minus++);

                        for(i=atoi(pstart);i<=lastport;i++)
                            if (!add_port(h,i))
                            {
                                stopnow=2;
                                break;
                            }
                    }
                    else
                    {
                        if (!add_port(h,atoi(pstart)))
                            stopnow=2;
                    }
                    pstart=ports+1;
                    break;
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                case '-':
                    break;
                default:
                    stopnow=2;
            }
            ports++;
        }
        if (stopnow==2)
        {
            fprintf(stderr,"Couldn't parse port specifier\n");
            exit(1);
        }
    }
    h->in_addr = resolve (name);
    if (h->in_addr.s_addr == INADDR_NONE)
    return 0;
    if (!nocheck)
        for (n=0; n<a_sock_max; n++)
       {
        if (hosts[n].name && hosts[n].in_addr.s_addr==h->in_addr.s_addr)
        {
        if (!f_quiet)
            fprintf(stderr, "ip duplication: %s == %s (last host ignored)\n",
                hosts[n].name, name);
        return 0;
        }
        }
    h->name = (char *) Smalloc (strlen (name) + 1);
    strcpy (h->name, name);
    if(f_fast || h->portlist)
        h->port=next_port(h);
    else
        h->port = a_start;
    h->status = HO_ACTIVE;
    gettimeofday(&(h->time_start), NULL);
    return 1;
}

Ada juga yang bercerita, kalo buah strobery itu asam dan kurang segar,  akhirnya tuan rumah membersihkan buah2 yang dirasa tidak segar dan dikemas dalam bentuk lain berupa yogurt dan minuman lainnya.

fvoid
host_clear (h)
  struct hosts_s *h;
{
    if (h->name)
    {
        free (h->name);
    }
    *h=ho_initial;
}

Setelah tahu kalo itu adalah minuman, maka strobery yang berupa buah itu berganti status nama menjadi yogurt rasa strobery.

fvoid
host_stats (h)
  struct hosts_s *h;
{
    struct timeval tv, tv2;
    float t, st;
    gettimeofday(&tv, NULL);
    timeval_subtract(&tv2, &tv, &(h->time_start));
    t = tv2.tv_sec+(float)tv2.tv_usec/1000000.0;
    st = h->time_used.tv_sec+(float)h->time_used.tv_usec/1000000.0;
    fprintf(stderr, "stats: host = %s trys = %d cons = %d time = %.2fs trys/s = %.2f trys/ss = %.2f\n",
    h->name, h->attempts_done, h->connects, t, h->attempts_done/t, h->attempts_done/st);
}

Malah ada sebagian ibu2 yang menyajikan kue ulang tahunnya dengan pemanis strobery untuk menyedapkan mata pengunjung.

fvoid
final_stats()
{
    struct timeval tv, tv2;
    float t;
    gettimeofday(&tv, NULL);
    timeval_subtract(&tv2, &tv, &(time_start));
    t = tv2.tv_sec+(float)tv2.tv_usec/1000000.0;
    fprintf(stderr, "stats: hosts = %d trys = %d cons = %d time = %.2fs trys/s = %.2f\n",
    hosts_done, attempts_done, connects, t, attempts_done/t);
}

Kue berhiaskan strobery itupun akhirnya ditunda untuk dibagikan, menunggu tamu undangan datang.

bool skip_host(h)
  struct hosts_s *h;
{
    if (a_abort && !h->connects && (h->attempts_highest_done >= a_abort)) /* async pain */
    {
    if (h->status & HO_ABORT)
    {
        if ((time(NULL)-h->notice_abort)>a_timeout)
        {
        if (f_verbose)
            fprintf(stderr, "skipping: %s (no connects in %d attempts)\n",
            h->name, h->attempts_done);
        return 1;
        }
    } else
        {
        h->notice_abort=time(NULL);
        h->status|=HO_ABORT;
    }
    }
    return 0;
}

Kemudian, tuan rumah juga mendata secara linear, siapa aja yang suka buah strobery atau kue ulang tahun.

fvoid
scan_ports_linear ()
{
    struct hosts_s host;
    char *name;
    while ((name = next_host ()))
    {
    if (!host_init(&host, name, 1)) continue;
    for (;;)
    {
        scatter (&host, a_timeout);
        if (skip_host(&host)) break;
        if ((host.port = next_port(&host))==-1)
        break;
    }
    wait_end (a_timeout);
    if (f_verbose_stats)
        host_stats (&host);
    clear_all ();
    host_clear(&host);
    }
}

/* Huristics:
 *  o  fast connections have priority == maximise bandwidth i.e
 *     a port in the hand is worth two in the bush
 *
 *  o  newer hosts have priority == lower ports checked more quickly
 *
 *  o  all hosts eventually get equal "socket time" == despite
 *     priorities let no one host hog the sockets permanently
 *
 *  o  when host usage times are equal (typically on or shortly after
 *     initial startup) distribute hosts<->sockets evenly rather than
 *     play a game of chaotic bifurcatic ping-pong
 */

Kemudian juga menanyakan, siapa aja yang mau membagikan buah itu secara langsung berhadapan atau paralell, dari distribusi buah yang kecil sampai buah yang besar.

fvoid
scan_ports_paralell ()
{
    int n;
    struct timeval smallest_val;
    int smallest_cnt;
    char *name;
    struct hosts_s *h, *smallest;
    struct hosts_s *anyhost;
    do
    {
    smallest_val.tv_sec=0xfffffff;
    smallest_val.tv_usec=0;
    for (n = 0, smallest_cnt = 0xfffffff, anyhost= smallest = NULL; n < a_sock_max; n++)
    {
        h = &hosts[n];

        if (((h->status & HO_COMPLETING) &&
                 (h->attempts_done == h->attempts)) ||
                skip_host(h))
        {
        if (f_verbose_stats) host_stats (h);
        host_clear (h);
        }

        if (!h->name && ((name = next_host ())))
        if (!host_init (h, name, 0))
        {
            host_clear (h);
            continue;
        }

        if (h->name)
        {
                anyhost=h;
        if ((((h->time_used.tv_sec < smallest_val.tv_sec) ||
             ((h->time_used.tv_sec == smallest_val.tv_sec) &&
              (h->time_used.tv_usec <= smallest_val.tv_usec))) &&
            (((h->time_used.tv_sec != smallest_val.tv_sec) &&
              (h->time_used.tv_usec != smallest_val.tv_usec)) ||
             (h->attempts < smallest_cnt)))&&
                     !(h->status&HO_COMPLETING))
            {
              smallest_cnt = h->attempts;
            smallest_val = h->time_used;
            smallest = h;
         }
        }
    }

    if (smallest)
    {
/* scatter adds connection or calls gather() until one is freed   */
        scatter (smallest, a_timeout);
        if ((smallest->port=next_port(smallest))==-1)
                smallest->status|=HO_COMPLETING;
    }
        else
            gather(a_timeout);
    }
    while(anyhost);
}

Buah juga dideskripsikan fungsinya, mana untuk darah tinggi, mana utk kolesterol, lambung, kulit dll.

fvoid
loaddescs ()
{
    FILE *fh;
    char lbuf[1024];
    char desc[256];
    char portname[17];
    unsigned int port;
    char *fn;
    char prot[4];
    prot[3]='';
    if (!(fh = fopen ((fn=a_services), "r")) &&
        !(fh = fopen ((fn=LIB_STROBE_SERVICES), "r")) &&
        !(fh = fopen ((fn=ETC_SERVICES), "r")))
    {
    perror (fn);
    exit (1);
    }
    port_descs=(struct port_desc_s **) Smalloc(sizeof(struct port_descs_s *) * 65536);
    memset(port_descs, 0, 65536);
    while (fgets (lbuf, sizeof (lbuf), fh))
    {
    char *p;
    struct port_desc_s *pd, *pdp;
    if (strchr("*# \t\n", lbuf[0])) continue;
    if (!(p = strchr (lbuf, '/'))) continue;
    *p = ' ';
    desc[0]='';
    if (sscanf (lbuf, "%16s %u %3s %255[^\r\n]", portname, &port, prot, desc) <3 || strcmp (prot, "tcp") || (port > 65535))
        continue;
    pd = port_descs[port];
    if (!pd)
    {
        portlist = (int *)Srealloc((char *)portlist, ++portlist_n*sizeof(int));
        portlist[portlist_n-1]=port;
    }
    pdp = (struct port_desc_s *) Smalloc (sizeof (*pd) + strlen (desc) + 1 + strlen (portname) + 1);
    if (pd)
    {
        for (; pd->next; pd = pd->next);
        pd->next = pdp;
        pd = pd->next;
    } else
    {
        pd = pdp;
        port_descs[port] = pd;
    }
    pd->next = NULL;
    pd->name = (char *) (pd) + sizeof (*pd);
    pd->portname = pd->name + strlen(desc)+1;
    strcpy (pd->name, desc);
    strcpy (pd->portname, portname);
    }
    fclose (fh);
}

Akhirnya, dibuatlah kesimpulan penggunaan dan distribusi buah strobery, agar dipasarkan secara baik.

fvoid
usage ()
{
    fprintf (stderr, "\
usage: %8s [options]\n\
\t\t[-v(erbose)]\n\
\t\t[-V(erbose_stats]\n\
\t\t[-m(inimise)]\n\
\t\t[-d(elete_dupes)]\n\
\t\t[-g(etpeername_disable)]\n\
\t\t[-s(tatistics)]\n\
\t\t[-q(uiet)]\n\
\t\t[-o output_file]\n\
\t\t[-b begin_port_n]\n\
\t\t[-e end_port_n]\n\
\t\t[-p single_port_n]\n\
\t\t[-P bind_port_n]\n\
\t\t[-A bind_addr_n]\n\
\t\t[-t timeout_n]\n\
\t\t[-n num_sockets_n]\n\
\t\t[-S services_file]\n\
\t\t[-i hosts_input_file]\n\
\t\t[-l(inear)]\n\
\t\t[-f(ast)]\n\
\t\t[-a abort_after_port_n]\n\
\t\t[-c capture_n]\n\
\t\t[-w wrap_col_n]\n\
\t\t[-x(heXdump)]\n\
\t\t[-L capture_lines_n]\n\
\t\t[-D capture_directory]\n\
\t\t[-T capture_timeout_n]\n\
\t\t[-M(ail_author)]\n\
\t\t[host1 [...host_n]]\n", Argv[0]);
    exit (1);
}
int
main (argc, argv)
  int argc;
  char **argv;
{
    int c;
    Argc = argc;
    Argv = argv;

    while ((c = getopt (argc, argv, "o:dvVmgb:e:p:P:a:A:t:n:S:i:lfsqMc:w:xL:D:T:")) != -1)
    switch (c)
    {
    case 'o':
        a_output = optarg;
        break;
    case 'd':
        f_delete_dupes=1;
        break;
    case 'v':
        f_verbose = 1;
        break;
    case 'V':
        f_verbose_stats = 1;
        break;
    case 'm':
        f_minimise = 1;
        break;
    case 'g':
        f_dontgetpeername = 1;
        break;
    case 'b':
        a_start = atoi (optarg);
        break;
    case 'e':
        a_end = atoi (optarg);
        break;
    case 'P':
        a_bindport = htons (atoi (optarg));
        break;
    case 'A':
        a_bindaddr = optarg;
        bindaddr = resolve (a_bindaddr);
        if (bindaddr.s_addr == INADDR_NONE)
        {
            perror(a_bindaddr);
        exit(1);
        }
            break;
    case 'p':
        a_start = a_end = atoi (optarg);
        break;
    case 'a':
        a_abort = atoi (optarg);
        break;
    case 't':
        a_timeout = atoi (optarg);
        break;
    case 'n':
        a_sock_max = atoi (optarg);
        break;
    case 'S':
        a_services = optarg;
        break;
    case 'i':
        a_input = optarg;
        break;
    case 'l':
        f_linear = 1;
        break;
    case 'f':
        f_fast = 1;
        break;
    case 's':
        f_stats = 1;
        break;
        case 'q':
        f_quiet = 1;
        break;
    case 'M':
        fprintf(stderr, "Enter mail to author below. End with ^D or .\n");
        system("mail strobe@suburbia.net");
        break;
    case 'c':
        a_capture = atoi(optarg);
        break;
    case 'w':
        a_wrap = atoi(optarg);
        break;
    case 'x':
        f_hexdump = 1;
        break;
    case 'L':
        a_lines = atoi(optarg);
        break;
        case 'D':
            a_dircap = optarg;
            break;
    case 'T':
        a_data_timeout = atoi (optarg);
        break;
    case '?':
    default:
        fprintf (stderr, "unknown option %s\n", argv[optind-1]);
        usage ();
        /* NOT_REACHED */
    }
    host_n = optind;

    if (!f_quiet)
        fprintf (stderr, "strobe %s (c) 1995-1999 Julian Assange <proff@iq.org>.\n", VERSION);
    if (a_input)
    {
        if ( ! strcmp("-",a_input) ) { /* Use stdin as input file */
        fh_input = stdin;
      }
    else {
      if (!(fh_input = fopen (a_input, "r")))
        {
          perror (a_input);
          exit (1);
        }
    }
    } else
    {
      switch ( argc - host_n ) { /* Number of hosts found on command line */
      case 0:
    fh_input = stdin;
    a_input = "stdin"; /* Needed in "next_host()" */
    break;
      case 1:
    f_linear = 1;
    break;
      }
    }

    if ((fh_input==stdin) && !f_quiet)
      fprintf (stderr, "Reading host names from stdin...\n");    if (a_output)
    {
        int fd;
        if ((fd=open(a_output, O_WRONLY|O_CREAT|O_TRUNC, 0666))==-1)
    {
        perror(a_output);
        exit(1);
    }
    dup2(fd, 1);
    }
    if (a_capture)
        capture_buf = Smalloc(a_capture);
    attempt = (struct htuple_s *) Smalloc (a_sock_max * sizeof (struct htuple_s));
    attempt_init();
    if (!f_linear)
    {
        hosts = (struct hosts_s *) Smalloc (a_sock_max * sizeof (struct hosts_s));
        hosts_init();
    }
    loaddescs ();
    fdsets_init();
    gettimeofday(&time_start, NULL);
    f_linear ? scan_ports_linear ():
            scan_ports_paralell ();
    if (f_stats || f_verbose_stats)
    final_stats();
    exit (0);
}

Dan, buah stroberypun dapat didistribusikan dengan baik, buah dapat terjual dengan harga mahal dan kemasan yang berbeda-beda, pengirimpun sudah dapat informasi dari Raja sampai pesuruh, siapa saja yang
bisa makan strobery, jenis penyakit yang dapat disembuhkan dan tentunya buah dikemas dengan berbagai bahan, akhirnya pengawal mendapatkan informasi penuh dari rumah yang dikunjunginya.
selamat mencoba untuk mengembangkan kembali code yang diciptakan oleh Jullian Assange, narasi dari code di atas adalah bocoran langsung dari kawat blog Juli, sebutan pria australia yang pernah duda ini.

No comments: