c - 也许是指针问题。 Linux程序+libpcap+getopt_long()+C语言

标签 c pointers getopt-long

我正在使用 libpcap 库为我的大学项目制作网络嗅探器。大多数代码都可以正常工作,但是,我遇到了以下问题。我使用 getopt_long() 函数添加了五个命令行选项,但有一个选项没有按预期工作。

选项是-d (--device_info),用于打印与接口(interface)关联的I.P addressnetmask。它有一个参数,即要为其打印信息的 interface 的名称。

程序代码的必要部分附在下面。我的问题是,即使我明确地将 interface 的名称分配给 char *device(第 35 行),然后将其作为参数传递给 print_device_info ()(第 36 行),当 print_device_info() 执行时,它总是执行 if block (第 4 行)即 char *deviceprint_device_info() 中始终等于 NULL,即使我将它作为参数传递也是如此。

我是一名初级程序员,这是我正在开发的第一个“真正的”项目。我想这是一个指针问题,但我不确定。

请您也提出一些解决方法。

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);
       }

编辑:我在这里发布了原始程序的编辑版本。这个编辑版本本身就是一个完整的程序,因此应该足以满足 future 的任何查询。

#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);

}

最佳答案

您在测试结束时有一个杂散的分号 (;)。

这意味着测试唯一控制的是一个空表达式,if 语句后面的 block 只是一个嵌套 block (将始终执行)。

关于c - 也许是指针问题。 Linux程序+libpcap+getopt_long()+C语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4013930/

相关文章:

C错误: Initialization From Incompatible Pointer Type

c - 如何使用 getopt 只解析一个选项一次

c - 为什么gdb一直显示optarg为0x0

在c中以编程方式创建圣诞树?

c - 使用 strtok() 标记字符串会导致 c 崩溃

C 重定向指针

perl - 当参数的值是 0 时,为什么我的 Perl 程序会打印帮助消息?

c - 确定用户输入值的数据类型

c++ - 如何将elasticsearch的数据保存为json格式?

c - 为什么 VS 在编译 strcpy 函数中使用的未初始化字符串时会抛出错误?