/*
* loop.c -- the main loop of the capture engine
* Part of the tcpick project
*
* Author: Francesco Stablum <duskdruid @ despammed.com>
*
* Copyright (C) 2003, 2004 Francesco Stablum
* Licensed under the GPL
*
*/
/*
* 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 you 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,
* USA.
*/
#include "tcpick.h"
#include "extern.h"
int
got_packet (u_char * useless,
const struct pcap_pkthdr* hdr,
const u_char* packet)
/* called by pcap_loop.
this is the main loop for the packet engine. */
{ /* FIXME: this function is too long */
/* check if the flag for checking for expired connections
is turned on */
if(expired_flag == CHECK_GOTPACKET) {
check_expired();
}
expired_flag = CHECK_NOT;
if(! packet)
fault( "got_packet", "didn't grab packet" );
count_packets++;
ippacket=(struct ip *)(packet + datalink_size);
#if __BYTE_ORDER == __LITTLE_ENDIAN
iplen = (ippacket->ip_len % 256) * 256 + (ippacket->ip_len) / 256;
#elif __BYTE_ORDER == __BIG_ENDIAN
iplen = ippacket->ip_len;
#else
# error "Please fix <bits/endian.h>"
#endif
switch(ippacket->ip_p) {
case IPPROTO_TCP:
tcppacket = (struct tcphdr *)(packet + datalink_size + IP_SIZE);
tcp_size = tcppacket->doff * 4;
payload = (u_char *)(packet + datalink_size + IP_SIZE + tcp_size);
payload_len = iplen - IP_SIZE - tcp_size;
#ifdef TCPICK_DEBUG
if( payload_len != (hdr->len - (int)( payload - packet ) ) ) {
suicide( "got_packet",
"payload lenght calculated with iplen and hdr->len\n"
"differs by %d bytes\n"
"hdr->len = %d\n"
"datalink_size = %d\n"
"IP_SIZE = %d\n"
"iplen = %d\n"
"tcp_size = %d\n"
"iplen - IP_SIZE - tcp_size = %d\n"
"(hdr->len - (int)( payload - packet ) = %d\n",
payload_len - (hdr->len - (int)( payload - packet )),
hdr->len,
datalink_size,
IP_SIZE,
iplen,
tcp_size,
payload_len,
(hdr->len - (int)( payload - packet ))
);
}
#endif /* TCPICK_DEBUG */
if( flags.header > 0 )
display_header( stdout, ippacket, tcppacket,
payload_len );
verify(); /* call the core to manage the packet */
if( payload_len == 0 || SILENCE )
goto end;
out_flavour( flags.display_payload,
stdout, payload, payload_len );
break;
case IPPROTO_UDP:
udppacket = (struct udphdr *)(packet + datalink_size + IP_SIZE);
payload = (u_char *)(packet + datalink_size + IP_SIZE + sizeof(*udppacket));
payload_len = hdr->len - (int)( payload - packet );
if( payload_len == 0 || SILENCE )
goto end;
out_flavour( flags.display_payload,
stdout, payload, payload_len );
break;
default: /* Packet with an unidentified protocol */
debug( "Packet with unidentified protocol caught: %s > %s",
inet_ntoa(ippacket->ip_src),
inet_ntoa(ippacket->ip_dst) );
}
end:
if( flags.exitpackets != 0 ) {
if (count_packets == flags.exitpackets)
exit(EXIT_SUCCESS);
}
/* Now the callback is able to check! */
expired_flag = CHECK_LISTENING;
}
syntax highlighted by Code2HTML, v. 0.9.1