0

EDIT: the solution is on the bottom of the page maybe. I answered my question with the solution. I hope this helps the others.

I'm having here in linux a little problem. I'm programming a simple port scan but I'm having a problem with the function that takes the arguments.

I will explain on the code:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>

//this function handle the arguments.

char* ret[2]= {"NULL","NULL"}; //declaring this in global because of segmention fault?

char** arguments_handle(int argc,char **arg)
{
    if(argc!=5)
    {
        printf("Usage:./file -p PORT-RAGE -h HOST.IP\n");
        exit(1);
    }
    //make sure the user type the correct arguments. in this case just -h and -p
    if(strcmp(arg[1],"-p")==0 || strcmp(arg[1],"-h")==0 && strcmp(arg[3],"-p")==0 || strcmp(arg[3],"-h")==0)
    {
        //if in the arguments we got -h or -p run this
        //if is -p
        if(strcmp(arg[1],"-p")==0)
        {
            //take the next argument in this case is the port range and put in our array
            strcpy(ret[0],arg[2]);
        }
        else
        {
            strcpy(ret[1],arg[2]);
        }
        if(strcmp(arg[3],"-h")==0)
        {
            //now for the -h
            strcpy(ret[1],arg[4]);
        }
        else
        {
            strcpy(ret[0],arg[4]);
        }
    }
    return ret;
}
int main(int argc, char **argv)
{
    char** ipnport;
    ipnport = arguments_handle(argc,argv);
    printf("IP is :%s port range is %s\n",ipnport[0],ipnport[1]);
    //the rest of the code about port scan goes here. I'm just cutting
    return 0x0;
}

The problem here is that I can compile right but I got Segmentation fault. I can't see where I'm wrong. I guess it is about something deal with buffer or stack overflow.

So what I'm doing here in this function is taking the argv and sending it to arguments_handle function. What that does is see where is the arguments "-p" and "-h" and "store" that in the right order in an array of char. Like this char: "char pointer to this array that contains an array of chars"

                    pointer     pointer    pointer
pointer to this-> ["firstarg","secondarg","etc"]

In that case, the "pointer pointer pointer" will be the first char of the string.

Summarizing: I want to make a string array and return that from arguments_handle to the main's function.

Any ideas? :)

Sincerely,

int3

2
  • You're accessing ret beyond the bounds of the array resulting in undefined behavior. Commented Nov 4, 2013 at 22:53
  • I think your strcpy is the problem. Look at the answer posted by Mysticial Commented Nov 4, 2013 at 22:55

2 Answers 2

1

The problem is that you are not allocating the correct memory space for the strings you getting from the command line.

char* ret[2]= {"NULL","NULL"};

This creates an array with two strings of size 4 + end character ('\0'). Is this what you wanted? Or you want to create two NULL pointers. What happens if the size of the input string is bigger than 4? You might access a wrong memory which causes a segmentation fault. In addition, you should not use strcpy or strcmp but strncpy and strncmp.

The code should be change as follows :

    char * ret[2];

    if(strncmp(arg[3],"-h", 3)==0)
    {   
        string_size = strlen(arg[4]) + 1; 
        ret[1]= malloc(sting_size); 
        memset(ret[1], 0, string_size); 
        strncpy(ret[1],arg[4], string_size);
        // or ret[1]=arg[4] as suggested by Roland
    }

However, there is not need for writing a parser for input parameters as the function getopt does this for you. This is the manual with a good example at the end : http://man7.org/linux/man-pages/man3/getopt.3.html

A quick example for your code:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>

#define NUMBER_ARGUMENTS 2 
#define IP 1
#define PORT 0

char* ret[NUMBER_ARGUMENTS];  

int main(int argc, char **argv)
{
    int opt; 

    while ((opt = getopt(argc, argv, "p:h:")) != -1) {
               switch (opt) {
               case 'p':
                    ret[PORT]=optarg; 
                   break;
               case 'h':
                    ret[IP]=optarg; 
                   break;
               default: /* '?' */
                   fprintf(stderr, "Usage: %s -p PORT -h HOST\n",
                           argv[0]);
                   exit(EXIT_FAILURE);
               }
    } 
    printf("IP is :%s port range is %s\n",ret[IP],ret[PORT]);
    //the rest of the code about port scan goes here. I'm just cutting
    return 0x0;
}
Sign up to request clarification or add additional context in comments.

6 Comments

+1 for mentioning getopt, -1 for strncpy. Simply assigning argv[i] to a const char *hostname and a const char *portrange is easier.
Really? malloc? strlen? strncpy? Skip all that crud and use std::string.
@Captain Obvlious I'm programming C not C++. :) there are no namespaces eheh
@int3 Then don't tag your question C++ if you're expecting a C only answer.
I have updated my answer. I hope it is useful. @RolandIllig, yes you are right. That s the easiest solution and I used in my code example. Thanks for the suggestion.
|
1

I resolved the problem!

Thanks a lot Giuseppe Pes! I'm not used to malloc and memset and stuff. But that solves the problem. I knew it was trying to put data where it shouldn't :D

Here is my final code:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>

//this function handle the arguments.

//well i didnt edit strcpy and strcmp to strncpy yet but I will :D

char* ret[2]; //GLOBAL ofc.

char** arguments_handle(int argc,char **arg)
{
    if(argc!=5)
    {
        printf("Usage:./file -p PORT-RAGE -h HOST.IP\n");
        exit(1);
    }
    //make sure the user type the correct arguments. in this case just -h and -p
    if(strcmp(arg[1],"-p")==0 || strcmp(arg[1],"-h")==0 && strcmp(arg[3],"-p")==0 || strcmp(arg[3],"-h")==0)
    {
        //if in the arguments we got -h or -p run this
        //if is -p
        if(strcmp(arg[1],"-p")==0)
        {
            //take the next argument in this case is the port range and put in our array
            strcpy(ret[0],arg[2]);
        }
        else
        {
            strcpy(ret[1],arg[2]);
        }
        if(strcmp(arg[3],"-h")==0)
        {
            //now for the -h
            strcpy(ret[1],arg[4]);
        }
        else
        {
            strcpy(ret[0],arg[4]);
        }
    }
    return ret;
}
int main(int argc, char **argv)
{
    //tested on windows we need to put a cast before malloc
    //in linux it works fine on my raspberrypi !! :D
    ret[0] = (char*)malloc(20); //some compilers maybe will throw here an error
    ret[1] = (char*)malloc(20); //because malloc returns a void pointer and ret is a char*

    memset(ret[0],0,20);
    memset(ret[1],0,20);

    char** ipnport;
    ipnport = arguments_handle(argc,argv);
    printf("IP is :%s port range is %s\n",ipnport[1],ipnport[0]);
    //the rest of the code about port scan goes here. I'm just cutting
    return 0x0;
}

Thanks again and I hope this code will help some other people seeing this post :)

Sincerely,

int3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.