1

I know this topic has probably been done to death, but I've been unable to find anything that made me understand it. I need to enter a value, for instance an IP address, into the command line and pass it to a function.

Below is my getopt_long function.

while (1)
{
    static struct option long_options[] =
    {
        /* Options */
    {"send",       no_argument,       0, 's'}, /* args s and r have no function yet */
    {"recieve",    no_argument,       0, 'r'},
    {"file",       required_argument, 0, 'f'}, 
    {"destip",     required_argument, 0, 'i'},
    {"destport",   required_argument, 0, 'p'},
    {"sourceip",   required_argument, 0, 'o'},
    {"sourceport", required_argument, 0, 't'},
    {0, 0, 0, 0}
    };

   int option_index = 0;

   c = getopt_long (argc, argv, "srf:d:i:p:o:t:",
                long_options, &option_index);

              /* Detect the end of the options. */
   if (c == -1)
     break;

   switch (c)
     {
     case 0:
       /* If this option set a flag, do nothing else now. */
       if (long_options[option_index].flag != 0)
         break;
       printf ("option %s", long_options[option_index].name);
       if (optarg)
         printf (" with arg %s", optarg);
       printf ("\n");
       break;

     case 's':
       puts ("option -s\n");
       break;

     case 'r':
       puts ("option -r\n");
       break;

     case 'f':
       printf ("option -f with value `%s'\n", optarg);
       break;

     case 'i':
       printf ("option -i with value `%s'\n", optarg);
       break;

     case 'p':
       printf ("option -p with value `%s'\n", optarg);
       break;

     case 'o': 
       printf ("option -o with value `%s'\n", optarg);
       break;

     case 't': 
       printf ("option -t with value `%s'\n", optarg);
       break;

     case '?':
       /* Error message printed */
       break;

     default:
       abort ();
     }
}

/* Print any remaining command line arguments (not options). */
if (optind < argc)
{
    printf ("non-option ARGV-elements: ");
    while (optind < argc)
    printf ("%s ", argv[optind++]);
    putchar ('\n');
}

This is where I need the value to go (part of a pretty standard tcp struct)

ip->iph_sourceip = inet_addr(arg);

How do I do this correctly? I researched quite a bit, and although many cover similar topics they do not seem to explain my issue all too well.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
youjustreadthis
  • 622
  • 3
  • 9
  • 24
  • 1
    you appear to have everything that you need? In the `switch` case for the `i` argument, `ip->iph_sourceip = inet_addr(optarg);`, or store that `optarg` in another variable to be passed to your packet setup later? – pb2q Jul 18 '12 at 21:39
  • I see... well stupid me then, haha. But do I have to remove `ip->iph_sourceip = inet_addr(optarg);` in the send_tcp function, or should that be a duplicate of the i switch case? @pb2q – youjustreadthis Jul 18 '12 at 22:29

1 Answers1

1

When using getopt, you'll typically declare variables that match the various switches, so that you can act on them later, once argument parsing has completed; some arguments you can act on immediately during argument processing.

For instance you might have an address variable for storing the address from the -i command, similarly for the -p argument:

in_addr_t address;
int port;

// ... later in your switch statement:
switch (c)
{
    // ...

   case 'i':
       printf("option -i with value `%s'\n", optarg);
       address = inet_addr(optarg);
       break;
   case 'p':
       printf("option -p with value `%s'\n", optarg);
       // be sure to add handling of bad (non-number) input here
       port = atoi(optarg);
       break;
    // ...
}

// later in your code, e.g. after arg parsing, something like:
send_tcp(address, port);
pb2q
  • 58,613
  • 19
  • 146
  • 147
  • OK, that seems to answer my question very nicely. Thanks :) just one more thing. This is the first time I've seen `in_addr_t`. What does that do? @pb2q – youjustreadthis Jul 18 '12 at 23:56
  • abstract type representing an ip address, returned by the `inet_addr` function, which takes the dotted string representation and converts it into the `in_addr_t` type. – pb2q Jul 18 '12 at 23:57
  • you'll get `in_addr_t` as well as the `inet_addr` function by including `inet.h`. `iph_sourceip` from your example is of type `in_addr_t`. – pb2q Jul 19 '12 at 00:00
  • So say I needed to change a port using the htons function. I would need something similar? (sorry if I come across a bit thick but it's quite a bit for a rather new hobby programmer to get my head around.) @pb2q edit: I have included and . Will those do the trick? – youjustreadthis Jul 19 '12 at 00:04
  • yes for any argument that you need to act on later make a variable, as you're moving through the arguments, unless you can act on the argument immediately. so in your case you'll probably also have a variable for port, I'll edit the answer. Sorry not sure what you mean about using `htons`. Post new questions as you get farther and need additional help with specific issues, rather than asking more here using comments. – pb2q Jul 19 '12 at 00:11