TUCoPS :: BSD
:: gork20b.c
Gork 2.0b
Gork is a tcp/udp/icmp/ip dumper with options to log only
packets from/to specific machine/s in a file. This version
supports pcap library.
|
/*
* G o r k - U n i x P a c k e t L o g g e r
*
* v e r s i o n 2.0b - bugs fixed
*
* Questo sorgente non e' coperto da nessun copyright e come tale potete farci
* quello che volete... visto che non arrichisce le mie tasche potete
* tranquillamente rubarlo all'autore che tanto a lui non gliene frega un
* cazzo... ne' io, ne' il ladro ci possiamo ritenere responsabili di quello
* che fate con questo sorgente...
*
* Compile with: gcc gork.c -Wall -lpcap
*
* Tested on:
* Linux RedHat 6.X ( mail.cameretta.pig )
* Linux Debian 2.0r3 ( porcellino.cameretta.pig )
* FreeBSD 4.0 ( sp00f.y0ur.life.cameretta.pig )
*
* - Now it logs correctly
*
* pIGpEN [pigpen@s0ftpj.org]
*/
/*
* Questa e' la versione che permette di loggare i pacchetti rispetto alla
* versione pubblicata su bfi 7:
*
* - e' stata corretta la hostLookup()
* - HST_FOUND viene inizializzata dentro il ciclo in modo da permettere di
* loggare solo sui files giusti
* - il codice e' stato identato come dio bit comanda e sono state tolte
* alcune parti superflue tra cui una variabile in piu' utilizzata per
* leggere l'header pcap c'e' ancora una che non serve un cazzo ma che
* viene passata come parametro alla funzione pcap_next()
*/
// CONFIGURATION
/*
* DONT_LOOKUP -> if you have problems with gork & your dns
* SYSTEM_LOG -> Log gork msg via syslog warning this can give problems
* PROMISC -> 1 to activate it 0 if you wanna see only your box pkts
*/
#define PROMISC 1
/*
*
* G o R K a porting of Timothy Leary on your Box ... ;)
*
*/
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <pcap.h>
#if (linux)
#define __FAVOR_BSD
#endif
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#ifdef SYSTEM_LOG
#include <syslog.h>
#endif
#define CONF "gork.conf"
#define LOG_TYPE 4 //syslog
#define SYSLOG_PORT 514
#define MTU 1500
#define URG 32
#define ACK_PSH 24
#define SYN_ACK 18
#define FIN_ACK 17
#define ACK 16
#define PSH 8
#define RST 4
#define SYN 2
#define FIN 1
#define WHITE printf("\033[0;29m")
#define RED printf("\033[1;31m")
#define GREEN printf("\033[1;32m")
#define YELLOW printf("\033[1;33m")
#define BLUE printf("\033[1;34m")
#define MAGENTA printf("\033[1;35m")
#define CYAN printf("\033[1;36m")
#define RETURN printf("\n")
#define CLEAR printf("\033[2J\033[1;1H")
#define LINE printf("<\033[1;32m-----\033[1;34m>\n");
#define ADDR_DIM 255
#define LOG_ALL "all_g0rk.log"
#define LOG_SL "gork.syslog"
unsigned char s_addr[ADDR_DIM];
unsigned char d_addr[ADDR_DIM];
char *hst_saddr=NULL;
char *hst_daddr=NULL;
time_t now;
char date[60];
int port=0;
char *syslog_string;
extern char *optarg;
pcap_t *pcap_global_descriptor;
char *deviceglobal=NULL;
int offset;
struct packet_info{
unsigned char ttl, protocol, version;
unsigned char *saddr, *daddr;
unsigned long seq, ack_seq;
unsigned short source, dest, type, id, flags, window;
char dataload[MTU];
};
struct DNSpkt {
HEADER head;
char query[255];
};
struct TCPhdr {
u_short source, dest;
u_int32_t seq, ack_seq;
u_short offset_flag, window, checksum, urgent;
};
int main __P((int, char **));
void usage __P((char *));
void scan __P((struct packet_info));
void fuckin_about_all_day __P((void));
void print_addr __P((struct packet_info));
void pcap_device_on __P((void));
void sniff_pk __P((struct packet_info *));
void ethclose __P(());
void dump_tcp __P((struct packet_info, int));
void dump_udp __P((struct packet_info));
void dump_icmp __P((struct packet_info));
#ifndef DONT_LOOKUP
char *hostLookup __P((struct in_addr));
char *hostLookup(struct in_addr in)
{
struct hostent *hostEnt;
if((hostEnt=gethostbyaddr((char *)&in, sizeof(struct in_addr), AF_INET)))
return (strdup(hostEnt->h_name));
return NULL;
}
#endif
void usage(char *arg)
{
YELLOW;
printf("\t\t\t pIGpEN - diGiTaL dEAdhEAd -");
BLUE;
printf("\n\n\nPut hostname/ip in gork.conf ... \nUse ");
MAGENTA;
printf("-p dest_port ");
BLUE;
printf("if you wanna log only packets to dest_port\n and with ip/hostname in");
MAGENTA;
printf(" gork.conf\n");
BLUE;
printf("To log all source ip put in gork.conf: ");
MAGENTA;
printf(".\n");
printf("-l string ");
BLUE;
printf("write in gork.syslog if <string> was found in syslog messages\n");
printf("Other options: \n");
printf(" -i interface\n");
printf(" -v verbose mode for tcp\n");
WHITE;
}
void fuckin_about_all_day(void)
{
CLEAR;
fflush(stdout); sleep(1);
printf("\033[1;35m .g#S$'$S#n.\n");
printf("\033[1;35m $$$$$ $$$$'\n");
printf("\033[1;35m $$$$$\n");
printf("\033[1;35m `$$$$$$$$$n\n");
printf("\033[1;34m $$$$$\n");
printf("\033[1;34m $$$$$ $$$$$\n");
printf("\033[1;34m `$$$$s$$$S'\n\n");
fflush(stdout); sleep(1);
printf("\033[1;35m .g#S$'$S#n.\n");
printf("\033[1;35m $$$$$ $$$$$\n");
printf("\033[1;35m $$$$$ $$$$$\n");
printf("\033[1;35m $$$$$ $$$$$\n");
printf("\033[1;34m $$$$$s$$$$'\n");
printf("\033[1;34m $$$$$ \n");
printf("\033[1;34m $$$$ \n");
fflush(stdout); sleep(1);
printf("\033[1;35m S#n.\n");
printf("\033[1;35m $$$$\n");
printf("\033[1;35m $$$$\n");
printf("\033[1;35m $$$$\n");
printf("\033[1;34m $$$$\n");
printf("\033[1;34m $$$$$ $$$$\n");
printf("\033[1;34m `$$$$s$$S'\n\n");
fflush(stdout); sleep(1);
MAGENTA;
printf("\033[15A\t\t\t\t _____________________\n");
fflush(stdout); sleep(1);
printf("\033[01A\t\t\t\t s o f t p r o j e c t\n\n");
fflush(stdout); sleep(1);
BLUE;
printf("\t\t\t ____________________________________________\n\n");
fflush(stdout); sleep(1);
printf("\t\t\t\033[02A d i g i t a l s e k u r i t y f o r y 2 k\n\n");
fflush(stdout); sleep(1);
printf("\t\t\t\t ___________________________\n");
fflush(stdout); sleep(1);
printf("\t\t\t\t\033[01A w w w . s 0 f t p j . o r g\n");
fflush(stdout); sleep(1);
sleep(3);
CLEAR;
}
void print_addr(struct packet_info infoz)
{
struct servent *service = NULL;
struct protoent *proto = NULL;
struct in_addr in_a;
int yes_lookup=0;
now=time(NULL);
strftime(date,60,"%H:%M:%S %a %h %d", localtime(&now));
bzero(s_addr,sizeof(s_addr));
bzero(d_addr,sizeof(d_addr));
hst_daddr=NULL;
hst_saddr=NULL;
sprintf(s_addr,"%u.%u.%u.%u",
infoz.saddr[0],
infoz.saddr[1],
infoz.saddr[2],
infoz.saddr[3]);
sprintf(d_addr,"%u.%u.%u.%u",
infoz.daddr[0],
infoz.daddr[1],
infoz.daddr[2],
infoz.daddr[3]);
GREEN; printf("%s\n",date);
BLUE; printf("%s",s_addr);
GREEN; printf(" -> ");
MAGENTA; printf("%s",d_addr);
if(infoz.protocol!=IPPROTO_ICMP) {
if((proto=getprotobynumber(infoz.protocol))) {
BLUE;
if((service=getservbyport(infoz.source,proto->p_name)))
printf(" %s",service->s_name);
else printf(" %d",infoz.source);
YELLOW; printf(" / ");
MAGENTA;
if((service=getservbyport(infoz.dest,proto->p_name)))
printf("%s",service->s_name);
else printf("%d",infoz.dest);
}
}
#ifndef DONT_LOOKUP
BLUE;
// limit shit for dns ... invoked with gethostbyaddr()
// you can change it as you want ...
switch(infoz.protocol) {
case IPPROTO_TCP:
if(infoz.flags==SYN)
yes_lookup=1;
break;
case IPPROTO_UDP:
if(infoz.source != NAMESERVER_PORT &&
infoz.dest != NAMESERVER_PORT)
yes_lookup=1;
break;
case IPPROTO_ICMP:
yes_lookup=1;
break;
}
if(yes_lookup) {
RETURN;
inet_aton((char *)s_addr, &in_a);
if(!(hst_saddr=hostLookup(in_a)))
printf("none -> ");
else
printf("%s -> ",hst_saddr);
MAGENTA;
inet_aton((char *)d_addr, &in_a);
if(!(hst_daddr=hostLookup(in_a)))
printf("none");
else
printf("%s",hst_daddr);
}
#endif
MAGENTA; RETURN;
scan(infoz);
}
void scan(struct packet_info infoz)
{
FILE *iff, *of;
char buf[512];
char o[400],tmp_port[10];
char *flags=NULL;
int HST_FOUND=0;
if(!(iff=fopen(CONF,"r")))
return;
while(fgets(buf,512,iff)) {
if(buf[strlen(buf)-1]=='\n')
buf[strlen(buf)-1]=0;
HST_FOUND = 0;
if(infoz.version!=4) {
CLEAR;
printf("Sorry this is only a ipv4 version. write to: pigpen@s0ftpj.org\n");
printf("if you wanna ipv6 support\n");
exit(-1);
}
if(port && infoz.dest!=port && infoz.source!=port)
return;
if(port && (infoz.protocol==IPPROTO_ICMP))
return;
if(hst_saddr) {
if(strstr(hst_saddr,buf))
HST_FOUND=1;
}
if(hst_daddr) {
if(strstr(hst_daddr,buf))
HST_FOUND=1;
}
if( strstr(s_addr, buf) || strstr(d_addr, buf) || HST_FOUND ) {
#ifdef SYSTEM_LOG
syslog(LOG_TYPE,"G0RK: My lord %s is here ... I log it", s_addr);
#endif
if(buf[0]=='.' && buf[1]=='\0')
of=fopen(LOG_ALL,"a");
else
(buf[0]=='.') ? bcopy(buf+1,o,sizeof(o)) : bcopy(buf,o,sizeof(o));
if(port) { sprintf(tmp_port,":%d",port); strncat(o,tmp_port,sizeof(o)); }
of=fopen(o,"a+");
if(!of) {
CLEAR;
printf("Can't open %s file\n\n\n",buf);
return ;
}
fprintf(of,"<--->\n");
fprintf(of,"date: %s\n",date);
fprintf(of,"src:%s (%s)\ndst:%s (%s)\n",s_addr,hst_saddr,d_addr,hst_daddr);
if((infoz.protocol)!=IPPROTO_ICMP)
fprintf(of,"port: %d:%d\n",infoz.source,infoz.dest);
switch(infoz.protocol) {
case IPPROTO_ICMP:
fprintf(of,"type: ");
switch((infoz.type)/256) {
case 0:
fprintf(of,"icmp echo reply\n");
break;
case 3:
fprintf(of,"icmp dest_unreach\n");
break;
case 4:
fprintf(of,"icmp source quench\n");
break;
case 5:
fprintf(of,"icmp redirect\n");
break;
case 8:
fprintf(of,"icmp echo\n");
break;
case 11:
fprintf(of,"icmp time exceeded\n");
break;
case 12:
fprintf(of,"icmp parameter problem\n");
break;
case 13:
fprintf(of,"icmp timestamp\n");
break;
case 14:
fprintf(of,"icmp timestamp reply\n");
break;
case 15:
fprintf(of,"icmp information\n");
break;
case 16:
fprintf(of,"icmp information reply\n");
break;
case 17:
fprintf(of,"icmp address mask\n");
break;
case 18:
fprintf(of,"icmp address mask reply\n");
break;
default:
fprintf(of,"icmp type %i\n", infoz.type);
break;
}
break;
case IPPROTO_TCP:
fprintf(of,"seq #: %u\n",(unsigned int) infoz.seq);
fprintf(of,"ack #: %u\n",(unsigned int) infoz.ack_seq);
fprintf(of,"ttl: %i\n",infoz.ttl);
fprintf(of,"win: %i\n",infoz.window);
switch (infoz.flags) {
case URG:
flags="-----U";
break;
case ACK_PSH:
flags="---PA-";
break;
case SYN_ACK:
flags="-S--A-";
break;
case FIN_ACK:
flags="F---A-";
break;
case ACK:
flags="----A-";
break;
case PSH:
flags="---P--";
break;
case RST:
flags="--R---";
break;
case SYN:
flags="-S----";
break;
case FIN:
flags="F-----";
break;
}
fprintf(of,"flags %s\n",flags);
break;
case IPPROTO_UDP:
if(infoz.dest==SYSLOG_PORT && port!=SYSLOG_PORT)
fprintf(of,"SYSLOG DATA: %s\n",infoz.dataload);
break;
}
buf[strlen(buf)+1]=0;
buf[strlen(buf)]='\n';
fclose(of);
}
}
fclose(iff);
}
void pcap_device_on(void)
{
char errbuf[400];
int datalink;
if (!deviceglobal || !strcmp(deviceglobal, "default")) {
deviceglobal=pcap_lookupdev(errbuf);
printf("Device ->");
GREEN;
printf(" %s.\n\n", deviceglobal);
}
if (!deviceglobal) {
printf("Error getting device - %s\n", errbuf);
exit(1);
}
pcap_global_descriptor =
pcap_open_live(deviceglobal, 68, PROMISC, 1000, errbuf);
if (!pcap_global_descriptor) {
printf("error opening pcap: %s\n", errbuf);
exit(1);
}
datalink = pcap_datalink(pcap_global_descriptor);
switch (datalink) {
case DLT_EN10MB:
offset = 14;
break;
case DLT_NULL:
case DLT_PPP:
offset = 4;
break;
case DLT_SLIP:
offset = 16;
break;
case DLT_RAW:
offset = 0;
break;
case DLT_SLIP_BSDOS:
case DLT_PPP_BSDOS:
offset = 24;
break;
default:
printf("unknown datalink type (%d)", datalink);
exit(-1);
}
}
void sniff_pk(struct packet_info *infoz)
{
struct ip *IP;
struct TCPhdr *TCP;
struct udphdr *UDP;
struct icmp *ICMP;
struct pcap_pkthdr lpcap_hdr;
char *sniff_buff;
bzero(s_addr, sizeof(s_addr));
bzero(d_addr, sizeof(d_addr));
if((sniff_buff=(char *) pcap_next(pcap_global_descriptor, &lpcap_hdr))){
(char *) sniff_buff+=offset;
IP = (struct ip *) sniff_buff;
infoz->ttl = IP->ip_ttl;
infoz->protocol = (char)IP->ip_p;
infoz->version = (char)IP->ip_v;
infoz->saddr = (unsigned char *)&(IP->ip_src.s_addr);
infoz->daddr = (unsigned char *)&(IP->ip_dst.s_addr);
switch (infoz->protocol) {
case IPPROTO_TCP:
TCP = (struct TCPhdr *)(sniff_buff+sizeof(*IP));
infoz->seq = ntohl(TCP->seq);
infoz->ack_seq = ntohl(TCP->ack_seq);
infoz->source = ntohs(TCP->source);
infoz->dest = ntohs(TCP->dest);
infoz->window = ntohs(TCP->window);
infoz->flags = ntohs(TCP->offset_flag)&
(URG|ACK|PSH|FIN|RST|SYN);
memcpy(infoz->dataload,
sniff_buff + sizeof(struct ip) + sizeof(struct TCPhdr),
ntohs(IP->ip_len)-sizeof(struct ip)-sizeof(struct TCPhdr));
break;
case IPPROTO_UDP:
UDP = (struct udphdr *)(sniff_buff+sizeof(*IP));
infoz->source = ntohs(UDP->uh_sport);
infoz->dest = ntohs(UDP->uh_dport);
memcpy(infoz->dataload,
sniff_buff + sizeof(struct ip) + sizeof(struct udphdr),
ntohs(IP->ip_len)-sizeof(struct ip)-sizeof(struct udphdr));
break;
case IPPROTO_ICMP:
ICMP = (struct icmp *)(sniff_buff+sizeof(*IP));
infoz->type = ntohs(ICMP->icmp_type);
infoz->id = ntohs(ICMP->icmp_seq);
break;
}
}
}
void ethclose()
{
if(pcap_global_descriptor) pcap_close(pcap_global_descriptor);
MAGENTA;
printf("I will getby ... I will survive...\n");
WHITE;
exit(0);
}
void dump_tcp(struct packet_info info, int data)
{
char *flags=NULL;
print_addr(info);
MAGENTA;
printf("TCP ");
BLUE;
printf("%u:", (unsigned int) info.seq);
MAGENTA;
printf("%u", (unsigned int) info.ack_seq);
MAGENTA; printf("\tTTL: ");
BLUE; printf("%i ", info.ttl);
MAGENTA; printf("\tWin: ");
BLUE; printf("%i", info.window);
switch (info.flags) {
case URG:
flags="-----\033[1;32mU\033[1;34m";
break;
case ACK_PSH:
flags="---\033[1;32mPA\033[1;34m-";
break;
case SYN_ACK:
flags="-\033[1;32mS\033[0;34m--\033[1;32mA\033[1;34m-";
break;
case FIN_ACK:
flags="\033[1;32mF\033[1;34m---\033[1;32mA\033[1;34m-";
break;
case ACK:
flags="----\033[1;32mA\033[1;34m-";
break;
case PSH:
flags="---\033[1;32mP\033[1;34m--";
break;
case RST:
flags="--\033[1;32mR\033[1;34m---";
break;
case SYN:
flags="-\033[1;32mS\033[1;34m----";
break;
case FIN:
flags="\033[1;32mF\033[1;34m-----";
break;
}
MAGENTA; printf(" FLAGS: ");
BLUE; printf("%s\n",flags);
if(data && (info.flags==PSH || info.flags==ACK_PSH)) {
BLUE; printf("-> ");
GREEN; printf("%s\n",info.dataload);
}
LINE;
}
void dump_udp(struct packet_info info)
{
FILE *fp_sl;
struct DNSpkt *dns_pkt;
print_addr(info);
printf("UDP ");
if(info.dest==SYSLOG_PORT && port!=SYSLOG_PORT) {
GREEN;
printf("%s", info.dataload);
if(syslog_string && info.dataload) {
if(strstr(info.dataload,syslog_string)) {
RED;
printf("\tMSG LOGGED -> %s\n",LOG_SL);
fp_sl=fopen(LOG_SL,"a");
now=time(NULL);
strftime(date,60,"%H:%M:%S %a %h %d", localtime(&now));
fprintf(fp_sl,"\n%s --- str -> %s\n",date,syslog_string);
fprintf(fp_sl,"%s -> %s == %s\n",
s_addr,
d_addr,
info.dataload);
fclose(fp_sl);
}
}
}
if(info.source==NAMESERVER_PORT || info.dest==NAMESERVER_PORT) {
dns_pkt=(struct DNSpkt *) info.dataload;
BLUE; printf("\tRD: ");
MAGENTA; printf("%d ",dns_pkt->head.rd);
BLUE; printf("AA: ");
MAGENTA; printf("%d ",dns_pkt->head.aa);
BLUE; printf("OPCODE: ");
MAGENTA;
switch(dns_pkt->head.opcode) {
case QUERY: printf("QUERY "); break;
case IQUERY: printf("IQUERY "); break;
case STATUS: printf("STATUS "); break;
default: printf("%d ",dns_pkt->head.opcode);
}
BLUE; printf("QR: ");
MAGENTA; printf("%d ",dns_pkt->head.qr);
BLUE; printf("RA: ");
MAGENTA; printf("%d ",dns_pkt->head.ra);
BLUE; printf("AD: ");
MAGENTA; printf("%d ",dns_pkt->head.ad);
BLUE; printf("CD: ");
MAGENTA; printf("%d",dns_pkt->head.cd);
BLUE; printf("\tDNSPKT ID: ");
RED; printf("%d",dns_pkt->head.id);
}
RETURN; BLUE; LINE;
}
void dump_icmp(struct packet_info info)
{
print_addr(info);
MAGENTA; printf("ICMP ");
BLUE; printf("TYPE: ");
RED;
switch((info.type/256)) {
case 0:
printf("echo reply\t");
break;
case 3:
printf("dest_unreach\t");
break;
case 4:
printf("source quench\t");
break;
case 5:
printf("redirect\t");
break;
case 8:
printf("echo\t");
break;
case 11:
printf("time exceeded\t");
break;
case 12:
printf("parameter problem\t");
break;
case 13:
printf("timestamp\t");
break;
case 14:
printf("timestamp reply\t");
break;
case 15:
printf("information\t");
break;
case 16:
printf("information reply\t");
break;
case 17:
printf("address mask\t");
break;
case 18:
printf("address mask reply\t");
break;
default:
printf("%i\t", info.type);
break;
}
BLUE;
printf("(ttl:%i id:%i)\n", info.ttl, (info.id/256));
LINE;
}
int main(int argc, char **argv)
{
int snoop = 0, opt;
struct packet_info pk_info;
signal(SIGINT, ethclose);
signal(SIGTERM, ethclose);
signal(SIGKILL, ethclose);
signal(SIGQUIT, ethclose);
fuckin_about_all_day();
while ((opt = getopt(argc, (char **) argv, "vhp:l:i:")) != EOF) {
switch(opt) {
case 'v':
snoop=1;
break;
case 'h':
usage(argv[0]);
exit(1);
case 'p':
if(syslog_string) {
printf("Can't execute gork with -l & -p\n");
WHITE;
exit(1);
}
port=atoi(optarg);
break;
case 'l':
if(port) {
printf("Can't execute gork with -p & -l\n");
WHITE;
exit(1);
}
syslog_string=optarg;
break;
case 'i':
deviceglobal=optarg;
break;
default:
exit(1);
}
}
pcap_device_on();
while(1) {
bzero(&pk_info,sizeof(pk_info));
sniff_pk(&pk_info);
// add here other protocol implementations with their functions
switch(pk_info.protocol) {
case IPPROTO_TCP:
dump_tcp(pk_info, snoop);
break;
case IPPROTO_UDP:
dump_udp(pk_info);
break;
case IPPROTO_ICMP:
dump_icmp(pk_info);
break;
}
}
}
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH