Я делаю сетевой анализатор для своего проекта в колледже, используя библиотеку libpcap
.Большая часть кода работает без проблем, однако я застрял в следующей проблеме.Я добавил пять опций командной строки, используя функцию getopt_long()
, но одна опция не работает должным образом.
Опция -d (--device_info)
и используется для печати связанных I.P address
и netmask
с интерфейсом.Он принимает один аргумент - имя interface
, для которого должна быть напечатана информация.
Необходимая часть кода из программы прилагается ниже.Моя проблема в том, что, хотя я явно назначаю имя interface
для char *device
(строка 35), а затем передаю его в качестве аргумента print_device_info()
(строка 36), когда print_device_info()
выполняется, оно всегдавыполняет блок if
(строка 4), т.е. char *device
всегда равен NULL
в print_device_info()
, даже если я передаю его в качестве аргумента.
Я начинающий программист, и этоПервый «настоящий» проект я разрабатываю.Я предполагаю, что это проблема с указателем, но я не уверен.
Пожалуйста, также предложите какой-нибудь метод для ее решения.
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);
}
Редактировать: Здесь я публикую отредактированную версиюоригинальная программа.Эта отредактированная версия сама по себе является законченной программой, поэтому ее должно быть достаточно для любых будущих запросов.
#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);
}