|
LQ Newbie
Registered: Oct 2011
Posts: 10
Rep: 
|
Getting interface error while running a C program
Hi,
I am running a C program which on execution will capture the network traffic and will give the network statistics..i am running the code as root by using the command--gcc sniff.c(C code) -lncurses -lpcap
The code gets compiled but on execution(by using the command ./a.out) it gives the error..
Using device: eth0
SIOCGIFADDR: Cannot assign requested address
I have also specified another interface(eth1) but gets hanged....
here is the source code....
#include <pcap.h>
#include <stdio.h>
#include <netinet/ip.h>
#include <netinet/ether.h>
#include <netinet/tcp.h>
#include <time.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <signal.h>
#include <curses.h>
#include <string.h>
#include<stdlib.h>
#define ETHERTYPE_IPX 0x8137
struct timeval *start_time;
int total_time = 0;
/* Our addresses */
struct in_addr *my_in_addr;
struct ether_addr *my_eth_addr;
char *dev;
/* Traffic so far */
int nEthTotal = 0;
int nEthSrc = 0;
int nEthDest = 0;
int nInTotal = 0;
int nInSrc = 0;
int nInDest = 0;
int nIpxTotal = 0;
int nIpxSrc = 0;
int nIpxDest = 0;
int nTcpSrc = 0;
int nTcpDest = 0;
/* Logging */
FILE *lfp;
/* Curses window */
WINDOW *mywin;
/* Libpcap entry point */
pcap_t *handle;
void sniff_packet(u_char *args,
const struct pcap_pkthdr *header,
const u_char *packet);
void parse_ethernet(struct ether_header *header, u_char *payload, int len);
void parse_ip(struct ip *header, u_char *payload, int len);
void parse_arp(struct ether_arp *header);
void parse_tcp(struct tcphdr *header);
void sig_intr(int sig);
void sig_alrm(int sig);
void printstat(int line, int t, int l, int a);
char* format_unit(double val, char buf[]);
void init_my_addr();
void init_curses();
int main(int argc, char** argv)
{
char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
struct bpf_program filter; /* The compiled filter */
char filter_app[] = "port 23"; /* The filter expression */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */
/* Define the device */
if (argc > 1)
dev = argv[1];
else {
dev = pcap_lookupdev(errbuf);
}
printf("Using device: %s\n", dev);
/* Open log device */
lfp = fopen("sniff.log", "w");
if (lfp == NULL) {
fprintf(stderr, "error: Cannot open file sniff.log\n");
exit(1);
}
/* Install signal handlers */
signal(SIGINT, sig_intr);
signal(SIGALRM, sig_alrm);
/* Find the addresses associated with this device */
init_my_addr();
printf("Ethernet (MAC)address: %s\n",
ether_ntoa((struct ether_addr *)&my_eth_addr));
printf("Internet (IP) address: %s\n",
inet_ntoa(my_in_addr));
/* Find the properties for the device */
pcap_lookupnet(dev, &net, &mask, errbuf);
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
/* Go to curses mode */
init_curses();
/** Compile and apply the filter
* pcap_compile(handle, &filter, filter_app, 0, net);
* pcap_setfilter(handle, &filter);
*/
/* Set alarm of 1 second */
alarm(1);
/* Enter loop */
pcap_loop(handle, -1, sniff_packet, NULL);
return(0);
}
void sniff_packet(u_char *args,
const struct pcap_pkthdr *header,
const u_char *packet
)
{
struct ether_header *_header = (struct ether_header*) packet;
u_char *_payload = (u_char *)(packet + sizeof(struct ether_header));
parse_ethernet(_header, _payload, header->len);
}
void parse_ethernet(struct ether_header *header,
u_char *payload,
int len)
{
u_char *_header;
u_char *_payload;
int _hl;
nEthTotal += len;
if (!memcmp(&header->ether_shost, &my_eth_addr, sizeof(my_eth_addr)))
nEthSrc += len;
if (!memcmp(&header->ether_dhost, &my_eth_addr, sizeof(my_eth_addr)))
nEthDest += len;
fprintf(lfp, " <ether_frame ");
fprintf(lfp, "src=\"%s\" ", ether_ntoa((struct ether_addr *)&header->ether_shost));
fprintf(lfp, "dest=\"%s\" ", ether_ntoa((struct ether_addr *)&header->ether_dhost));
fprintf(lfp, "type=");
switch (ntohs(header->ether_type)) {
case ETHERTYPE_IP:
_header = payload;
_hl = ((((struct ip*) _header)->ip_hl) << 2);
_payload = payload + _hl;
fprintf(lfp, "\"ip\">\n");
parse_ip((struct ip *)_header, _payload, len - _hl);
break;
case ETHERTYPE_ARP:
_header = payload;
fprintf(lfp, "\"arp\">\n");
parse_arp((struct ether_arp *)_header);
break;
case ETHERTYPE_REVARP:
fprintf(lfp, "\"rarp\">\n");
break;
case ETHERTYPE_IPX:
len -= sizeof(struct ether_header);
nIpxTotal += len;
if (!memcmp(&header->ether_shost, &my_eth_addr, sizeof(my_eth_addr)))
nIpxSrc += len;
if (!memcmp(&header->ether_dhost, &my_eth_addr, sizeof(my_eth_addr)))
nIpxDest += len;
fprintf(lfp, "\"ipx\">\n");
break;
default:
fprintf(lfp, "\"%d\">\n", header->ether_type);
}
fprintf(lfp, " </ether_frame>\n\n");
}
void parse_ip(struct ip *header,
u_char *payload,
int len)
{
nInTotal += len;
if (!memcmp(&header->ip_src, &my_in_addr, sizeof(my_in_addr)))
nInSrc += len;
if (!memcmp(&header->ip_dst, &my_in_addr, sizeof(my_in_addr)))
nInDest += len;
fprintf(lfp, " <ip_datagram ");
/* fprintf(lfp, "version=\"%d\" ", header->ip_v);*/
fprintf(lfp, "ttl=\"%d\" ", header->ip_ttl);
fprintf(lfp, "src=\"%s\" ", inet_ntoa(header->ip_src));
fprintf(lfp, "dest=\"%s\" ", inet_ntoa(header->ip_dst));
switch (header->ip_p) {
case 0:
fprintf(lfp, "protocol=\"dummy\">\n");
break;
case 1:
fprintf(lfp, "protocol=\"icmp\">\n");
break;
case 6:
if (!memcmp(&header->ip_src, &my_in_addr, sizeof(my_in_addr)))
nTcpSrc += len;
if (!memcmp(&header->ip_dst, &my_in_addr, sizeof(my_in_addr)))
nTcpDest += len;
fprintf(lfp, "protocol=\"tcp\">\n");
parse_tcp((struct tcphdr *) payload);
break;
case 12:
fprintf(lfp, "protocol=\"udp\">\n");
break;
default:
fprintf(lfp, "protocol=\"%d\">\n", header->ip_p);
break;
}
fprintf(lfp, " </ip_datagram>\n");
}
void parse_arp(struct ether_arp *header)
{
fprintf(lfp, " <arp_packet hrd=");
switch (ntohs(header->ea_hdr.ar_hrd)) {
case ARPHRD_NETROM:
fprintf(lfp, "\"netrom\" ");
break;
case ARPHRD_ETHER:
fprintf(lfp, "\"ethernet\" ");
break;
case ARPHRD_AX25:
fprintf(lfp, "\"AX.25 level 2\" ");
break;
case ARPHRD_IEEE802:
fprintf(lfp, "\"IEEE 802.2\" ");
break;
case ARPHRD_ARCNET:
fprintf(lfp, "\"arcnet\" ");
break;
case ARPHRD_DLCI:
fprintf(lfp, "\"frame relay\" ");
break;
case ARPHRD_ATM:
fprintf(lfp, "\"atm\" ");
break;
case ARPHRD_PPP:
fprintf(lfp, "\"ppp\" ");
break;
default:
fprintf(lfp, "%d ", header->ea_hdr.ar_hrd);
break;
}
fprintf(lfp, "opcode=");
switch (ntohs(header->ea_hdr.ar_op)) {
case ARPOP_REQUEST:
fprintf(lfp, "\"ARP request\">\n");
break;
case ARPOP_REPLY:
fprintf(lfp, "\"ARP reply\">\n");
break;
case ARPOP_RREQUEST:
fprintf(lfp, "\"RARP request\">\n");
break;
case ARPOP_RREPLY:
fprintf(lfp, "\"RARP reply\">\n");
break;
case ARPOP_InREQUEST:
fprintf(lfp, "\"InARP request\">\n");
break;
case ARPOP_InREPLY:
fprintf(lfp, "\"InARP reply\">\n");
break;
case ARPOP_NAK:
fprintf(lfp, "\"(ATM)ARM NAK\">\n");
break;
default:
fprintf(lfp, "\"%d\">\n", header->ea_hdr.ar_op);
break;
}
fprintf(lfp, " <sender_mac>%s</sender_mac>\n",
ether_ntoa((struct ether_addr *)header->arp_sha));
fprintf(lfp, " <sender_ip>%s</sender_ip>\n",
inet_ntoa(*(struct in_addr*) header->arp_spa));
fprintf(lfp, " <receiver_mac>%s</receiver_mac>\n",
ether_ntoa((struct ether_addr *)header->arp_tha));
fprintf(lfp, " <receiver_ip>%s</receiver_ip>\n",
inet_ntoa(*(struct in_addr*) header->arp_tpa));
fprintf(lfp, " </arp_packet>\n");
}
void parse_tcp(struct tcphdr *header)
{
fprintf(lfp,
" <tcp sport=\"%d\" dport=\"%d\" seq=\"%d\" ack=\"%d\"/>\n",
ntohs(header->source),
ntohs(header->dest),
ntohl(header->seq),
ntohl(header->ack));
}
void sig_intr(int sig)
{
delwin(mywin);
endwin();
fclose(lfp);
/* Close */
pcap_close(handle);
}
void sig_alrm(int sig)
{
static int prev_nEthTotal = 0;
static int prev_nEthSrc = 0;
static int prev_nEthDest = 0;
static int prev_nInTotal = 0;
static int prev_nInSrc = 0;
static int prev_nInDest = 0;
static int prev_nIpxTotal = 0;
static int prev_nIpxSrc = 0;
static int prev_nIpxDest = 0;
static int prev_nTcpSrc = 0;
static int prev_nTcpDest = 0;
alarm(1);
total_time += 1;
printstat(8,
nEthTotal,
nEthTotal - prev_nEthTotal,
((double)nEthTotal)/total_time);
prev_nEthTotal = nEthTotal;
printstat(9,
nEthSrc,
nEthSrc - prev_nEthSrc,
((double)nEthSrc)/total_time);
prev_nEthSrc = nEthSrc;
printstat(10,
nEthDest,
nEthDest - prev_nEthDest,
((double)nEthDest)/total_time);
prev_nEthDest = nEthDest;
printstat(11,
nInTotal,
nInTotal - prev_nInTotal,
((double)nInTotal)/total_time);
prev_nInTotal = nInTotal;
printstat(12,
nInSrc,
nInSrc - prev_nInSrc,
((double)nInSrc)/total_time);
prev_nInSrc = nInSrc;
printstat(13,
nInDest,
nInDest - prev_nInDest,
((double)nInDest)/total_time);
prev_nInDest = nInDest;
printstat(14,
nTcpSrc,
nTcpSrc - prev_nTcpSrc,
((double)nTcpSrc)/total_time);
prev_nTcpSrc = nTcpSrc;
printstat(15,
nTcpDest,
nTcpDest - prev_nTcpDest,
((double)nTcpDest)/total_time);
prev_nTcpDest = nTcpDest;
printstat(16,
nIpxTotal,
nIpxTotal - prev_nIpxTotal,
((double)nIpxTotal)/total_time);
prev_nIpxTotal = nIpxTotal;
printstat(17,
nIpxSrc,
nIpxSrc - prev_nIpxSrc,
((double)nIpxSrc)/total_time);
prev_nIpxSrc = nIpxSrc;
printstat(18,
nIpxDest,
nIpxDest - prev_nIpxDest,
((double)nIpxDest)/total_time);
prev_nIpxDest = nIpxDest;
wmove(mywin, 1, 1);
wrefresh(mywin);
}
void printstat(int line, int t, int l, int a)
{
char buf[50];
mvwaddstr(mywin, line, 41, format_unit(t, buf));
mvwaddstr(mywin, line, 49, format_unit(l, buf));
mvwaddstr(mywin, line, 57, format_unit(a, buf));
}
char* format_unit(double val, char b[])
{
char buf[15];
if (val >= 1024*1024)
sprintf(buf, "%.3g M", val/(1024*1024));
else if (val >= 1024)
sprintf(buf, "%.3g K", val/1024);
else
sprintf(buf, "%.3g", val);
sprintf(b, "%6s ", buf);
b[7] = '\0';
return b;
}
void init_my_addr()
{
int s;
struct ifreq ifr;
bzero(&ifr, sizeof(struct ifreq));
if (( s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
perror( "socket" );
exit( 1 );
}
strcpy(ifr.ifr_name, dev);
if (ioctl(s, SIOCGIFHWADDR, &ifr) == -1) {
perror("SIOCGIFHWADDR");
exit(0);
}
memcpy(&my_eth_addr, &ifr.ifr_hwaddr.sa_data, sizeof(my_eth_addr));
bzero(&ifr, sizeof(struct ifreq));
strcpy(ifr.ifr_name, dev);
if (ioctl(s, SIOCGIFADDR, &ifr) == -1) {
perror("SIOCGIFADDR");
exit(0);
}
memcpy(&my_in_addr,
& ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr, sizeof(my_in_addr));
close(s);
}
void init_curses()
{
(void) initscr(); /* initialize the curses library */
mywin = derwin(stdscr, 25, 65, 2, 6);
if (mywin == NULL) {
exit(1);
}
keypad(mywin, TRUE); /* enable keyboard mapping */
(void) nonl(); /* tell curses not to do NL->CR/NL on output */
(void) cbreak(); /* take input chars one at a time, no wait for \n */
(void) noecho(); /* don't echo input */
if (has_colors())
{
start_color();
/*
* Simple color assignment, often all we need.
*/
init_pair(COLOR_BLUE, COLOR_WHITE, COLOR_BLUE);
init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
}
wattrset(mywin, COLOR_PAIR(COLOR_BLUE));
mvwaddstr(mywin, 1, 1,
" Packet capture statistics ");
wattrset(mywin, A_BOLD | COLOR_PAIR(COLOR_WHITE));
mvwaddstr(mywin, 3, 5, " Ethernet device: ");
mvwaddstr(mywin, 3, 35, dev);
mvwaddstr(mywin, 4, 5, " Hardware (MAC) address: ");
mvwaddstr(mywin, 4, 35, ether_ntoa((struct ether_addr *)&my_eth_addr));
mvwaddstr(mywin, 5, 5, " Internet (IP) address: ");
mvwaddstr(mywin, 5, 35,(char *)inet_ntoa(my_in_addr));
wattrset(mywin, COLOR_PAIR(COLOR_WHITE) | A_REVERSE);
mvwaddstr(mywin, 7, 1,
" TOT LAST AVG ");
wstandend(mywin);
mvwaddstr(mywin, 8, 2, " Total ethernet traffic on wire:");
mvwaddstr(mywin, 9, 2, " Incoming ethernet traffic:");
mvwaddstr(mywin, 10, 2, " Outgoing ethernet traffic:");
mvwaddstr(mywin, 11, 2, " Total IP traffic:");
mvwaddstr(mywin, 12, 2, " Incoming IP traffic:");
mvwaddstr(mywin, 13, 2, " Outgoing IP traffic:");
mvwaddstr(mywin, 14, 2, " Incoming TCP traffic:");
mvwaddstr(mywin, 15, 2, " Outgoing TCP traffic:");
mvwaddstr(mywin, 16, 2, " Total IPX/SPX traffic:");
mvwaddstr(mywin, 17, 2, " Incoming IPX/SPX traffic:");
mvwaddstr(mywin, 18, 2, " Outgoing IPX/SPX traffic:");
wrefresh(mywin);
}
|