0

libpcapライブラリを使用して、大学のプロジェクト用のネットワークスニファを作成しています。コードの大部分は問題なく動作しますが、私は次の問題で立ち往生しています。関数を使用して5つのコマンドラインオプションを追加しましgetopt_long()たが、1つのオプションが期待どおりに機能しません。

このオプションは、インターフェイスに関連付けられたおよび-d (--device_info)を印刷するために使用されます。情報が印刷される対象の名前である1つの引数を取ります。I.P addressnetmaskinterface

プログラムのコードの必要な部分を以下に添付します。私の問題は、interfacetoの名前を明示的に割り当て(35行目)、それを引数として(36行目)にchar *device渡しても、実行すると常にブロック(4行目)が実行されることです。つまり、常に次のようになります。私はそれを引数として渡しますが。print_device_info()print_device_info()ifchar *deviceNULLprint_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);

}
4

2 に答える 2

3

;テストの最後にセミコロン ( ) があります。

これは、テストによって制御される唯一のものは空の式であり、ステートメントに続くブロックifはネストされたブロック (常に実行される) であることを意味します。

于 2010-10-25T12:13:29.980 に答える
2

arg-readingループから抜け出すようにコードを変更しましたが、期待どおりに機能します。

$ ./longopt(null)$
./longopt
-d eth0
eth0

コードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>


int main(int argc, char *argv[])
{ 
    int next_option; // Options
    char *device=NULL; // NIC to sniff packet from.

    // A string listing valid short options letters.
    const char* const short_options = "ho:i:d:p";

    /* An array describing valid long options. */
    const struct option long_options[] = 
        {
            { "help",        0, NULL, 'h' },
            { "output",      1, NULL, 'o' },
            { "interface",   1, NULL, 'i' },
            { "device_info", 1, NULL, 'd' },
            { "promisc_off", 0, NULL, 'p' },
            { NULL,          0, NULL,  0  } /* Required at end of array. */
        };

    //Check the arguments and perform their respective functions
    while(1) {
        next_option = getopt_long (argc, argv, short_options,
                                   long_options, NULL);
        if (next_option == -1)
            break;


        switch (next_option)
        {
            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);

    return(0);

}
于 2010-10-25T11:38:08.333 に答える