/*
nast
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 "include/nast.h"
/* prototypes */
void sniff (int d, int x, FILE *output, FILE *ldd);
int run_sniffer (u_short promisc, u_short data, u_short hex, u_short f, u_short l, u_short tcpdlog, u_short tcpdread, char *filter, char *dev, char *ldname);
/* plugin to run sniffer */
int run_sniffer (u_short promisc, u_short data, u_short hex, u_short f, u_short l, u_short tcpdlog, u_short tcpdread, char *filter, char *dev, char *ldname)
{
char *mask;
char errbuf[PCAP_ERRBUF_SIZE];
libnet_t *L;
int ld;
struct libnet_ether_addr *e;
struct in_addr addr;
/* log data FILE descriptor */
FILE *ldd;
ldd = NULL;
ld = 0;
npkt = 0;
if (strcmp (ldname, "NULL")) /* != NULL */
(ld=1);
/* ask pcap for the network address and mask of the device */
if ((pcap_lookupnet(dev,&netp,&maskp,errbuf))==-1)
{
w_error(1, "pcap_lookupnet error: %s\n\n", errbuf);
}
if (tcpdlog) /* write in tcdl file in tcpdump log format */
{
if ((descr = pcap_open_live (dev, BUFSIZ, promisc, 10, errbuf))==NULL)
{
w_error(1, "pcap_open_live() error: %s\n\n",errbuf);
}
if ((dumper = pcap_dump_open(descr,tcpdl))==NULL)
{
w_error(1, "pcap_dump_open() error: %s\n\n",errbuf);
}
}
else if(tcpdread) /* read from tcpdl file */
{
if ((descr = pcap_open_offline(tcpdl,errbuf))==NULL)
{
w_error(1, "pcap_open_offline() error: %s\n\n",errbuf);
}
}
/* normal case */
else if ((descr = pcap_open_live (dev, BUFSIZ, promisc, 10, errbuf))==NULL)
{
w_error(1, "pcap_open_live() error: %s\n\n",errbuf);
}
if ((offset=(device(dev,descr)))==-1) return -1;
L = libnet_init (LIBNET_LINK, dev, errbuf);
e = libnet_get_hwaddr(L);
if (!e)
{
w_error(1, "Can't get hardware address: %s\n\n", libnet_geterror(L));
}
addr.s_addr = maskp;
if ((mask = inet_ntoa(addr))==NULL)
{
w_error(1, "Impossible get the mask\n\n");
}
if(!graph)
{
printf("%sSniffing on:\n\n%s", CYAN, NORMAL);
printf("%s- Device:\t%s%s\n",BOLD, NORMAL, dev);
printf("%s- MAC address:\t%s%s\n", BOLD, NORMAL, nast_hex_ntoa (e->ether_addr_octet));
printf("%s- IP address:\t%s%s\n", BOLD, NORMAL, libnet_addr2name4(libnet_get_ipaddr4(L), 0));
printf("%s- Netmask:\t%s%s\n",BOLD, NORMAL, mask);
printf("%s- Promisc mode:\t%s", BOLD, NORMAL);
if (promisc) printf("Set\n");
else printf("Not set\n");
printf ("%s- Filter:\t%s", BOLD, NORMAL);
if (filter) printf("%s\n", filter);
else printf("None\n");
printf("%s- Logging:\t%s", BOLD, NORMAL);
if (!ld && !l) printf ("None\n");
else if (ld && !l) printf ("Sniffed data\n");
else if (!ld && l) printf ("Traffic\n");
else if (ld && l) printf ("Traffic and Sniffed data\n");
}
/* log all packets */
if (l)
{
openfile();
fprintf(logd, "NAST SNIFFER LOGGING REPORT\n");
fprintf(logd, "Made on %s, device %s (%s)\n\n", timed, dev, libnet_addr2name4(libnet_get_ipaddr4(L), 0));
}
/* log only data */
if (ld)
{
if ((ldd = (fopen(ldname,"w"))) == NULL)
{
w_error(1, "\nError: unable to open logfile descriptor: %s\n\n", strerror(errno));
}
fprintf(ldd, "NAST SNIFFED DATA REPORT\n");
fprintf(ldd, "Made on %s, device %s (%s)\n\n", timed, dev, libnet_addr2name4(libnet_get_ipaddr4(L), 0));
}
libnet_destroy(L);
if (f)
{
if(pcap_compile(descr,&fp,filter,0,netp) == -1)
{
if(w_error(0, "Error in pcap_compile, insert a different filter\n")==-1)
return(0);
}
if(pcap_setfilter(descr,&fp) == -1)
{
w_error(1, "Error calling pcap_setfilter\n\n");
}
}
/* demonize only now */
if (demonize)
bkg();
/* sniff here */
while(1)
{
(packet = (u_char *) pcap_next (descr, &hdr));
if(packet==NULL)
continue;
++npkt;
if (!ldname)
sniff (data, hex, stdout, NULL);
/* print to stdout and write to data file*/
/* this works also for tcpdump read file!! */
else
{
sniff (data, hex, stdout, ldd);
fflush (ldd);
}
if (l)
{
sniff (data, hex, logd, NULL); /* log packets to file */
fflush (logd);
}
if (tcpdlog)
{
fflush((FILE *)dumper);
pcap_dump((u_char *)dumper,&hdr,packet);
}
}
if (l)
fclose (logd);
if (ldname)
fclose (ldd);
return 0;
}
/* sniffer function heandler */
void sniff (int d, int x, FILE *output, FILE *ldd)
{
struct libnet_ipv4_hdr *ip;
u_int16_t type;
type = handle_ethernet (packet);
if ((type==ETHERTYPE_ARP) || (type==ETHERTYPE_REVARP))
handle_ARP(output);
ip = (struct libnet_ipv4_hdr *) (packet+offset);
switch(ip->ip_p)
{
case IPPROTO_TCP:
handle_TCP (d, x, output, ldd);
break;
case IPPROTO_UDP:
handle_UDP (d, x, output, ldd);
break;
case IPPROTO_ICMP:
handle_ICMP (d, x, output, ldd);
break;
case IPPROTO_IGMP:
handle_IGMP (output);
break;
}
}
syntax highlighted by Code2HTML, v. 0.9.1