Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1682 lines (1459 sloc) 51.315 kb
/* $Id$ */
/*
** Copyright (C) 2002-2009 Sourcefire, Inc.
** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License Version 2 as
** published by the Free Software Foundation. You may not use, modify or
** distribute this program under any other version of the GNU General
** Public License.
**
** 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif /* !WIN32 */
#include <errno.h>
#include <signal.h>
#include "log.h"
#include "util.h"
#include "debug.h"
#include "barnyard2.h"
#include "log_text.h"
#ifdef SUP_IP6
#include "sfutil/sf_ip.h"
#endif
//extern OptTreeNode *otn_tmp; /* global ptr to current rule data */
/*--------------------------------------------------------------------
* utility functions
*--------------------------------------------------------------------
*/
void LogTimeStamp(TextLog* log, Packet* p)
{
char timestamp[TIMEBUF_SIZE];
ts_print((struct timeval*)&p->pkth->ts, timestamp);
TextLog_Puts(log, timestamp);
}
/*--------------------------------------------------------------------
* alert stuff cloned from log.c
*--------------------------------------------------------------------
*/
/*--------------------------------------------------------------------
* Function: LogPriorityData()
*
* Purpose: Prints out priority data associated with an alert
*
* Arguments: log => pointer to TextLog to write the data to
* doNewLine => tack a \n to the end of the line or not (bool)
*
* Returns: void function
*--------------------------------------------------------------------
*/
void LogPriorityData(TextLog* log, uint32_t classification_id, uint32_t priority_id, bool doNewLine)
{
ClassType *cn = ClassTypeLookupById(barnyard2_conf, classification_id);
if ( cn != NULL )
{
TextLog_Print(
log, "[Classification: %s] [Priority: %d] ",
cn->name, cn->priority
);
}
else
{
TextLog_Print(
log, "[Classification ID: %s] [Priority ID: %d] ",
classification_id, priority_id
);
}
if ( doNewLine )
TextLog_NewLine(log);
}
/*--------------------------------------------------------------------
* Layer 2 header stuff cloned from log.c
*--------------------------------------------------------------------
*/
#ifndef NO_NON_ETHER_DECODER
/*--------------------------------------------------------------------
* Function: LogTrHeader(TextLog*, Packet*)
*
* Purpose: Print the packet TokenRing header to the given TextLog
*
* Arguments: log => pointer to TextLog to print to
*
* Returns: void function
*--------------------------------------------------------------------
*/
void LogTrHeader(TextLog* log, Packet* p)
{
TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0],
p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3],
p->trh->saddr[4], p->trh->saddr[5]);
TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0],
p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3],
p->trh->daddr[4], p->trh->daddr[5]);
TextLog_Print(log, "access control:0x%X frame control:0x%X\n", p->trh->ac,
p->trh->fc);
if(!p->trhllc)
return;
TextLog_Print(log, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n",
p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0],
p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype);
if(p->trhmr)
{
TextLog_Print(log, "RIF structure is present:\n");
TextLog_Print(log, "bcast: 0x%X length: 0x%X direction: 0x%X largest"
"fr. size: 0x%X res: 0x%X\n",
TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr),
TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr),
TRH_MR_RES(p->trhmr));
TextLog_Print(log, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n",
p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2],
p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5],
p->trhmr->rseg[6], p->trhmr->rseg[7]);
}
}
#endif // NO_NON_ETHER_DECODER
/*--------------------------------------------------------------------
* Function: LogEthHeader()
*
* Purpose: Print the packet Ethernet header to the given TextLog
*
* Arguments: log => pointer to TextLog to print to
*
* Returns: void function
*--------------------------------------------------------------------
*/
static void LogEthHeader(TextLog* log, Packet* p)
{
/* src addr */
TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", p->eh->ether_src[0],
p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3],
p->eh->ether_src[4], p->eh->ether_src[5]);
/* dest addr */
TextLog_Print(log, "%X:%X:%X:%X:%X:%X ", p->eh->ether_dst[0],
p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3],
p->eh->ether_dst[4], p->eh->ether_dst[5]);
/* protocol and pkt size */
TextLog_Print(log, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->len);
}
#ifdef MPLS
static void LogMPLSHeader(TextLog* log, Packet* p)
{
TextLog_Print(log,"label:0x%05X exp:0x%X bos:0x%X ttl:0x%X\n",
p->mplsHdr.label, p->mplsHdr.exp, p->mplsHdr.bos, p->mplsHdr.ttl);
}
#endif
#ifndef NO_NON_ETHER_DECODER
/*--------------------------------------------------------------------
* Function: LogSLLHeader(TextLog* )
*
* Purpose: Print the packet SLL (fake) header to the given TextLog
* (piece partly is borrowed from tcpdump :))
*
* Arguments: log => pointer to TextLog to print to
*
* Returns: void function
*--------------------------------------------------------------------
*/
#ifdef DLT_LINUX_SLL
static void LogSLLHeader(TextLog* log, Packet* p)
{
switch (ntohs(p->sllh->sll_pkttype)) {
case LINUX_SLL_HOST:
TextLog_Puts(log, "< ");
break;
case LINUX_SLL_BROADCAST:
TextLog_Puts(log, "B ");
break;
case LINUX_SLL_MULTICAST:
TextLog_Puts(log, "M ");
break;
case LINUX_SLL_OTHERHOST:
TextLog_Puts(log, "P ");
break;
case LINUX_SLL_OUTGOING:
TextLog_Puts(log, "> ");
break;
default:
TextLog_Puts(log, "? ");
break;
}
/* mac addr */
TextLog_Print(log, "l/l len: %i l/l type: 0x%X %X:%X:%X:%X:%X:%X\n",
htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype),
p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2],
p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]);
/* protocol and pkt size */
TextLog_Print(log, "pkt type:0x%X proto: 0x%X len:0x%X\n",
ntohs(p->sllh->sll_pkttype),
ntohs(p->sllh->sll_protocol), p->pkth->len);
}
#endif
/*--------------------------------------------------------------------
* Function: LogWifiHeader(TextLog* )
*
* Purpose: Print the packet 802.11 header to the given TextLog
*
* Arguments: log => pointer to TextLog to print to
*
* Returns: void function
*--------------------------------------------------------------------
*/
static void LogWifiHeader(TextLog* log, Packet * p)
{
/* This assumes we are printing a data packet, could be changed
to print other types as well */
const u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL,
*ta = NULL;
/* per table 4, IEEE802.11 section 7.2.2 */
if ((p->wifih->frame_control & WLAN_FLAG_TODS) &&
(p->wifih->frame_control & WLAN_FLAG_FROMDS)) {
ra = p->wifih->addr1;
ta = p->wifih->addr2;
da = p->wifih->addr3;
sa = p->wifih->addr4;
}
else if (p->wifih->frame_control & WLAN_FLAG_TODS) {
bssid = p->wifih->addr1;
sa = p->wifih->addr2;
da = p->wifih->addr3;
}
else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) {
da = p->wifih->addr1;
bssid = p->wifih->addr2;
sa = p->wifih->addr3;
}
else {
da = p->wifih->addr1;
sa = p->wifih->addr2;
bssid = p->wifih->addr3;
}
/* DO this switch to provide additional info on the type */
switch(p->wifih->frame_control & 0x00ff)
{
case WLAN_TYPE_MGMT_BEACON:
TextLog_Puts(log, "Beacon ");
break;
/* management frames */
case WLAN_TYPE_MGMT_ASREQ:
TextLog_Puts(log, "Assoc. Req. ");
break;
case WLAN_TYPE_MGMT_ASRES:
TextLog_Puts(log, "Assoc. Resp. ");
break;
case WLAN_TYPE_MGMT_REREQ:
TextLog_Puts(log, "Reassoc. Req. ");
break;
case WLAN_TYPE_MGMT_RERES:
TextLog_Puts(log, "Reassoc. Resp. ");
break;
case WLAN_TYPE_MGMT_PRREQ:
TextLog_Puts(log, "Probe Req. ");
break;
case WLAN_TYPE_MGMT_PRRES:
TextLog_Puts(log, "Probe Resp. ");
break;
case WLAN_TYPE_MGMT_ATIM:
TextLog_Puts(log, "ATIM ");
break;
case WLAN_TYPE_MGMT_DIS:
TextLog_Puts(log, "Dissassoc. ");
break;
case WLAN_TYPE_MGMT_AUTH:
TextLog_Puts(log, "Authent. ");
break;
case WLAN_TYPE_MGMT_DEAUTH:
TextLog_Puts(log, "Deauthent. ");
break;
/* Control frames */
case WLAN_TYPE_CONT_PS:
case WLAN_TYPE_CONT_RTS:
case WLAN_TYPE_CONT_CTS:
case WLAN_TYPE_CONT_ACK:
case WLAN_TYPE_CONT_CFE:
case WLAN_TYPE_CONT_CFACK:
TextLog_Puts(log, "Control ");
break;
}
if (sa != NULL) {
TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", sa[0],
sa[1], sa[2], sa[3], sa[4], sa[5]);
}
else if (ta != NULL) {
TextLog_Print(log, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0],
ta[1], ta[2], ta[3], ta[4], ta[5]);
}
TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", da[0],
da[1], da[2], da[3], da[4], da[5]);
if (bssid != NULL)
{
TextLog_Print(log, "bssid: %X:%X:%X:%X:%X:%X", bssid[0],
bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
}
if (ra != NULL) {
TextLog_Print(log, " ra: %X:%X:%X:%X:%X:%X", ra[0],
ra[1], ra[2], ra[3], ra[4], ra[5]);
}
TextLog_Puts(log, " Flags:");
if (p->wifih->frame_control & WLAN_FLAG_TODS) TextLog_Puts(log," ToDs");
if (p->wifih->frame_control & WLAN_FLAG_TODS) TextLog_Puts(log," FrDs");
if (p->wifih->frame_control & WLAN_FLAG_FRAG) TextLog_Puts(log," Frag");
if (p->wifih->frame_control & WLAN_FLAG_RETRY) TextLog_Puts(log," Re");
if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) TextLog_Puts(log," Pwr");
if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) TextLog_Puts(log," MD");
if (p->wifih->frame_control & WLAN_FLAG_WEP) TextLog_Puts(log," Wep");
if (p->wifih->frame_control & WLAN_FLAG_ORDER) TextLog_Puts(log," Ord");
TextLog_NewLine(log);
}
#endif // NO_NON_ETHER_DECODER
/*--------------------------------------------------------------------
* Function: Log2ndHeader(TextLog* , Packet p)
*
* Purpose: Log2ndHeader -- prints second layber header info.
*
* Arguments: log => pointer to TextLog to print to
*
* Returns: void function
*--------------------------------------------------------------------
*/
void Log2ndHeader(TextLog* log, Packet* p)
{
switch(datalink)
{
case DLT_EN10MB: /* Ethernet */
if(p && p->eh)
LogEthHeader(log, p);
break;
#ifndef NO_NON_ETHER_DECODER
#ifdef DLT_IEEE802_11
case DLT_IEEE802_11:
if(p && p->wifih)
LogWifiHeader(log, p);
break;
#endif
case DLT_IEEE802: /* Token Ring */
if(p && p->trh)
LogTrHeader(log, p);
break;
#ifdef DLT_LINUX_SLL
case DLT_LINUX_SLL:
if (p && p->sllh)
LogSLLHeader(log, p); /* Linux cooked sockets */
break;
#endif
#endif // NO_NON_ETHER_DECODER
default:
if (BcLogVerbose())
{
ErrorMessage("Datalink %i type 2nd layer display is not "
"supported\n", datalink);
}
}
}
/*-------------------------------------------------------------------
* IP stuff cloned from log.c
*-------------------------------------------------------------------
*/
static void LogIpOptions(TextLog* log, Packet * p)
{
int i;
int j;
u_long init_offset;
u_long print_offset;
init_offset = TextLog_Tell(log);
if(!p->ip_option_count || p->ip_option_count > 40)
return;
TextLog_Print(log, "IP Options (%d) => ", p->ip_option_count);
for(i = 0; i < (int) p->ip_option_count; i++)
{
print_offset = TextLog_Tell(log);
if((print_offset - init_offset) > 60)
{
TextLog_Puts(log, "\nIP Options => ");
init_offset = TextLog_Tell(log);
}
switch(p->ip_options[i].code)
{
case IPOPT_RR:
TextLog_Puts(log, "RR ");
break;
case IPOPT_EOL:
TextLog_Puts(log, "EOL ");
break;
case IPOPT_NOP:
TextLog_Puts(log, "NOP ");
break;
case IPOPT_TS:
TextLog_Puts(log, "TS ");
break;
case IPOPT_ESEC:
TextLog_Puts(log, "ESEC ");
break;
case IPOPT_SECURITY:
TextLog_Puts(log, "SEC ");
break;
case IPOPT_LSRR:
case IPOPT_LSRR_E:
TextLog_Puts(log, "LSRR ");
break;
case IPOPT_SATID:
TextLog_Puts(log, "SID ");
break;
case IPOPT_SSRR:
TextLog_Puts(log, "SSRR ");
break;
case IPOPT_RTRALT:
TextLog_Puts(log, "RTRALT ");
break;
default:
TextLog_Print(log, "Opt %d: ", p->ip_options[i].code);
if(p->ip_options[i].len)
{
for(j = 0; j < p->ip_options[i].len; j++)
{
if (p->ip_options[i].data)
TextLog_Print(log, "%02X", p->ip_options[i].data[j]);
else
TextLog_Print(log, "%02X", 0);
if((j % 2) == 0)
TextLog_Putc(log, ' ');
}
}
break;
}
}
TextLog_NewLine(log);
}
/*--------------------------------------------------------------------
* Function: LogIPHeader(TextLog* )
*
* Purpose: Dump the IP header info to the given TextLog
*
* Arguments: log => TextLog to print to
*
* Returns: void function
*--------------------------------------------------------------------
*/
void LogIPHeader(TextLog* log, Packet * p)
{
if(!IPH_IS_VALID(p))
{
TextLog_Print(log, "IP header truncated\n");
return;
}
if(p->frag_flag)
{
/* just print the straight IP header */
TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p)));
TextLog_Puts(log, " -> ");
TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p)));
}
else
{
if(GET_IPH_PROTO(p) != IPPROTO_TCP && GET_IPH_PROTO(p) != IPPROTO_UDP)
{
/* just print the straight IP header */
TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p)));
TextLog_Puts(log, " -> ");
TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p)));
}
else
{
if (!BcObfuscate())
{
/* print the header complete with port information */
TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p)));
TextLog_Print(log, ":%d -> ", p->sp);
TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p)));
TextLog_Print(log, ":%d", p->dp);
}
else
{
/* print the header complete with port information */
if(IS_IP4(p))
TextLog_Print(log, "xxx.xxx.xxx.xxx:%d -> xxx.xxx.xxx.xxx:%d", p->sp, p->dp);
else if(IS_IP6(p))
TextLog_Print(log, "x:x:x:x:x:x:x:x:%d -> x:x:x:x:x:x:x:x:%d", p->sp, p->dp);
}
}
}
if(!BcOutputDataLink())
{
TextLog_NewLine(log);
}
else
{
TextLog_Putc(log, ' ');
}
TextLog_Print(log, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u",
protocol_names[GET_IPH_PROTO(p)],
GET_IPH_TTL(p),
GET_IPH_TOS(p),
IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)),
GET_IPH_HLEN(p) << 2,
GET_IP_DGMLEN(p));
/* print the reserved bit if it's set */
if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1)
TextLog_Puts(log, " RB");
/* printf more frags/don't frag bits */
if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1)
TextLog_Puts(log, " DF");
if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1)
TextLog_Puts(log, " MF");
TextLog_NewLine(log);
/* print IP options */
if(p->ip_option_count != 0)
{
LogIpOptions(log, p);
}
/* print fragment info if necessary */
if(p->frag_flag)
{
TextLog_Print(log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n",
(p->frag_offset & 0x1FFF),
GET_IP_PAYLEN(p));
}
}
/*-------------------------------------------------------------------
* TCP stuff cloned from log.c
*-------------------------------------------------------------------
*/
static void LogTcpOptions(TextLog* log, Packet * p)
{
int i;
int j;
u_char tmp[5];
u_long init_offset;
u_long print_offset;
init_offset = TextLog_Tell(log);
TextLog_Print(log, "TCP Options (%d) => ", p->tcp_option_count);
if(p->tcp_option_count > 40 || !p->tcp_option_count)
return;
for(i = 0; i < (int) p->tcp_option_count; i++)
{
print_offset = TextLog_Tell(log);
/**
if((print_offset - init_offset) > 60)
{
TextLog_Puts(log, "\nTCP Options => ");
init_offset = TextLog_Tell(log);
}
**/
switch(p->tcp_options[i].code)
{
case TCPOPT_MAXSEG:
memset((char*)tmp, 0, sizeof(tmp));
TextLog_Puts(log, "MSS: ");
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 2);
TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp));
break;
case TCPOPT_EOL:
TextLog_Puts(log, "EOL ");
break;
case TCPOPT_NOP:
TextLog_Puts(log, "NOP ");
break;
case TCPOPT_WSCALE:
if (p->tcp_options[i].data)
TextLog_Print(log, "WS: %u ", p->tcp_options[i].data[0]);
else
TextLog_Print(log, "WS: %u ", 0);
break;
case TCPOPT_SACK:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data && (p->tcp_options[i].len >= 2))
memcpy(tmp, p->tcp_options[i].data, 2);
TextLog_Print(log, "Sack: %u@", EXTRACT_16BITS(tmp));
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data && (p->tcp_options[i].len >= 4))
memcpy(tmp, (p->tcp_options[i].data) + 2, 2);
TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp));
break;
case TCPOPT_SACKOK:
TextLog_Puts(log, "SackOK ");
break;
case TCPOPT_ECHO:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 4);
TextLog_Print(log, "Echo: %u ", EXTRACT_32BITS(tmp));
break;
case TCPOPT_ECHOREPLY:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 4);
TextLog_Print(log, "Echo Rep: %u ", EXTRACT_32BITS(tmp));
break;
case TCPOPT_TIMESTAMP:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 4);
TextLog_Print(log, "TS: %u ", EXTRACT_32BITS(tmp));
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, (p->tcp_options[i].data) + 4, 4);
TextLog_Print(log, "%u ", EXTRACT_32BITS(tmp));
break;
case TCPOPT_CC:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 4);
TextLog_Print(log, "CC %u ", EXTRACT_32BITS(tmp));
break;
case TCPOPT_CCNEW:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 4);
TextLog_Print(log, "CCNEW: %u ", EXTRACT_32BITS(tmp));
break;
case TCPOPT_CCECHO:
memset((char*)tmp, 0, sizeof(tmp));
if (p->tcp_options[i].data)
memcpy(tmp, p->tcp_options[i].data, 4);
TextLog_Print(log, "CCECHO: %u ", EXTRACT_32BITS(tmp));
break;
default:
if(p->tcp_options[i].len)
{
TextLog_Print(log, "Opt %d (%d): ", p->tcp_options[i].code,
(int) p->tcp_options[i].len);
for(j = 0; j < p->tcp_options[i].len; j++)
{
if (p->tcp_options[i].data)
TextLog_Print(log, "%02X", p->tcp_options[i].data[j]);
else
TextLog_Print(log, "%02X", 0);
if ((j + 1) % 2 == 0)
TextLog_Putc(log, ' ');
}
TextLog_Putc(log, ' ');
}
else
{
TextLog_Print(log, "Opt %d ", p->tcp_options[i].code);
}
break;
}
}
TextLog_NewLine(log);
}
/*--------------------------------------------------------------------
* Function: LogTCPHeader(TextLog* )
*
* Purpose: Dump the TCP header info to the given TextLog
*
* Arguments: log => pointer to TextLog to print data to
*
* Returns: void function
*--------------------------------------------------------------------
*/
void LogTCPHeader(TextLog* log, Packet * p)
{
char tcpFlags[9];
if(p->tcph == NULL)
{
TextLog_Print(log, "TCP header truncated\n");
return;
}
/* print TCP flags */
CreateTCPFlagString(p, tcpFlags);
TextLog_Puts(log, tcpFlags); /* We don't care about the NULL */
/* print other TCP info */
TextLog_Print(log, " Seq: 0x%lX Ack: 0x%lX Win: 0x%X TcpLen: %d",
(u_long) ntohl(p->tcph->th_seq),
(u_long) ntohl(p->tcph->th_ack),
ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2);
if((p->tcph->th_flags & TH_URG) != 0)
{
TextLog_Print(log, " UrgPtr: 0x%X\n", (uint16_t) ntohs(p->tcph->th_urp));
}
else
{
TextLog_NewLine(log);
}
/* dump the TCP options */
if(p->tcp_option_count != 0)
{
LogTcpOptions(log, p);
}
}
/*-------------------------------------------------------------------
* UDP stuff cloned from log.c
*-------------------------------------------------------------------
*/
/*--------------------------------------------------------------------
* Function: LogUDPHeader(TextLog* )
*
* Purpose: Dump the UDP header to the given TextLog
*
* Arguments: log => pointer to TextLog
*
* Returns: void function
*--------------------------------------------------------------------
*/
void LogUDPHeader(TextLog* log, Packet* p)
{
if(p->udph == NULL)
{
TextLog_Print(log, "UDP header truncated\n");
return;
}
/* not much to do here... */
TextLog_Print(log, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN);
}
/*--------------------------------------------------------------------
* ICMP stuff cloned from log.c
*--------------------------------------------------------------------
*/
/*--------------------------------------------------------------------
* Function: LogEmbeddedICMPHeader(TextLog* , ICMPHdr *)
*
* Purpose: Prints the 64 bits of the original IP payload in an ICMP packet
* that requires it
*
* Arguments: log => pointer to TextLog
* icmph => ICMPHdr struct pointing to original ICMP
*
* Returns: void function
*--------------------------------------------------------------------
*/
static void LogEmbeddedICMPHeader(TextLog* log, const ICMPHdr *icmph)
{
if (log == NULL || icmph == NULL)
return;
TextLog_Print(log, "Type: %d Code: %d Csum: %u",
icmph->type, icmph->code, ntohs(icmph->csum));
switch (icmph->type)
{
case ICMP_DEST_UNREACH:
case ICMP_TIME_EXCEEDED:
case ICMP_SOURCE_QUENCH:
break;
case ICMP_PARAMETERPROB:
if (icmph->code == 0)
TextLog_Print(log, " Ptr: %u", icmph->s_icmp_pptr);
break;
case ICMP_REDIRECT:
#ifdef SUP_IP6
// XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing"
#else
TextLog_Print(log, " New Gwy: %s", inet_ntoa(icmph->s_icmp_gwaddr));
#endif
break;
case ICMP_ECHO:
case ICMP_ECHOREPLY:
case ICMP_TIMESTAMP:
case ICMP_TIMESTAMPREPLY:
case ICMP_INFO_REQUEST:
case ICMP_INFO_REPLY:
case ICMP_ADDRESS:
case ICMP_ADDRESSREPLY:
TextLog_Print(log, " Id: %u SeqNo: %u",
ntohs(icmph->s_icmp_id), ntohs(icmph->s_icmp_seq));
break;
case ICMP_ROUTER_ADVERTISE:
TextLog_Print(log, " Addrs: %u Size: %u Lifetime: %u",
icmph->s_icmp_num_addrs, icmph->s_icmp_wpa,
ntohs(icmph->s_icmp_lifetime));
break;
default:
break;
}
TextLog_NewLine(log);
return;
}
/*--------------------------------------------------------------------
* Function: LogICMPEmbeddedIP(TextLog* , Packet *)
*
* Purpose: Prints the original/encapsulated IP header + 64 bits of the
* original IP payload in an ICMP packet
*
* Arguments: log => pointer to TextLog
* p => packet struct
*
* Returns: void function
*--------------------------------------------------------------------
*/
static void LogICMPEmbeddedIP(TextLog* log, Packet *p)
{
Packet op;
Packet *orig_p;
uint32_t orig_ip_hlen;
if (log == NULL || p == NULL)
return;
memset((char*)&op, 0, sizeof(op));
orig_p = &op;
orig_p->iph = p->orig_iph;
orig_p->tcph = p->orig_tcph;
orig_p->udph = p->orig_udph;
orig_p->sp = p->orig_sp;
orig_p->dp = p->orig_dp;
orig_p->icmph = p->orig_icmph;
#ifdef SUP_IP6
orig_p->iph_api = p->orig_iph_api;
orig_p->ip4h = p->orig_ip4h;
orig_p->ip6h = p->orig_ip6h;
orig_p->family = p->orig_family;
#endif
if(orig_p->iph != NULL)
{
TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
LogIPHeader(log, orig_p);
orig_ip_hlen = IP_HLEN(p->orig_iph) << 2;
switch(GET_IPH_PROTO(orig_p))
{
case IPPROTO_TCP:
if(orig_p->tcph != NULL)
TextLog_Print(log, "Seq: 0x%lX\n",
(u_long)ntohl(orig_p->tcph->th_seq));
break;
case IPPROTO_UDP:
if(orig_p->udph != NULL)
TextLog_Print(log, "Len: %d Csum: %d\n",
ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN,
ntohs(orig_p->udph->uh_chk));
break;
case IPPROTO_ICMP:
if(orig_p->icmph != NULL)
LogEmbeddedICMPHeader(log, orig_p->icmph);
break;
default:
TextLog_Print(log, "Protocol: 0x%X (unknown or "
"header truncated)", GET_IPH_PROTO(orig_p));
break;
} /* switch */
/* if more than 8 bytes of original IP payload sent */
if (p->dsize - orig_ip_hlen > 8)
{
TextLog_Print(log, "(%d more bytes of original packet)\n",
p->dsize - orig_ip_hlen - 8);
}
TextLog_Puts(log, "** END OF DUMP");
}
else
{
TextLog_Puts(log, "\nORIGINAL DATAGRAM TRUNCATED");
}
}
/*--------------------------------------------------------------------
* Function: LogICMPHeader(TextLog* )
*
* Purpose: Print ICMP header
*
* Arguments: log => pointer to TextLog
*
* Returns: void function
*--------------------------------------------------------------------
*/
void LogICMPHeader(TextLog* log, Packet * p)
{
#ifdef SUP_IP6
/* 32 digits plus 7 colons and a NULL byte */
char buf[8*4 + 7 + 1];
#endif
if(p->icmph == NULL)
{
TextLog_Puts(log, "ICMP header truncated\n");
return;
}
TextLog_Print(log, "Type:%d Code:%d ", p->icmph->type, p->icmph->code);
switch(p->icmph->type)
{
case ICMP_ECHOREPLY:
TextLog_Print(log, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id),
ntohs(p->icmph->s_icmp_seq));
TextLog_Puts(log, "ECHO REPLY");
break;
case ICMP_DEST_UNREACH:
TextLog_Puts(log, "DESTINATION UNREACHABLE: ");
switch(p->icmph->code)
{
case ICMP_NET_UNREACH:
TextLog_Puts(log, "NET UNREACHABLE");
break;
case ICMP_HOST_UNREACH:
TextLog_Puts(log, "HOST UNREACHABLE");
break;
case ICMP_PROT_UNREACH:
TextLog_Puts(log, "PROTOCOL UNREACHABLE");
break;
case ICMP_PORT_UNREACH:
TextLog_Puts(log, "PORT UNREACHABLE");
break;
case ICMP_FRAG_NEEDED:
TextLog_Print(log, "FRAGMENTATION NEEDED, DF SET\n"
"NEXT LINK MTU: %u",
ntohs(p->icmph->s_icmp_nextmtu));
break;
case ICMP_SR_FAILED:
TextLog_Puts(log, "SOURCE ROUTE FAILED");
break;
case ICMP_NET_UNKNOWN:
TextLog_Puts(log, "NET UNKNOWN");
break;
case ICMP_HOST_UNKNOWN:
TextLog_Puts(log, "HOST UNKNOWN");
break;
case ICMP_HOST_ISOLATED:
TextLog_Puts(log, "HOST ISOLATED");
break;
case ICMP_PKT_FILTERED_NET:
TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED NETWORK FILTERED");
break;
case ICMP_PKT_FILTERED_HOST:
TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED HOST FILTERED");
break;
case ICMP_NET_UNR_TOS:
TextLog_Puts(log, "NET UNREACHABLE FOR TOS");
break;
case ICMP_HOST_UNR_TOS:
TextLog_Puts(log, "HOST UNREACHABLE FOR TOS");
break;
case ICMP_PKT_FILTERED:
TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED");
break;
case ICMP_PREC_VIOLATION:
TextLog_Puts(log, "PREC VIOLATION");
break;
case ICMP_PREC_CUTOFF:
TextLog_Puts(log, "PREC CUTOFF");
break;
default:
TextLog_Puts(log, "UNKNOWN");
break;
}
LogICMPEmbeddedIP(log, p);
break;
case ICMP_SOURCE_QUENCH:
TextLog_Puts(log, "SOURCE QUENCH");
LogICMPEmbeddedIP(log, p);
break;
case ICMP_REDIRECT:
TextLog_Puts(log, "REDIRECT");
switch(p->icmph->code)
{
case ICMP_REDIR_NET:
TextLog_Puts(log, " NET");
break;
case ICMP_REDIR_HOST:
TextLog_Puts(log, " HOST");
break;
case ICMP_REDIR_TOS_NET:
TextLog_Puts(log, " TOS NET");
break;
case ICMP_REDIR_TOS_HOST:
TextLog_Puts(log, " TOS HOST");
break;
}
#ifdef SUP_IP6
/* written this way since inet_ntoa was typedef'ed to use sfip_ntoa
* which requires sfip_t instead of inaddr's. This call to inet_ntoa
* is a rare case that doesn't use sfip_t's. */
// XXX-IPv6 NOT YET IMPLEMENTED - IPV6 addresses technically not supported - need to change ICMP
/* no inet_ntop in Windows */
sfip_raw_ntop(AF_INET, (const void *)(&p->icmph->s_icmp_gwaddr.s_addr),
buf, sizeof(buf));
TextLog_Print(log, " NEW GW: %s", buf);
#else
TextLog_Print(log, " NEW GW: %s", inet_ntoa(p->icmph->s_icmp_gwaddr));
#endif
LogICMPEmbeddedIP(log, p);
break;
case ICMP_ECHO:
TextLog_Print(log, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id),
ntohs(p->icmph->s_icmp_seq));
TextLog_Puts(log, "ECHO");
break;
case ICMP_ROUTER_ADVERTISE:
TextLog_Print(log, "ROUTER ADVERTISMENT: "
"Num addrs: %d Addr entry size: %d Lifetime: %u",
p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa,
ntohs(p->icmph->s_icmp_lifetime));
break;
case ICMP_ROUTER_SOLICIT:
TextLog_Puts(log, "ROUTER SOLICITATION");
break;
case ICMP_TIME_EXCEEDED:
TextLog_Puts(log, "TTL EXCEEDED");
switch(p->icmph->code)
{
case ICMP_TIMEOUT_TRANSIT:
TextLog_Puts(log, " IN TRANSIT");
break;
case ICMP_TIMEOUT_REASSY:
TextLog_Puts(log, " TIME EXCEEDED IN FRAG REASSEMBLY");
break;
}
LogICMPEmbeddedIP(log, p);
break;
case ICMP_PARAMETERPROB:
TextLog_Puts(log, "PARAMETER PROBLEM");
switch(p->icmph->code)
{
case ICMP_PARAM_BADIPHDR:
TextLog_Print(log, ": BAD IP HEADER BYTE %u",
p->icmph->s_icmp_pptr);
break;
case ICMP_PARAM_OPTMISSING:
TextLog_Puts(log, ": OPTION MISSING");
break;
case ICMP_PARAM_BAD_LENGTH:
TextLog_Puts(log, ": BAD LENGTH");
break;
}
LogICMPEmbeddedIP(log, p);
break;
case ICMP_TIMESTAMP:
TextLog_Print(log, "ID: %u Seq: %u TIMESTAMP REQUEST",
ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
break;
case ICMP_TIMESTAMPREPLY:
TextLog_Print(log, "ID: %u Seq: %u TIMESTAMP REPLY:\n"
"Orig: %u Rtime: %u Ttime: %u",
ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime,
p->icmph->s_icmp_ttime);
break;
case ICMP_INFO_REQUEST:
TextLog_Print(log, "ID: %u Seq: %u INFO REQUEST",
ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
break;
case ICMP_INFO_REPLY:
TextLog_Print(log, "ID: %u Seq: %u INFO REPLY",
ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
break;
case ICMP_ADDRESS:
TextLog_Print(log, "ID: %u Seq: %u ADDRESS REQUEST",
ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
break;
case ICMP_ADDRESSREPLY:
TextLog_Print(log, "ID: %u Seq: %u ADDRESS REPLY: 0x%08X",
ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
(u_int) ntohl(p->icmph->s_icmp_mask));
break;
default:
TextLog_Puts(log, "UNKNOWN");
break;
}
TextLog_NewLine(log);
}
/*--------------------------------------------------------------------
* reference stuff cloned from signature.c
*--------------------------------------------------------------------
*/
/* print a reference node */
static void LogReference(TextLog* log, ReferenceNode *refNode)
{
if(refNode)
{
if(refNode->system)
{
if(refNode->system->url)
TextLog_Print(log, "[Xref => %s%s]", refNode->system->url,
refNode->id);
else
TextLog_Print(log, "[Xref => %s %s]", refNode->system->name,
refNode->id);
}
else
{
TextLog_Print(log, "[Xref => %s]", refNode->id);
}
}
return;
}
/*
* Function: LogXrefs(TextLog* )
*
* Purpose: Prints out cross reference data associated with an alert
*
* Arguments: log => pointer to TextLog to write the data to
* doNewLine => tack a \n to the end of the line or not (bool)
*
* Returns: void function
*/
void LogXrefs(TextLog* log, SigNode *sn, int doNewLine)
{
ReferenceNode *refNode = NULL;
if(sn != NULL)
{
refNode = sn->refs;
while(refNode != NULL)
{
LogReference(log, refNode);
refNode = refNode->next;
/* on the last loop through, print a newline in
Full mode */
if(doNewLine && (refNode == NULL))
TextLog_NewLine(log);
}
}
}
/*--------------------------------------------------------------------
* payload stuff cloned from log.c
*--------------------------------------------------------------------
*/
/*--------------------------------------------------------------------
* Function: LogCharData(TextLog*, char*, int)
*
* Purpose: Dump the printable ASCII data from a packet
*
* Arguments: log => ptr to TextLog to print to
* data => pointer to buffer data
* len => length of data buffer
*
* Returns: void function
*--------------------------------------------------------------------
*/
static void LogCharData(TextLog* log, char *data, int len)
{
const char* pb = data;
const char* end = data + len;
int lineCount = 0;
if ( !data )
{
return;
}
while ( pb < end )
{
if ( *pb > 0x1F && *pb < 0x7F)
{ /* printable */
TextLog_Putc(log, *pb);
}
else
{ /* not printable */
TextLog_Putc(log, '.');
}
if ( ++lineCount == 64 )
{
TextLog_Putc(log, ' ');
TextLog_NewLine(log);
lineCount = 0;
}
pb++;
}
/* slam a \n on the back */
TextLog_Putc(log, ' ');
TextLog_NewLine(log);
TextLog_Putc(log, ' ');
}
/*
* Function: LogNetData(TextLog*, u_char *,int)
*
* Purpose: Do a side by side dump of a buffer, hex on
* the left, decoded ASCII on the right.
*
* Arguments: log => ptr to TextLog to print to
* data => pointer to buffer data
* len => length of data buffer
*
* Returns: void function
*/
#define BYTES_PER_FRAME 16
/* middle of packet:"41 02 43 04 45 06 47 08 49 0A 4B 0C 4D 0E 4F 0F A.C.E.G.I.K.M.O."*/
/* at end of packet:"41 02 43 04 45 06 47 08 A.C.E.G."*/
static char* pad3 = " ";
static void LogNetData (TextLog* log, const u_char* data, const int len)
{
const u_char* pb = data;
const u_char* end = data + len;
int offset = 0;
char conv[] = "0123456789ABCDEF"; /* xlation lookup table */
if ( !len )
{
TextLog_NewLine(log);
return;
}
if ( !data )
{
TextLog_Print(log, "Got NULL ptr in LogNetData()\n");
return;
}
if ( len > IP_MAXPACKET )
{
if (BcLogVerbose())
{
TextLog_Print(
log, "Got bogus buffer length (%d) for LogNetData, "
"defaulting to %d bytes!\n", len, BYTES_PER_FRAME
);
}
end = data + BYTES_PER_FRAME;
}
/* loop thru the whole buffer */
while ( pb < end )
{
int i = 0;
if (BcVerboseByteDump())
{
TextLog_Print(log, "0x%04X: ", offset);
offset += BYTES_PER_FRAME;
}
/* process one frame */
/* first print the binary as ascii hex */
for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++)
{
char b = pb[i];
TextLog_Putc(log, conv[(b & 0xFF) >> 4]);
TextLog_Putc(log, conv[(b & 0xFF) & 0x0F]);
TextLog_Putc(log, ' ');
}
/* print ' ' past end of packet and before ascii */
TextLog_Puts(log, pad3+(3*i));
/* then print the actual ascii chars */
/* or a '.' for control chars */
for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++)
{
char b = pb[i];
if ( b > 0x1F && b < 0x7F)
TextLog_Putc(log, (char)(b & 0xFF));
else
TextLog_Putc(log, '.');
}
pb += BYTES_PER_FRAME;
TextLog_NewLine(log);
}
TextLog_NewLine(log);
}
/*--------------------------------------------------------------------
* Function: LogIPPkt(TextLog*, int, Packet *)
*
* Purpose: Dump the packet to the given TextLog
*
* Arguments: log => pointer to print data to
* type => packet protocol
* p => pointer to decoded packet struct
*
* Returns: void function
*--------------------------------------------------------------------
*/
#ifdef SUP_IP6
#define DATA_PTR(p) \
((u_char*)p->iph + (GET_IPH_HLEN(p) << 2))
#define DATA_LEN(p) \
(p->actual_ip_len - (GET_IPH_HLEN(p) << 2))
#else
#define DATA_PTR(p) \
((u_char *)p->iph + (IP_HLEN(p->iph) << 2))
#define DATA_LEN(p) \
(p->actual_ip_len - (IP_HLEN(p->iph) << 2))
#endif
#define SEPARATOR \
"=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
void LogIPPkt(TextLog* log, int type, Packet * p)
{
DEBUG_WRAP(DebugMessage(DEBUG_LOG, "LogIPPkt type = %d\n", type););
/* dump the timestamp */
LogTimeStamp(log, p);
/* dump the ethernet header if we're doing that sort of thing */
if (BcOutputDataLink())
{
Log2ndHeader(log, p);
}
#ifdef MPLS
if(p->mpls)
{
LogMPLSHeader(log, p);
}
#endif
/* etc */
LogIPHeader(log, p);
/* if this isn't a fragment, print the other header info */
if ( !p->frag_flag )
{
switch (GET_IPH_PROTO(p))
{
case IPPROTO_TCP:
if ( p->tcph != NULL )
{
LogTCPHeader(log, p);
}
else
{
LogNetData(log, DATA_PTR(p), DATA_LEN(p));
}
break;
case IPPROTO_UDP:
if ( p->udph != NULL )
{
LogUDPHeader(log, p);
}
else
{
LogNetData(log, DATA_PTR(p), DATA_LEN(p));
}
break;
case IPPROTO_ICMP:
if ( p->icmph != NULL )
{
LogICMPHeader(log, p);
}
else
{
LogNetData(log, DATA_PTR(p), GET_IP_PAYLEN(p));
}
break;
default:
break;
}
}
/* dump the application layer data */
if (BcOutputAppData() && !BcVerboseByteDump())
{
if (BcOutputCharData())
LogCharData(log, (char*) p->data, p->dsize);
else
LogNetData(log, p->data, p->dsize);
}
else if (BcVerboseByteDump())
{
LogNetData(log, p->pkt, p->pkth->caplen);
}
TextLog_Print(log, "%s\n\n", SEPARATOR);
}
#ifndef NO_NON_ETHER_DECODER
/*--------------------------------------------------------------------
* ARP stuff cloned from log.c
*--------------------------------------------------------------------
*/
#ifndef SUP_IP6
static unsigned char ezero[6]; /* crap for ARP */
#endif
void LogArpHeader(TextLog* log, Packet * p)
{
#ifdef SUP_IP6
// XXX-IPv6 "NOT YET IMPLEMENTED - printing ARP header"
#else
struct in_addr ip_addr;
const uint8_t *mac_src = NULL;
const uint8_t *mac_dst = NULL;
memset((struct in_addr *) &ip_addr, 0, sizeof(struct in_addr));
/* determine what to use as MAC src and dst */
if (p->eh != NULL)
{
mac_src = p->eh->ether_src;
mac_dst = p->eh->ether_dst;
} /* per table 4, 802.11 section 7.2.2 */
else if (p->wifih != NULL &&
(p->wifih->frame_control & WLAN_FLAG_FROMDS))
{
mac_src = p->wifih->addr3;
mac_dst = p->wifih->addr2;
}
else if (p->wifih != NULL &&
(p->wifih->frame_control & WLAN_FLAG_TODS))
{
mac_src = p->wifih->addr2;
mac_dst = p->wifih->addr3;
}
else if (p->wifih != NULL)
{
mac_src = p->wifih->addr2;
mac_dst = p->wifih->addr1;
}
/*
* if these are null this function will break, exit until
* someone writes a function for it...
*/
if(mac_src == NULL || mac_dst == NULL)
{
return;
}
/* dump the timestamp */
LogTimeStamp(log, p);
if(ntohs(p->ah->ea_hdr.ar_pro) != ETHERNET_TYPE_IP)
{
TextLog_Print(log, "ARP #%d for protocol #%.4X (%d) hardware #%d (%d)\n",
ntohs(p->ah->ea_hdr.ar_op), ntohs(p->ah->ea_hdr.ar_pro),
p->ah->ea_hdr.ar_pln, ntohs(p->ah->ea_hdr.ar_hrd),
p->ah->ea_hdr.ar_hln);
return;
}
switch(ntohs(p->ah->ea_hdr.ar_op))
{
case ARPOP_REQUEST:
/* bcopy() deprecated, replaced with memmove() */
memmove((void *) &ip_addr, (void *)p->ah->arp_tpa, sizeof(ip_addr));
TextLog_Print(log, "ARP who-has %s", inet_ntoa(ip_addr));
if(memcmp((char *) ezero, (char *) p->ah->arp_tha, 6) != 0)
{
TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_tha[0],
p->ah->arp_tha[1], p->ah->arp_tha[2], p->ah->arp_tha[3],
p->ah->arp_tha[4], p->ah->arp_tha[5]);
}
/* bcopy() deprecated, replaced with memmove() */
memmove((void *) &ip_addr, (void *)p->ah->arp_spa, sizeof(ip_addr));
TextLog_Print(log, " tell %s", inet_ntoa(ip_addr));
if(memcmp((char *) mac_src, (char *) p->ah->arp_sha, 6) != 0)
{
TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_sha[0],
p->ah->arp_sha[1], p->ah->arp_sha[2], p->ah->arp_sha[3],
p->ah->arp_sha[4], p->ah->arp_sha[5]);
}
break;
case ARPOP_REPLY:
/* bcopy() deprecated, replaced with memmove() */
memmove((void *) &ip_addr, (void *)p->ah->arp_spa, sizeof(ip_addr));
TextLog_Print(log, "ARP reply %s", inet_ntoa(ip_addr));
/* print out the originating request if we're on a weirder
* wireless protocol */
if(memcmp((char *) mac_src, (char *) p->ah->arp_sha, 6) != 0)
{
TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", mac_src[0],
mac_src[1], mac_src[2], mac_src[3],
mac_src[4], mac_src[5]);
}
TextLog_Print(log, " is-at %X:%X:%X:%X:%X:%X", p->ah->arp_sha[0],
p->ah->arp_sha[1], p->ah->arp_sha[2], p->ah->arp_sha[3],
p->ah->arp_sha[4], p->ah->arp_sha[5]);
if(memcmp((char *) mac_dst, (char *) p->ah->arp_tha, 6) != 0)
{
TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_tha[0],
p->ah->arp_tha[1], p->ah->arp_tha[2], p->ah->arp_tha[3],
p->ah->arp_tha[4], p->ah->arp_tha[5]);
}
break;
case ARPOP_RREQUEST:
TextLog_Print(log, "RARP who-is %X:%X:%X:%X:%X:%X tell %X:%X:%X:%X:%X:%X",
p->ah->arp_tha[0], p->ah->arp_tha[1], p->ah->arp_tha[2],
p->ah->arp_tha[3], p->ah->arp_tha[4], p->ah->arp_tha[5],
p->ah->arp_sha[0], p->ah->arp_sha[1], p->ah->arp_sha[2],
p->ah->arp_sha[3], p->ah->arp_sha[4], p->ah->arp_sha[5]);
break;
case ARPOP_RREPLY:
/* bcopy() deprecated, replaced with memmove() */
memmove((void *) &ip_addr, (void *)p->ah->arp_tpa, sizeof(ip_addr));
TextLog_Print(log, "RARP reply %X:%X:%X:%X:%X:%X at %s",
p->ah->arp_tha[0], p->ah->arp_tha[1], p->ah->arp_tha[2],
p->ah->arp_tha[3], p->ah->arp_tha[4], p->ah->arp_tha[5],
inet_ntoa(ip_addr));
break;
default:
TextLog_Print(log, "Unknown operation: %d", ntohs(p->ah->ea_hdr.ar_op));
break;
}
TextLog_Puts(log, "\n\n");
#endif
}
#endif // NO_NON_ETHER_DECODER
Jump to Line
Something went wrong with that request. Please try again.