never stop questioning

plogd2.c

plogd2.c
Posted Apr 26, 2000
Authored by Venglin | Site freebsd.lublin.pl

Plogd v2 (Revision 1.5) is a syn/udp/icmp packet logger for freebsd.

Changes: Fixed fd leak, misc bugfixes.
tags | udp
systems | freebsd
MD5 | eef674504b75af8c3aa2b70b04a1ae7d

plogd2.c

Change Mirror Download
/*
*
* (c) 2000 venglin / buffer0verfl0w security (www.b0f.com)
*
* plogd v2 -- syn/udp/icmp packet logger (freebsd version)
*
* [ compile with -lpcap ]
*
* bug reports: babunia@freebsd.lublin.pl
*
* $Log: plogd2.c,v $
* Revision 1.5 2000/04/18 09:11:09 venglin
* fd leak
*
* Revision 1.4 2000/04/16 11:12:31 venglin
* ctime() added
*
* Revision 1.3 2000/04/14 20:13:41 venglin
* some fflush() added
*
* Revision 1.2 2000/02/28 00:07:51 venglin
* SIGSEGV in rfc931_lookup()
*
* Revision 1.1 2000/02/27 23:29:18 venglin
* Initial revision
*
*
*/

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <stdarg.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>

#define IDENT 113
#define BUFSIZE 1024
#define IP_SIZE 20
#define TCP_SIZE 20
#define DLT_LEN 14

/* static */

FILE *log;
pcap_t *ip_socket;

struct {
unsigned int noresolve : 1;
unsigned int noident : 1;
unsigned int notcp : 1;
unsigned int noudp : 1;
unsigned int noicmp : 1;
} flags;

char rcsid[]="$Id: plogd2.c,v 1.5 2000/04/18 09:11:09 venglin Exp $";

/* prototypes */

static char *hostlookup __P((unsigned));
void filter_packet __P((u_char *, struct pcap_pkthdr *, u_char *));
void log_syn __P((struct ip *, struct tcphdr *));
void log_icmp __P((struct ip *, struct icmp *));
void log_udp __P((struct ip *, struct udphdr *));
void usage __P((char *));
int rfc931_lookup __P((long, unsigned, unsigned, char *));
void loginit __P((char *, char *));
void debug __P((const char *, ...));
void fatal __P((const char *, ...));

/* log routines */

void loginit(ofile, av0)
char *ofile, *av0;
{
if (ofile)
{
if (!(log = fopen(ofile, "w")))
fatal("fopen(): %s", strerror(errno));
}
else
{
closelog();
openlog(av0, LOG_PID, LOG_DAEMON);
}
}

void fatal(const char *fmt, ...)
{
char buf[BUFSIZE];
va_list args;
time_t now;
char *timestamp;

va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);

if (log)
{
(void)time(&now);
timestamp = ctime(&now) + 4;
fprintf(log, "%.20s: fatal: %s\n", timestamp, buf);
fflush(log);
}
else
syslog(LOG_ERR, "fatal: %.500s", buf);

closelog();
if (log)
fclose(log);

if (ip_socket)
pcap_close(ip_socket);

exit(1);
}

void debug(const char *fmt, ...)
{
char buf[BUFSIZE];
va_list args;
time_t now;
char *timestamp;

va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);

if (log)
{
(void)time(&now);
timestamp = ctime(&now) + 4;
fprintf(log, "%.20s: status: %s\n", timestamp, buf);
fflush(log);
}
else
syslog(LOG_NOTICE, "status: %.500s", buf);

return;
}

/* signal handler */
void sigcatch(sig)
int sig;
{
fatal("Received signal %d; terminating.", sig);
return;
}

/* reverse host lookup routine */

char *hostlookup(unsigned int in)
{
static char tmp[BUFSIZE];
struct in_addr i;
struct hostent *he = NULL;

i.s_addr = in;

if(!flags.noresolve)
he = gethostbyaddr((char *)&i, sizeof(struct in_addr), AF_INET);

if (he == NULL || flags.noresolve)
strncpy(tmp, inet_ntoa(i), BUFSIZE-1);
else
strncpy(tmp, he->h_name, BUFSIZE-1);

tmp[BUFSIZE]='\0';
return (char *)tmp;
}

/* ident/tap (rfc931) lookup routine */

int rfc931_lookup(host, sport, dport, ident)
long host;
unsigned int sport, dport;
char *ident;
{
char buf[BUFSIZE], tmp[BUFSIZE];
char *cp;
int sockfd, dump;
struct sockaddr_in cli;

bzero(&cli, sizeof(cli));
cli.sin_family = AF_INET;
cli.sin_addr.s_addr=host;
cli.sin_port = htons(IDENT);

sprintf(buf, "%u,%u\r\n", sport, dport);

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1;

if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0)
{
close(sockfd);
return -1;
}

if (write(sockfd, buf, strlen(buf)) < 0)
{
close(sockfd);
return -1;
}

bzero(buf, BUFSIZE);

if (read(sockfd, buf, BUFSIZE-1) < 0)
{
close(sockfd);
return -1;
}

close(sockfd);

if (sscanf(buf, "%u , %u : USERID :%*[^:]:%s", &dump, &dump, tmp) != 3)
return -1;

if ((cp = strchr(tmp, '\r')))
*cp = '\0';

strncpy(ident, tmp, BUFSIZE);

return 0;
}

/* tcp syn log routine */

void log_syn(ip, tcp)
struct ip *ip;
struct tcphdr *tcp;
{
char ident[BUFSIZE];
struct servent *service;

if (flags.notcp)
return;

if (!flags.noident)
{
if (ntohs(tcp->th_dport) != IDENT)
{
if (rfc931_lookup((long)ip->ip_src.s_addr,
(unsigned)ntohs(tcp->th_sport),
(unsigned)ntohs(tcp->th_dport),
ident) < 0)

strcpy(ident, "unknown");
}
else
strcpy(ident, "unknown");
}
else
strcpy(ident, "unknown");

if ((service = getservbyport(tcp->th_dport, NULL)) != NULL)
debug("connection from %s@%s (port %u) to service %s (port %u)",
ident, hostlookup(ip->ip_src.s_addr),
ntohs(tcp->th_sport), service->s_name,
ntohs(tcp->th_dport));

else

debug("connection from %s@%s (port %u) to port %u", ident,
hostlookup(ip->ip_src.s_addr),
ntohs(tcp->th_sport),
ntohs(tcp->th_dport));

return;
}

/* icmp log routine */

void log_icmp(ip, icmp)
struct ip *ip;
struct icmp *icmp;
{
static char *icmptab[] =
{
"echo reply",
NULL,
NULL,
"unreachable",
"source quench",
"redirect",
NULL,
NULL,
"echo request",
"router advertisement",
"router solicitation",
"time exceed",
"parameter problem",
"timestamp request",
"timestamp reply",
"information request",
"information reply",
"address mask request",
"address mask reply",
NULL
};

if (flags.noicmp)
return;

debug("icmp %s from %s", icmptab[icmp->icmp_type],
hostlookup(ip->ip_src.s_addr));

return;
}

/* udp log routine */

void log_udp(ip, udp)
struct ip *ip;
struct udphdr *udp;
{
struct servent *service;

if (flags.noudp)
return;

if ((service = getservbyport(udp->uh_dport, NULL)) != NULL)
debug("udp packet from %s (port %u) to service %s (port %u)",
hostlookup(ip->ip_src.s_addr),
ntohs(udp->uh_sport), service->s_name,
ntohs(udp->uh_dport));

else

debug("udp packet from %s (port %u) to port %u",
hostlookup(ip->ip_src.s_addr),
ntohs(udp->uh_sport), ntohs(udp->uh_dport));

return;
}

/* filter routine */

void filter_packet(u, p, packet)
u_char *u, *packet;
struct pcap_pkthdr *p;
{
unsigned short ip_options = 0;
struct ip *ip;
struct tcphdr *tcp;
struct icmp *icmp;
struct udphdr *udp;
static u_char align_buf[4096];

ip = (struct ip *) (packet + DLT_LEN);

bcopy((char *)ip, (char *)align_buf, p->len);
packet = align_buf;

ip = (struct ip *)align_buf;

switch(ip->ip_p)
{
case IPPROTO_TCP:

ip_options = ip->ip_hl;
ip_options -= 5;
ip_options *= 4;

tcp = (struct tcphdr *)(packet + IP_SIZE + ip_options);
ip->ip_off &= 0xFF9F;
if(ip->ip_off != 0) return;

if((tcp->th_flags & TH_SYN) && !(tcp->th_flags & TH_ACK))
log_syn(ip, tcp);
break;

case IPPROTO_ICMP:

ip_options = ip->ip_hl;
ip_options -= 5;
ip_options *= 4;

icmp = (struct icmp *)(packet + IP_SIZE + ip_options);
log_icmp(ip, icmp);

break;

case IPPROTO_UDP:

ip_options = ip->ip_hl;
ip_options -= 5;
ip_options *= 4;

udp = (struct udphdr *)(packet + IP_SIZE + ip_options);
log_udp(ip, udp);

break;
}
}

/* nice usage routine */

void usage(av0)
char *av0;
{
(void)fprintf(stderr,
"\nusage: %s [-r] [-l] [-t] [-u] [-c] [-o file] [-i interface] \"filt_expr\"\n\n"
"\t[-r]\t\tdon't resolve hostnames\n"
"\t[-l]\t\tdon't perform rfc931 lookup\n"
"\t[-t]\t\tdon't log tcp connections\n"
"\t[-u]\t\tdon't log udp packets\n"
"\t[-c]\t\tdon't log icmp packets\n"
"\t[-o]\t\toutput file (default: syslogd)\n"
"\t[-i]\t\tnetwork interface\n"
"\t\"filt_expr\"\ttcpdump compatibile filter expression\n\n", av0);
exit(0);
}

/* ...and main! */

int main(argc, argv)
int argc;
char **argv;
{
extern char *optarg;
extern int optind;

int ch, f;
char *iface, *ofile, *av0, errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 network, netmask;
struct bpf_program prog;

if (strchr(argv[0], '/'))
av0 = strrchr(argv[0], '/') + 1;
else
av0 = argv[0];

opterr = flags.noresolve = flags.noident = flags.notcp = flags.noudp =
flags.noicmp = 0;

iface = ofile = NULL;
log = NULL;
ip_socket = NULL;

while ((ch = getopt(argc, argv, "rltuci:a:o:e:")) != -1)
switch((char)ch)
{

case 'r':
flags.noresolve = 1;
break;

case 'l':
flags.noident = 1;
break;

case 't':
flags.notcp = 1;
break;

case 'u':
flags.noudp = 1;
break;

case 'c':
flags.noicmp = 1;
break;

case 'i':
iface = strdup(optarg);
if (!iface)
fatal("malloc(): %s", strerror(errno));
break;

case 'o':
ofile = strdup(optarg);
if (!ofile)
fatal("malloc(): %s", strerror(errno));
break;

case '?':
default:

(void)usage(av0);

}

argc -= optind;
argv += optind;

if (argc < 1)
(void)usage(av0);

signal(SIGHUP, SIG_IGN);
signal(SIGINT, sigcatch);
signal(SIGQUIT, sigcatch);
signal(SIGTERM, sigcatch);
signal(SIGSEGV, sigcatch);
signal(SIGBUS, sigcatch);

loginit(ofile, av0);

if (!iface)
{
iface = strdup(pcap_lookupdev(errbuf));

if (!iface)
fatal("pcap_lookupdev(): %s", errbuf);
}

if (pcap_lookupnet(iface, &network, &netmask, errbuf) < 0)
fatal("pcap_lookupnet(): %s", errbuf);

if (!(ip_socket = pcap_open_live(iface, 1024, 0, 1024, errbuf)))
fatal("pcap_open_live(): %s", errbuf);

if (pcap_datalink(ip_socket) != DLT_EN10MB)
fatal("pcap_datalink(): only ethernet hardware supported");

if (pcap_compile(ip_socket, &prog, *argv, 1, netmask) < 0)
fatal("pcap_compile(): %s", errbuf);

if (pcap_setfilter(ip_socket, &prog) < 0)
fatal("pcap_setfilter(): %s", errbuf);

debug("ready to rock on %s (%s)", iface, *argv);

f = fork();

if (f < 0)
debug("fork(): %s (continuing in foreground)", strerror(errno));

if (f > 0)
{
debug("fork ok (pid %d)", f);
return 0;
}

setsid();

free(iface);
free(ofile);

while(1)
pcap_loop(ip_socket, -1, (pcap_handler)filter_packet, NULL);
}

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

May 2012

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    37 Files
  • 2
    May 2nd
    53 Files
  • 3
    May 3rd
    33 Files
  • 4
    May 4th
    4 Files
  • 5
    May 5th
    10 Files
  • 6
    May 6th
    17 Files
  • 7
    May 7th
    19 Files
  • 8
    May 8th
    36 Files
  • 9
    May 9th
    34 Files
  • 10
    May 10th
    35 Files
  • 11
    May 11th
    20 Files
  • 12
    May 12th
    18 Files
  • 13
    May 13th
    11 Files
  • 14
    May 14th
    27 Files
  • 15
    May 15th
    58 Files
  • 16
    May 16th
    54 Files
  • 17
    May 17th
    25 Files
  • 18
    May 18th
    53 Files
  • 19
    May 19th
    9 Files
  • 20
    May 20th
    15 Files
  • 21
    May 21st
    25 Files
  • 22
    May 22nd
    32 Files
  • 23
    May 23rd
    35 Files
  • 24
    May 24th
    26 Files
  • 25
    May 25th
    25 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2012 Packet Storm. All rights reserved.

close