📄 log.c
字号:
/* $Id: log.c,v 1.26 2000/03/19 00:48:42 roesch Exp $ */
/*
** Copyright (C) 1998,1999,2000 Martin Roesch <roesch@clark.net>
**
** 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 "log.h"
extern OptTreeNode *otn_tmp; /* global ptr to current rule data */
char *data_dump_buffer; /* printout buffer for PrintNetData */
int dump_ready; /* flag to indicate status of printout buffer */
int dump_size;
static unsigned char ezero[6]; /* crap for ARP */
/****************************************************************************
*
* Function: OpenLogFile()
*
* Purpose: Create the log directory and file to put the packet log into.
* This function sucks, I've got to find a better way to do this
* this stuff.
*
* Arguments: None.
*
* Returns: 0 on success, exits on error
*
****************************************************************************/
int OpenLogFile(int mode, Packet *p)
{
char log_path[STD_BUF]; /* path to log file */
char log_file[STD_BUF]; /* name of log file */
char proto[5]; /* logged packet protocol */
/* zero out our buffers */
bzero((char *)log_path, STD_BUF);
bzero((char *)log_file, STD_BUF);
bzero((char *)proto, 5);
if(mode == NON_IP)
{
if(p->eh != NULL)
{
sprintf(log_file, "%s/NET_PROTO%d", pv.log_dir, ntohs(p->eh->ether_type));
}
else if(p->trhllc != NULL)
{
sprintf(log_file, "%s/NET_PROTO%d", pv.log_dir, ntohs(p->trhllc->ethertype));
}
else if(p->fddiiparp != NULL)
{
sprintf(log_file, "%s/NET_PROTO%d", pv.log_dir, ntohs(p->fddiiparp->ethertype));
}
if ((log_ptr = fopen(log_file, "a")) == NULL)
{
FatalError("ERROR: OpenLogFile() => fopen(%s) log file: %s\n",
log_file, strerror(errno));
}
return 0;
}
if (mode == ARP)
{
sprintf(log_file, "%s/ARP", pv.log_dir);
if ((log_ptr = fopen(log_file, "a")) == NULL)
{
FatalError("ERROR: OpenLogFile() => fopen(%s) log file: %s\n",
log_file, strerror(errno));
}
return 0;
}
if (otn_tmp != NULL)
{
if (otn_tmp->logto != NULL)
{
sprintf(log_file, "%s/%s", pv.log_dir, otn_tmp->logto);
if ((log_ptr = fopen(log_file, "a")) == NULL)
{
FatalError("ERROR: OpenLogFile() => fopen(%s) log file: %s\n", log_file, strerror(errno));
}
return 0;
}
}
/* figure out which way this packet is headed in relation to the homenet */
if ((p->iph->ip_dst.s_addr & pv.netmask) == pv.homenet)
{
if ((p->iph->ip_src.s_addr & pv.netmask) != pv.homenet)
{
sprintf(log_path, "%s/%s", pv.log_dir, inet_ntoa(p->iph->ip_src));
}
else
{
if ( p->sp >= p->dp )
{
sprintf(log_path, "%s/%s", pv.log_dir, inet_ntoa(p->iph->ip_src));
}
else
{
sprintf(log_path, "%s/%s", pv.log_dir, inet_ntoa(p->iph->ip_dst));
}
}
}
else
{
if ((p->iph->ip_src.s_addr & pv.netmask) == pv.homenet)
{
sprintf(log_path, "%s/%s", pv.log_dir, inet_ntoa(p->iph->ip_dst));
}
else
{
if (p->sp >= p->dp)
{
sprintf(log_path, "%s/%s", pv.log_dir, inet_ntoa(p->iph->ip_src));
}
else
{
sprintf(log_path, "%s/%s", pv.log_dir, inet_ntoa(p->iph->ip_dst));
}
}
}
#ifdef DEBUG
ErrorMessage( "Creating directory: %s\n",log_path);
#endif
/* build the log directory */
if (mkdir(log_path,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
{
#ifdef DEBUG
if (errno != EEXIST)
{
printf("Problem creating directory %s\n",log_path);
}
#endif
}
#ifdef DEBUG
printf("Directory Created!\n");
#endif
/* build the log filename */
if(!p->frag_flag)
{
switch(p->iph->ip_proto)
{
case IPPROTO_TCP:
case IPPROTO_UDP:
if (p->sp >= p->dp)
{
sprintf(log_file, "%s/%s:%d-%d", log_path,
protocol_names[p->iph->ip_proto], p->sp, p->dp);
}
else
{
sprintf(log_file, "%s/%s:%d-%d", log_path,
protocol_names[p->iph->ip_proto], p->dp, p->sp);
}
break;
case IPPROTO_ICMP:
sprintf(log_file, "%s/%s_%s", log_path, "ICMP", IcmpFileName(p));
break;
default:
sprintf(log_file, "%s/XPORT_PROTO%d", log_path, p->iph->ip_proto);
break;
}
}
else
{
sprintf(log_file, "%s/IP_FRAG", log_path);
}
#ifdef DEBUG
printf("Opening file: %s\n", log_file);
#endif
/* finally open the log file */
if ((log_ptr = fopen(log_file, "a")) == NULL)
{
FatalError("ERROR: OpenLogFile() => fopen(%s) log file: %s\n",
log_file, strerror(errno));
}
#ifdef DEBUG
printf("File opened...\n");
#endif
return 0;
}
/****************************************************************************
*
* Function: PrintNetData(FILE *, char *,int)
*
* Purpose: Do a side by side dump of a buffer, hex dump of buffer bytes on
* the left, decoded ASCII on the right.
*
* Arguments: fp => ptr to stream to print to
* start => pointer to buffer data
* len => length of data buffer
*
* Returns: void function
*
****************************************************************************/
void PrintNetData(FILE *fp, u_char *start, const u_int len)
{
u_char *end; /* ptr to buffer end */
int i; /* counter */
int j = 0; /* counter */
int dbuf_size; /* data buffer size */
int done; /* flag */
u_char *data; /* index pointer */
/*int byte_offset=0;*/
char *frame_ptr; /* we use 66 byte frames for a printed line */
char *d_ptr; /* data pointer into the frame */
char *c_ptr; /* char pointer into the frame */
char conv[] = "0123456789ABCDEF"; /* xlation lookup table */
/* initialization */
done = 0;
if (start == NULL)
{
#ifdef DEBUG
printf("Got NULL ptr in PrintNetData()\n");
#endif
return;
}
/* zero, print a <CR> and get out */
if (!len)
{
fputc('\n', fp);
return;
}
/* if we've already prepared this particular data buffer, just print it
out again to save time */
if (dump_ready)
{
fwrite(data_dump_buffer, dump_size, 1, fp);
fflush(fp);
return;
}
end = start + (len-1); /* set the end of buffer ptr */
if (len > ETHERNET_MTU)
{
if(pv.verbose_flag)
{
printf("Got bogus buffer length (%d) for PrintNetData, defaulting to 16 bytes!\n", len);
}
if(pv.verbose_bytedump_flag == 1)
{
dbuf_size = (FRAME_SIZE + 8) + (FRAME_SIZE + 8) + 1;
}
else
{
dbuf_size = FRAME_SIZE + FRAME_SIZE + 1;
}
/*dbuf_size = 66 + 67;*/
end = start + 32;
}
else
{
if(pv.verbose_bytedump_flag == 1)
{
/* figure out how big the printout data buffer has to be */
dbuf_size = ((len / 16) * (FRAME_SIZE + 8)) + (FRAME_SIZE + 8) + 1;
}
else
{
/* figure out how big the printout data buffer has to be */
dbuf_size = ((len / 16) * FRAME_SIZE) + FRAME_SIZE + 1;
}
/*dbuf_size = ((len/16) * 66) + 67;*/
}
/* generate the buffer */
data_dump_buffer = (char *) malloc(dbuf_size);
/* make sure it got allocated properly */
if (data_dump_buffer == NULL)
{
ErrorMessage( "Failed allocating 0x%X bytes! (Length: %X)\n",
dbuf_size, len);
perror("PrintNetData()");
CleanExit(SIGQUIT);
}
/* clean it out */
memset(data_dump_buffer, 0x20, dbuf_size);
/* set the byte buffer pointer to step thru the data buffer */
data = start;
/* set the frame pointer to the start of the printout buffer */
frame_ptr = data_dump_buffer;
/* loop thru the whole buffer */
while (!done)
{
/* initialize counters and frame index pointers */
i = 0;
if(pv.verbose_bytedump_flag == 1)
{
d_ptr = frame_ptr + 8;
c_ptr = (frame_ptr + 8 + C_OFFSET);
sprintf(frame_ptr, "0x%04X: ", j);
j += 16;
}
else
{
d_ptr = frame_ptr;
c_ptr = (frame_ptr + C_OFFSET);
}
/* process 16 bytes per frame */
for (i=0; i<16; i++)
{
/* look up the ASCII value of the first nybble of the
current data buffer */
*d_ptr = conv[((*data&0xFF) >> 4)];
d_ptr++;
/* look up the second nybble */
*d_ptr = conv[((*data&0xFF)&0x0F)];
d_ptr++;
/* put a space in between */
*d_ptr = 0x20;
d_ptr++;
/* print out the char equivalent */
if (*data > 0x1F && *data < 0x7F)
*c_ptr = (*data&0xFF);
else
*c_ptr = 0x2E;
c_ptr++;
/* increment the pointer or finish up */
if (data < end)
data++;
else
{
/* finish up the buffer printout and set the "ready" flags */
done = 1;
dump_ready = 1;
*c_ptr='\n';
c_ptr++;
*c_ptr='\n';
c_ptr++;
*c_ptr = 0;
dump_size = (int) (c_ptr - data_dump_buffer);
fwrite(data_dump_buffer, dump_size, 1, fp);
return;
}
}
*c_ptr = '\n';
if(pv.verbose_bytedump_flag == 1)
{
frame_ptr += (FRAME_SIZE + 8);
}
else
{
frame_ptr += FRAME_SIZE;
}
}
}
void PrintCharData(FILE *fp, u_char *data, int data_len)
{
int bytes_processed;
int linecount = 0;
u_char *index;
char *ddb_ptr;
if (data == NULL)
{
return;
}
if (dump_ready)
{
fwrite(data_dump_buffer, dump_size, 1, fp);
fflush(fp);
return;
}
bytes_processed = data_len;
index = data;
data_dump_buffer = (char *) calloc(data_len + (data_len >> 6) + 2, sizeof(char));
ddb_ptr = data_dump_buffer;
while (bytes_processed)
{
if (*index > 0x1F && *index < 0x7F)
{
*ddb_ptr = *index;
}
else
{
*ddb_ptr = '.';
}
if (++linecount == 64)
{
ddb_ptr++;
*ddb_ptr = '\n';
linecount = 0;
}
ddb_ptr++;
index++;
bytes_processed--;
}
ddb_ptr++;
*ddb_ptr = '\n';
ddb_ptr++;
dump_ready = 1;
dump_size = (int) (ddb_ptr - data_dump_buffer);
fwrite(data_dump_buffer, dump_size, 1, fp);
}
/****************************************************************************
*
* Function: PrintIPPkt(FILE *, int, char *, int)
*
* Purpose: Dump the packet to the stream pointer
*
* Arguments: fp => pointer to print data to
* type => packet protocol
* data_ptr => pointer to the application layer data
* data_len => size of the app layer data
*
* Returns: void function
*
****************************************************************************/
void PrintIPPkt(FILE *fp, int type, Packet *p)
{
char timestamp[23];
#ifdef DEBUG
printf("PrintIPPkt type = %d\n", type);
#endif
bzero((char *)timestamp, 23);
ts_print((struct timeval*)&p->pkth->ts, timestamp);
/* dump the timestamp */
fwrite(timestamp, 22, 1, fp);
/* dump the ethernet header if we're doing that sort of thing */
if (pv.show2hdr_flag)
{
Print2ndHeader(fp, p);
}
/* etc */
PrintIPHeader(fp, p);
/*if this isn't a fragment, print the other header info */
if (!p->frag_flag)
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
if(p->tcph != NULL)
PrintTCPHeader(fp, p);
else
PrintNetData(fp, p->pkt, p->pkth->caplen);
break;
case IPPROTO_UDP:
if(p->udph != NULL)
PrintUDPHeader(fp, p);
else
PrintNetData(fp, p->pkt, p->pkth->caplen);
break;
case IPPROTO_ICMP:
if(p->icmph != NULL)
PrintICMPHeader(fp, p);
else
PrintNetData(fp, p->pkt, p->pkth->caplen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -