I'm making a network sniffer for my college project using the libpcap
library. Majority of the code works without any problem, however, I'm stuck with the following issue. I've added five command line options using getopt_long()
function, but one option doesn't work as expected.
The option is -d (--device_info)
and is used to print the I.P address
and netmask
associated with an interface. It takes one argument, which is the name of the interface
for which the information is to be printed.
The necessary portion of the code from the program is attached below. My problem is that even though I'm explicitly assigning the name of the interface
to char *device
(line 35) and then passing that as an argument to print_device_info()
(line 36), when print_device_info()
executes, it always executes the if
block (line 4) i.e char *device
is always equal to NULL
in print_device_info()
even though I pass it as an argument.
I'm a beginner programmer and this is the first "real" project I'm developing. I guess it's a pointer issue but I'm not sure.
Kindly, also suggest some method to solve it.
1) //Prints information associated with an interface.
2) void print_device_info(char *device)
3) {
...
...
...
4) if(device == NULL);
5) {
6) fprintf(stdout, "No interface specified \n");
7) exit(1);
8) }
...
...
...
9) }
10) int main(int argc, char *argv[])
11) {
12) int next_option; // Options
13) char *device=NULL; // NIC to sniff packet from.
14) // A string listing valid short options letters.
15) const char* const short_options = "ho:i:d:p";
16) /* An array describing valid long options. */
17) const struct option long_options[] =
18) {
19) { "help", 0, NULL, 'h' },
20) { "output", 1, NULL, 'o' },
21) { "interface", 1, NULL, 'i' },
22) { "device_info", 1, NULL, 'd' },
23) { "promisc_off", 0, NULL, 'p' },
24) { NULL, 0, NULL, 0 } /* Required at end of array. */
25) };
26) //Check the arguments and perform their respective functions
27) do {
28) next_option = getopt_long (argc, argv, short_options,
29) long_options, NULL);
30) switch (next_option)
31) {
32) case 'd': /* -d or --device_info */
33) /* User has requested information associated an interface. Print it to standard
34) output, and exit with exit code zero (normal termination). */
35) device = optarg;
36) print_device_info (device);
37) }
38) }while (next_option != -1);
}
Edit: Here I'm posting an edited version of the original program. This edited version is a complete program in itself, so should be sufficient for any future queries.
#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//Prints information associated with an interface.
void print_device_info(char *device)
{
struct in_addr addr_struct; //Stores I.P address.
char *ipaddr=NULL; //Points to I.P address in dotted-decimal form.
char *netmask=NULL; //Points to Netmask in dotted-decimal form.
int ret; //Return code (Useful for error detection).
bpf_u_int32 tmpip; // Stores I.P address temporarily in host-byte (little-endian) order.
bpf_u_int32 tmpmask;// Stores Netmask temporarily in host-byte (little-endian) order.
char errbuf[PCAP_ERRBUF_SIZE]; // Stores error messages.
printf("%s\n",device);
if(device==NULL);
{
fprintf(stdout, "No interface specified \n");
exit(1);
}
/*Lookup device info and store the return value in ret */
ret = pcap_lookupnet(device, &tmpip, &tmpmask, errbuf);
//error checking
if(ret==-1)
{
fprintf(stderr, "Couldn't find IP address and subnet mask: %s\n", errbuf);
exit(1);
}
//Calculate IP address
addr_struct.s_addr=tmpip;
ipaddr=inet_ntoa(addr_struct);
//error checking.
if(ipaddr==NULL)
{
perror("Error in locating the I.P address");
exit(1);
}
//Print the IP address
printf("IP address: %s\n",ipaddr);
//Calculate subnet mask
addr_struct.s_addr=tmpmask;
netmask=inet_ntoa(addr_struct);
//error checking.
if(netmask==NULL)
{
perror("Error in locating the subnet mask");
exit(1);
}
//Print the subnet mask
printf("Subnet mask: %s\n",netmask);
exit(0);
}
int main(int argc, char *argv[])
{
//A) Declarations -----------------------------------------------------------------------------------------------------
int next_option; // Options
char *device=NULL; // NIC to sniff packet from.
char errbuf[PCAP_ERRBUF_SIZE]; // Stores error messages.
// A string listing valid short options letters.
const char* const short_options = "i:d:";
/* An array describing valid long options. */
const struct option long_options[] =
{
{ "interface", 1, NULL, 'i' },
{ "device_info", 1, NULL, 'd' },
{ NULL, 0, NULL, 0 } /* Required at end of array. */
};
//Check the arguments and perform their respective functions
do {
next_option = getopt_long (argc, argv, short_options,
long_options, NULL);
switch (next_option)
{
case 'i': /* -i or --interface */
/* User has specified the NIC device to sniff from */
device = optarg;
break;
case 'd': /* -d or --device_info */
/* User has requested information associated an interface. Print it to standard
output, and exit with exit code zero (normal termination). */
device = optarg;
printf("%s\n",device);
print_device_info (device);
case -1: /* Done with options. */
break;
default: /* Something else: unexpected. */
abort ();
}
}
while (next_option != -1);
//B)Lookup device
if (device == NULL)
{
device=pcap_lookupdev(errbuf);
//Check for error
if(device==NULL)
{
fprintf(stderr, "Couldn't find device %s\n",errbuf);
return(2);
}
}
//Print Device
printf("Device: %s\n", device);
}