ec_decodedata.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:13k
源码类别:

网络截获/分析

开发平台:

C/C++

  1. /*
  2.     ettercap -- data decoding module
  3.     Copyright (C) 2001  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include "include/ec_main.h"
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <errno.h>
  21. #ifdef HAVE_CTYPE_H
  22.    #include <ctype.h>
  23. #endif
  24. #include "include/ec_inet_structures.h"
  25. #include "include/ec_inet.h"
  26. #include "include/ec_error.h"
  27. #ifdef DEBUG
  28.    #include "include/ec_debug.h"
  29. #endif
  30. typedef struct
  31. {
  32.    int port;
  33.    char proto;
  34.    char desc[18];
  35.    struct database *next;
  36. } database;
  37. database *d_list = NULL;
  38. #ifndef HAVE_CTYPE_H
  39.    int isprint(int c);
  40. #endif
  41. int Decodedata_MakeConnectionList(CONNECTION data);
  42. int Decodedata_RefreshConnectionList(void);
  43. char * Decodedata_GetType(char proto, int port1, int port2);
  44. char * Decodedata_GetAsciiData(char *buffer, int buff_len);
  45. char * Decodedata_GetHexData(char *buffer, int buff_len, short dimX);
  46. char * Decodedata_GetEnhanchedHexData(char *buffer, int buff_len, short cr);
  47. char * Decodedata_TCPFlags(char flags);
  48. //--------------------------
  49. #ifndef HAVE_CTYPE_H
  50.    int isprint(int c)
  51.    {
  52.       return ( (c>31 && c<127) ? 1 : 0 );
  53.    }
  54. #endif
  55. int Decodedata_MakeConnectionList(CONNECTION data)
  56. {
  57.    int num_conn = 1;
  58.    char filter[45];
  59.    char cur_conn[45];
  60.    char rev_cur_conn[45];
  61.    char found = 0;
  62.    CONNECTION *ptr;
  63.    sprintf(filter, "%c%s%d%s%d", data.proto, data.ip_source, data.source_port, data.ip_dest, data.dest_port);
  64.    if (number_of_connections == 0)
  65.    {
  66.       found = 0;
  67.    }
  68.    else
  69.    {
  70.       for(ptr=Conn_Between_Hosts; num_conn <= number_of_connections; ptr++)
  71.       {
  72.          sprintf(cur_conn, "%c%s%d%s%d", ptr->proto, ptr->ip_source, ptr->source_port, ptr->ip_dest, ptr->dest_port);
  73.          sprintf(rev_cur_conn, "%c%s%d%s%d", ptr->proto, ptr->ip_dest, ptr->dest_port, ptr->ip_source, ptr->source_port);
  74.          num_conn++;
  75.          if (!strcmp(filter, cur_conn))
  76.          {
  77.             if (ptr->proto == 'T')
  78.             {
  79.                ptr->source_seq = data.source_seq;
  80.                ptr->flags = data.flags;
  81.             }
  82.             found = 1;
  83.          }
  84.          if (!strcmp(filter, rev_cur_conn))
  85.          {
  86.             if (ptr->proto == 'T')
  87.             {
  88.                ptr->dest_seq = data.dest_seq;
  89.                ptr->flags = data.flags;
  90.             }
  91.             found = 1;
  92.          }
  93.          if (found)
  94.          {
  95.             if (ptr->user[1] != -1)    // waiting for syn
  96.             {
  97.                if ( ptr->user[0] == 0 )      // the string is under construction
  98.                {
  99.                   strncpy(ptr->user + 1 + strlen(ptr->user+1), data.user, 29 - strlen(ptr->user+1) );
  100.                   if (strchr(data.user, 'n'))
  101.                   {
  102.                      char str[30];
  103.                      ptr->user[0] = ' ';
  104.                      strtok(ptr->user, "n");
  105.                      if ( data.dest_port == 23 || data.source_port == 23 ||
  106.                           data.dest_port == 513 || data.source_port == 513 )
  107.                         data.pass[0] = 0;        // evil workaround for telnet... we assume that pass always come AFTER login
  108.                      snprintf(str, 30, "USER:%s", ptr->user);
  109.                      strcpy(ptr->user, str);
  110.                   }
  111.                }
  112.                if ( ptr->user[0] != 0 && ptr->pass[0] == 0 )      // the string is under construction
  113.                {
  114.                   strncpy(ptr->pass + 1 + strlen(ptr->pass+1), data.pass, 29 - strlen(ptr->pass+1) );
  115.                   if (strchr(data.pass, 'n'))
  116.                   {
  117.                      char str[30];
  118.                      ptr->pass[0] = ' ';
  119.                      strtok(ptr->pass, "n");
  120.                      snprintf(str, 30, "PASS:%s", ptr->pass);
  121.                      strcpy(ptr->pass, str);
  122.                   }
  123.                }
  124.                //if ( ptr->info[0] == 0)
  125.                {
  126.                   if (strlen(data.info) && !strchr(ptr->info, 'n'))
  127.                      strlcat(ptr->info, data.info, 100);
  128.                }
  129.             }
  130.             else
  131.             {
  132.                if ( (data.flags & TH_SYN))   // UDP don't care about SYN... but it never reaches this...
  133.                   ptr->user[1] = 0;          // ok the connection is starting... collect user and pass...
  134.             }
  135.             if (ptr->proto == 'T')
  136.             {
  137.                if (ptr->flags & TH_RST)
  138.                   strcpy(ptr->status,  "KILLED");
  139.                else if (ptr->flags & TH_SYN)
  140.                   strcpy(ptr->status,  "OPENING");
  141.                else if (ptr->flags & TH_FIN)
  142.                   strcpy(ptr->status,  "CLOSING");
  143.                else if (ptr->flags & TH_PSH)
  144.                   strcpy(ptr->status,  "ACTIVE");
  145.                else
  146.                   if (!strcmp(ptr->status, "CLOSING"))     // FIN ACK
  147.                      strcpy(ptr->status,  "CLOSED");       // ACK
  148.                   else if (strcmp(ptr->status, "CLOSED"))
  149.                      strcpy(ptr->status,  "silent");
  150.             }
  151.             else if (ptr->proto == 'U')
  152.             {
  153.                strcpy(ptr->status,  "  UDP ");
  154.             }
  155.             if (strcmp(data.type, ""))
  156.                strcpy(ptr->type, data.type);
  157.             return number_of_connections;
  158.          }
  159.       }
  160.    }
  161.    if (!found)
  162.    {
  163.       #ifdef DEBUG
  164.          Debug_msg("Decodedata_MakeConnectionList - new node ! %d ! %c %s:%d - %s:%d ", num_conn, data.proto, data.ip_source, data.source_port, data.ip_dest, data.dest_port);
  165.       #endif
  166.       Conn_Between_Hosts = (CONNECTION *)realloc(Conn_Between_Hosts, num_conn*sizeof(CONNECTION));
  167.       if ( Conn_Between_Hosts == NULL )
  168.          Error_msg("ec_decodedata:%d realloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  169.       else
  170.          memset(&Conn_Between_Hosts[num_conn-1], 0, sizeof(CONNECTION));
  171.       memcpy(Conn_Between_Hosts[num_conn-1].ip_source, &data.ip_source, sizeof(data.ip_source));
  172.       memcpy(Conn_Between_Hosts[num_conn-1].ip_dest, &data.ip_dest, sizeof(data.ip_dest));
  173.       Inet_PutMACinString(Conn_Between_Hosts[num_conn-1].mac_source, data.mac_source);
  174.       Inet_PutMACinString(Conn_Between_Hosts[num_conn-1].mac_dest, data.mac_dest);
  175.       Conn_Between_Hosts[num_conn-1].source_port = data.source_port;
  176.       Conn_Between_Hosts[num_conn-1].dest_port = data.dest_port;
  177.       Conn_Between_Hosts[num_conn-1].proto = data.proto;
  178.       if (Conn_Between_Hosts[num_conn-1].proto == 'T')
  179.       {
  180.          Conn_Between_Hosts[num_conn-1].source_seq = data.source_seq;
  181.          Conn_Between_Hosts[num_conn-1].dest_seq = data.dest_seq;
  182.          Conn_Between_Hosts[num_conn-1].flags = data.flags;
  183.          if (Conn_Between_Hosts[num_conn-1].flags & TH_RST)
  184.             strcpy(Conn_Between_Hosts[num_conn-1].status, "KILLED");
  185.          else if (Conn_Between_Hosts[num_conn-1].flags & TH_FIN)
  186.             strcpy(Conn_Between_Hosts[num_conn-1].status, "CLOSING");
  187.          else if (Conn_Between_Hosts[num_conn-1].flags & TH_SYN)
  188.             strcpy(Conn_Between_Hosts[num_conn-1].status, "OPENING");
  189.          else if (Conn_Between_Hosts[num_conn-1].flags & TH_PSH)
  190.             strcpy(Conn_Between_Hosts[num_conn-1].status, "ACTIVE");
  191.          else
  192.             strcpy(Conn_Between_Hosts[num_conn-1].status, "silent");
  193.       }
  194.       else if (Conn_Between_Hosts[num_conn-1].proto == 'U')
  195.          strcpy(Conn_Between_Hosts[num_conn-1].status, "  UDP ");
  196.       if (strcmp(data.type, ""))
  197.          strcpy(Conn_Between_Hosts[num_conn-1].type, data.type);
  198.       else
  199.          strncpy(Conn_Between_Hosts[num_conn-1].type, Decodedata_GetType(Conn_Between_Hosts[num_conn-1].proto,
  200.                                                                          Conn_Between_Hosts[num_conn-1].source_port,
  201.                                                                          Conn_Between_Hosts[num_conn-1].dest_port),
  202.                                                                          18);
  203.       if (Conn_Between_Hosts[num_conn-1].proto == 'T')
  204.       {
  205.          if (!(Conn_Between_Hosts[num_conn-1].flags & TH_SYN))
  206.             Conn_Between_Hosts[num_conn-1].user[1] = -1;  // flag for the "waiting for syn"
  207.       }
  208.       else if (Conn_Between_Hosts[num_conn-1].proto == 'U')
  209.       {
  210.          if (strcmp(data.user, ""))
  211.          {
  212.             strtok(data.user, "n");
  213.             snprintf(Conn_Between_Hosts[num_conn-1].user, 30, "USER: %s", data.user);
  214.          }
  215.          if (strcmp(data.pass, ""))
  216.          {
  217.             strtok(data.pass, "n");
  218.             snprintf(Conn_Between_Hosts[num_conn-1].pass, 30, "PASS: %s", data.pass);
  219.          }
  220.          if (strcmp(data.info, "")) strncpy(Conn_Between_Hosts[num_conn-1].info, data.info, 100);
  221.       }
  222.    }
  223.    return num_conn;
  224. }
  225. int Decodedata_RefreshConnectionList(void)
  226. {
  227. #ifdef DEBUG
  228.    Debug_msg("Decodedata_RefreshConnectionList");
  229. #endif
  230.    if (Conn_Between_Hosts) free(Conn_Between_Hosts);
  231.    Conn_Between_Hosts = NULL;
  232.    number_of_connections = 0;
  233.    return 0;
  234. }
  235. char * Decodedata_GetHexData(char *buffer, int buff_len, short dimX)
  236. {
  237.    short octets;
  238.    for(octets = 0; octets < dimX; octets++)
  239.    {
  240.       if ( (octets*3.5 + 12) >= dimX ) break;
  241.    }
  242.    if (octets > 16) octets = 16;
  243.    if (octets % 2 == 1) octets--;
  244.    return Decodedata_GetEnhanchedHexData(buffer, buff_len, octets);
  245. }
  246. char * Decodedata_GetEnhanchedHexData(char *buffer, int buff_len, short cr)
  247. {
  248.    static char *hexdata;
  249.    int i, j, jm;
  250.    int c, dim = 0;
  251.    if (buff_len == 0) return "";
  252.    c = cr*3.5 + 11;
  253.    dim = c;
  254.    for (i = 0; i < buff_len; i++)   // approximately
  255.       if ( i % cr == 0)             // approximately
  256.          dim += c;                  // approximately
  257.    if (hexdata) free(hexdata);
  258.    if ( (hexdata = (char *)calloc(dim, sizeof(char))) == NULL)
  259.       Error_msg("ec_decodedata:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  260.    // adapted from dsniff by Dug Song <dugsong@monkey.org>
  261.    sprintf(hexdata,"n");
  262.    for (i = 0; i < buff_len; i += cr) {
  263.            sprintf(hexdata, "%s %04x: ", hexdata, i );
  264.            jm = buff_len - i;
  265.            jm = jm > cr ? cr : jm;
  266.            for (j = 0; j < jm; j++) {
  267.                    if ((j % 2) == 1) sprintf(hexdata,"%s%02x ", hexdata, (unsigned char) buffer[i+j]);
  268.                    else sprintf(hexdata,"%s%02x", hexdata, (unsigned char) buffer[i+j]);
  269.            }
  270.            for (; j < cr; j++) {
  271.                    if ((j % 2) == 1) strcat(hexdata,"   ");
  272.                    else strcat(hexdata,"  ");
  273.            }
  274.            strcat(hexdata," ");
  275.            for (j = 0; j < jm; j++) {
  276.                    c = buffer[i+j];
  277.                    c = isprint(c) ? c : '.';
  278.                    sprintf(hexdata,"%s%c", hexdata, c);
  279.            }
  280.            strcat(hexdata,"n");
  281.    }
  282.    return hexdata;
  283. }
  284. char * Decodedata_GetAsciiData(char *buffer, int buff_len)
  285. {
  286.    int i = 0;
  287.    if (buff_len == 0) return "";
  288.    for(i = 0; i < buff_len; i++)
  289.    {
  290.       if ( !( isprint((int)buffer[i]) || buffer[i] == 'n' || buffer[i] == 't') )
  291.          buffer[i] = '.';
  292.    }
  293.    return buffer;
  294. }
  295. char * Decodedata_TCPFlags(char flags)
  296. {
  297.    static char string[8];
  298.    char *p;
  299.    memset(string, 0, 8);
  300.    p = string;
  301.    if (flags & TH_ACK) *p++ = 'A';
  302.    if (flags & TH_PSH) *p++ = 'P';
  303.    if (flags & TH_RST) *p++ = 'R';
  304.    if (flags & TH_SYN) *p++ = 'S';
  305.    if (flags & TH_FIN) *p++ = 'F';
  306.    return string;
  307. }
  308. char * Decodedata_GetType(char proto, int port1, int port2)
  309. {
  310.    static char type[18];
  311.    database *d_index;
  312.    if (d_list == NULL)  // only the first time
  313.    {
  314.       FILE *f_ser;
  315.       char line[1024], desc[18], stype[4];
  316.       int port;
  317. #ifdef DEBUG
  318.    Debug_msg("Decodedata_GetType - loading from /etc/services");
  319. #endif
  320.       if ( (d_index = (database *)calloc(1,sizeof(database))) == NULL)
  321.          Error_msg("ec_decodedata:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  322.       d_list = d_index;
  323.       if (!(f_ser = fopen ("/etc/services", "r")))
  324.          Error_msg("ec_decodedata:%d fopen("/etc/services") | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  325.       while (fgets (line, 1024, f_ser))
  326.       {
  327.          if ((sscanf (line, "%16s%u/%s", desc, &port, stype) == 3) && (!strstr (desc, "#")) )
  328.          {
  329.             if ( (d_index->next = ( struct database *) calloc (1, sizeof(database))) == NULL)
  330.                Error_msg("ec_decodedata:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  331.             d_index->port = port;
  332.             if (strstr (stype, "tcp")) d_index->proto = 'T';
  333.             if (strstr (stype, "udp")) d_index->proto = 'U';
  334.             strcpy (d_index->desc, desc);
  335.             d_index = (database *) d_index->next;
  336.          }
  337.       }
  338.       fclose (f_ser);
  339.       d_index->next = NULL;
  340.    }
  341.    d_index = d_list;
  342.    for( ; d_index; d_index = (database *)d_index->next)
  343.    {
  344.       if ( d_index->proto == proto && (port1 == d_index->port || port2 == d_index->port) )
  345.       {
  346.          strcpy(type, d_index->desc);
  347.          return type;
  348.       }
  349.    }
  350.    return "";
  351. }
  352. /* EOF */