ec_decodedata.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:13k
- /*
- ettercap -- data decoding module
- Copyright (C) 2001 ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include "include/ec_main.h"
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #ifdef HAVE_CTYPE_H
- #include <ctype.h>
- #endif
- #include "include/ec_inet_structures.h"
- #include "include/ec_inet.h"
- #include "include/ec_error.h"
- #ifdef DEBUG
- #include "include/ec_debug.h"
- #endif
- typedef struct
- {
- int port;
- char proto;
- char desc[18];
- struct database *next;
- } database;
- database *d_list = NULL;
- #ifndef HAVE_CTYPE_H
- int isprint(int c);
- #endif
- int Decodedata_MakeConnectionList(CONNECTION data);
- int Decodedata_RefreshConnectionList(void);
- char * Decodedata_GetType(char proto, int port1, int port2);
- char * Decodedata_GetAsciiData(char *buffer, int buff_len);
- char * Decodedata_GetHexData(char *buffer, int buff_len, short dimX);
- char * Decodedata_GetEnhanchedHexData(char *buffer, int buff_len, short cr);
- char * Decodedata_TCPFlags(char flags);
- //--------------------------
- #ifndef HAVE_CTYPE_H
- int isprint(int c)
- {
- return ( (c>31 && c<127) ? 1 : 0 );
- }
- #endif
- int Decodedata_MakeConnectionList(CONNECTION data)
- {
- int num_conn = 1;
- char filter[45];
- char cur_conn[45];
- char rev_cur_conn[45];
- char found = 0;
- CONNECTION *ptr;
- sprintf(filter, "%c%s%d%s%d", data.proto, data.ip_source, data.source_port, data.ip_dest, data.dest_port);
- if (number_of_connections == 0)
- {
- found = 0;
- }
- else
- {
- for(ptr=Conn_Between_Hosts; num_conn <= number_of_connections; ptr++)
- {
- sprintf(cur_conn, "%c%s%d%s%d", ptr->proto, ptr->ip_source, ptr->source_port, ptr->ip_dest, ptr->dest_port);
- sprintf(rev_cur_conn, "%c%s%d%s%d", ptr->proto, ptr->ip_dest, ptr->dest_port, ptr->ip_source, ptr->source_port);
- num_conn++;
- if (!strcmp(filter, cur_conn))
- {
- if (ptr->proto == 'T')
- {
- ptr->source_seq = data.source_seq;
- ptr->flags = data.flags;
- }
- found = 1;
- }
- if (!strcmp(filter, rev_cur_conn))
- {
- if (ptr->proto == 'T')
- {
- ptr->dest_seq = data.dest_seq;
- ptr->flags = data.flags;
- }
- found = 1;
- }
- if (found)
- {
- if (ptr->user[1] != -1) // waiting for syn
- {
- if ( ptr->user[0] == 0 ) // the string is under construction
- {
- strncpy(ptr->user + 1 + strlen(ptr->user+1), data.user, 29 - strlen(ptr->user+1) );
- if (strchr(data.user, 'n'))
- {
- char str[30];
- ptr->user[0] = ' ';
- strtok(ptr->user, "n");
- if ( data.dest_port == 23 || data.source_port == 23 ||
- data.dest_port == 513 || data.source_port == 513 )
- data.pass[0] = 0; // evil workaround for telnet... we assume that pass always come AFTER login
- snprintf(str, 30, "USER:%s", ptr->user);
- strcpy(ptr->user, str);
- }
- }
- if ( ptr->user[0] != 0 && ptr->pass[0] == 0 ) // the string is under construction
- {
- strncpy(ptr->pass + 1 + strlen(ptr->pass+1), data.pass, 29 - strlen(ptr->pass+1) );
- if (strchr(data.pass, 'n'))
- {
- char str[30];
- ptr->pass[0] = ' ';
- strtok(ptr->pass, "n");
- snprintf(str, 30, "PASS:%s", ptr->pass);
- strcpy(ptr->pass, str);
- }
- }
- //if ( ptr->info[0] == 0)
- {
- if (strlen(data.info) && !strchr(ptr->info, 'n'))
- strlcat(ptr->info, data.info, 100);
- }
- }
- else
- {
- if ( (data.flags & TH_SYN)) // UDP don't care about SYN... but it never reaches this...
- ptr->user[1] = 0; // ok the connection is starting... collect user and pass...
- }
- if (ptr->proto == 'T')
- {
- if (ptr->flags & TH_RST)
- strcpy(ptr->status, "KILLED");
- else if (ptr->flags & TH_SYN)
- strcpy(ptr->status, "OPENING");
- else if (ptr->flags & TH_FIN)
- strcpy(ptr->status, "CLOSING");
- else if (ptr->flags & TH_PSH)
- strcpy(ptr->status, "ACTIVE");
- else
- if (!strcmp(ptr->status, "CLOSING")) // FIN ACK
- strcpy(ptr->status, "CLOSED"); // ACK
- else if (strcmp(ptr->status, "CLOSED"))
- strcpy(ptr->status, "silent");
- }
- else if (ptr->proto == 'U')
- {
- strcpy(ptr->status, " UDP ");
- }
- if (strcmp(data.type, ""))
- strcpy(ptr->type, data.type);
- return number_of_connections;
- }
- }
- }
- if (!found)
- {
- #ifdef DEBUG
- 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);
- #endif
- Conn_Between_Hosts = (CONNECTION *)realloc(Conn_Between_Hosts, num_conn*sizeof(CONNECTION));
- if ( Conn_Between_Hosts == NULL )
- Error_msg("ec_decodedata:%d realloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- else
- memset(&Conn_Between_Hosts[num_conn-1], 0, sizeof(CONNECTION));
- memcpy(Conn_Between_Hosts[num_conn-1].ip_source, &data.ip_source, sizeof(data.ip_source));
- memcpy(Conn_Between_Hosts[num_conn-1].ip_dest, &data.ip_dest, sizeof(data.ip_dest));
- Inet_PutMACinString(Conn_Between_Hosts[num_conn-1].mac_source, data.mac_source);
- Inet_PutMACinString(Conn_Between_Hosts[num_conn-1].mac_dest, data.mac_dest);
- Conn_Between_Hosts[num_conn-1].source_port = data.source_port;
- Conn_Between_Hosts[num_conn-1].dest_port = data.dest_port;
- Conn_Between_Hosts[num_conn-1].proto = data.proto;
- if (Conn_Between_Hosts[num_conn-1].proto == 'T')
- {
- Conn_Between_Hosts[num_conn-1].source_seq = data.source_seq;
- Conn_Between_Hosts[num_conn-1].dest_seq = data.dest_seq;
- Conn_Between_Hosts[num_conn-1].flags = data.flags;
- if (Conn_Between_Hosts[num_conn-1].flags & TH_RST)
- strcpy(Conn_Between_Hosts[num_conn-1].status, "KILLED");
- else if (Conn_Between_Hosts[num_conn-1].flags & TH_FIN)
- strcpy(Conn_Between_Hosts[num_conn-1].status, "CLOSING");
- else if (Conn_Between_Hosts[num_conn-1].flags & TH_SYN)
- strcpy(Conn_Between_Hosts[num_conn-1].status, "OPENING");
- else if (Conn_Between_Hosts[num_conn-1].flags & TH_PSH)
- strcpy(Conn_Between_Hosts[num_conn-1].status, "ACTIVE");
- else
- strcpy(Conn_Between_Hosts[num_conn-1].status, "silent");
- }
- else if (Conn_Between_Hosts[num_conn-1].proto == 'U')
- strcpy(Conn_Between_Hosts[num_conn-1].status, " UDP ");
- if (strcmp(data.type, ""))
- strcpy(Conn_Between_Hosts[num_conn-1].type, data.type);
- else
- strncpy(Conn_Between_Hosts[num_conn-1].type, Decodedata_GetType(Conn_Between_Hosts[num_conn-1].proto,
- Conn_Between_Hosts[num_conn-1].source_port,
- Conn_Between_Hosts[num_conn-1].dest_port),
- 18);
- if (Conn_Between_Hosts[num_conn-1].proto == 'T')
- {
- if (!(Conn_Between_Hosts[num_conn-1].flags & TH_SYN))
- Conn_Between_Hosts[num_conn-1].user[1] = -1; // flag for the "waiting for syn"
- }
- else if (Conn_Between_Hosts[num_conn-1].proto == 'U')
- {
- if (strcmp(data.user, ""))
- {
- strtok(data.user, "n");
- snprintf(Conn_Between_Hosts[num_conn-1].user, 30, "USER: %s", data.user);
- }
- if (strcmp(data.pass, ""))
- {
- strtok(data.pass, "n");
- snprintf(Conn_Between_Hosts[num_conn-1].pass, 30, "PASS: %s", data.pass);
- }
- if (strcmp(data.info, "")) strncpy(Conn_Between_Hosts[num_conn-1].info, data.info, 100);
- }
- }
- return num_conn;
- }
- int Decodedata_RefreshConnectionList(void)
- {
- #ifdef DEBUG
- Debug_msg("Decodedata_RefreshConnectionList");
- #endif
- if (Conn_Between_Hosts) free(Conn_Between_Hosts);
- Conn_Between_Hosts = NULL;
- number_of_connections = 0;
- return 0;
- }
- char * Decodedata_GetHexData(char *buffer, int buff_len, short dimX)
- {
- short octets;
- for(octets = 0; octets < dimX; octets++)
- {
- if ( (octets*3.5 + 12) >= dimX ) break;
- }
- if (octets > 16) octets = 16;
- if (octets % 2 == 1) octets--;
- return Decodedata_GetEnhanchedHexData(buffer, buff_len, octets);
- }
- char * Decodedata_GetEnhanchedHexData(char *buffer, int buff_len, short cr)
- {
- static char *hexdata;
- int i, j, jm;
- int c, dim = 0;
- if (buff_len == 0) return "";
- c = cr*3.5 + 11;
- dim = c;
- for (i = 0; i < buff_len; i++) // approximately
- if ( i % cr == 0) // approximately
- dim += c; // approximately
- if (hexdata) free(hexdata);
- if ( (hexdata = (char *)calloc(dim, sizeof(char))) == NULL)
- Error_msg("ec_decodedata:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- // adapted from dsniff by Dug Song <dugsong@monkey.org>
- sprintf(hexdata,"n");
- for (i = 0; i < buff_len; i += cr) {
- sprintf(hexdata, "%s %04x: ", hexdata, i );
- jm = buff_len - i;
- jm = jm > cr ? cr : jm;
- for (j = 0; j < jm; j++) {
- if ((j % 2) == 1) sprintf(hexdata,"%s%02x ", hexdata, (unsigned char) buffer[i+j]);
- else sprintf(hexdata,"%s%02x", hexdata, (unsigned char) buffer[i+j]);
- }
- for (; j < cr; j++) {
- if ((j % 2) == 1) strcat(hexdata," ");
- else strcat(hexdata," ");
- }
- strcat(hexdata," ");
- for (j = 0; j < jm; j++) {
- c = buffer[i+j];
- c = isprint(c) ? c : '.';
- sprintf(hexdata,"%s%c", hexdata, c);
- }
- strcat(hexdata,"n");
- }
- return hexdata;
- }
- char * Decodedata_GetAsciiData(char *buffer, int buff_len)
- {
- int i = 0;
- if (buff_len == 0) return "";
- for(i = 0; i < buff_len; i++)
- {
- if ( !( isprint((int)buffer[i]) || buffer[i] == 'n' || buffer[i] == 't') )
- buffer[i] = '.';
- }
- return buffer;
- }
- char * Decodedata_TCPFlags(char flags)
- {
- static char string[8];
- char *p;
- memset(string, 0, 8);
- p = string;
- if (flags & TH_ACK) *p++ = 'A';
- if (flags & TH_PSH) *p++ = 'P';
- if (flags & TH_RST) *p++ = 'R';
- if (flags & TH_SYN) *p++ = 'S';
- if (flags & TH_FIN) *p++ = 'F';
- return string;
- }
- char * Decodedata_GetType(char proto, int port1, int port2)
- {
- static char type[18];
- database *d_index;
- if (d_list == NULL) // only the first time
- {
- FILE *f_ser;
- char line[1024], desc[18], stype[4];
- int port;
- #ifdef DEBUG
- Debug_msg("Decodedata_GetType - loading from /etc/services");
- #endif
- if ( (d_index = (database *)calloc(1,sizeof(database))) == NULL)
- Error_msg("ec_decodedata:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- d_list = d_index;
- if (!(f_ser = fopen ("/etc/services", "r")))
- Error_msg("ec_decodedata:%d fopen("/etc/services") | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- while (fgets (line, 1024, f_ser))
- {
- if ((sscanf (line, "%16s%u/%s", desc, &port, stype) == 3) && (!strstr (desc, "#")) )
- {
- if ( (d_index->next = ( struct database *) calloc (1, sizeof(database))) == NULL)
- Error_msg("ec_decodedata:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- d_index->port = port;
- if (strstr (stype, "tcp")) d_index->proto = 'T';
- if (strstr (stype, "udp")) d_index->proto = 'U';
- strcpy (d_index->desc, desc);
- d_index = (database *) d_index->next;
- }
- }
- fclose (f_ser);
- d_index->next = NULL;
- }
- d_index = d_list;
- for( ; d_index; d_index = (database *)d_index->next)
- {
- if ( d_index->proto == proto && (port1 == d_index->port || port2 == d_index->port) )
- {
- strcpy(type, d_index->desc);
- return type;
- }
- }
- return "";
- }
- /* EOF */