-1

I read a lot of posts before asking this question unfortunatly none of them gave me the required solution for my problem. I am writing a mpi program with gnu c and try to execute hping3 inside a previous child process. Actual status is, that i can spawn a child, maybe execute the hping3 command, but the piped output of the child gives me the following error message which could be from hping3:

"you must specify only one target host at a time"

I did the following: First i created loads of char-arrays to fill in my params. Why the arrays? I want to change port and ip during runtime (iteration loop)

//Parameter list for hping3 fork, maxlength precalculated (tcp restrictions and given params for hping)
char sudo[] = "/usr/bin/sudo";
char path[] = "/usr/sbin/hping3";
char scan[] = "--scan";
char port[] = "65535";
char ip[] = "192.168.111.111";
char verbose[] = "-V";
char *params[7];
params[0]=sudo;
params[1]=path;
params[2]=scan;
params[3]=port;
params[4]=ip;
params[5]=verbose;
params[6]=NULL;

Change of params looks like this:

sprintf(*(params + 3), "%u", *(portarray+i));
sprintf(*(params + 4), "%u.%u.%u.%u", (iterator & 0xFF000000)>>24, (iterator & 0x00FF0000)>>16, (iterator & 0x0000FF00)>>8, (iterator & 0x000000FF));

And finally the fork.

if(pid == -1){
               perror("Error forking");
            } else if(pid > 0){
               //Parent does not write
               close(pipes[1]);
               //Status Message
               printf("Pipe Output ...");
                fflush(stdout);
               //Parent, wait for child
               //waitpid(pid, &status, 0);
               //Save stdout from pipe
               while((nbytes = read(pipes[0], buffer+count, buffsize-count)) != -1) count+=nbytes;
               //Print out pipe
               printf("hping3: (%.*s)\n", nbytes, buffer);
               fflush(stdout);
               wait(NULL);
               close(pipes[0]);
            } else {
               //Child does not read
               close(pipes[0]);
               //Map stdout and stderr to write pipe-end
               dup2(pipes[1], STDOUT_FILENO);
               //dup2(pipes[1], STDERR_FILENO);

               //Status Message
               printf("Try to execute hping3 ...");
               fflush(stdout);

               //Child, exec hping with params
               execv("/usr/sbin/hping3",params);
               puts("never happens");
               close(pipes[1]);
               exit(1);
            }

I would appreciate your help i'm kind of stuck in this problem, have worked on an solution for 12 hours now.

lt_katana
  • 148
  • 3
  • 12
  • 1
    Don't execute `sudo` with `execv` instead execute your program with `sudo`. – Iharob Al Asimi Jan 08 '15 at 16:00
  • Same problem, i am not actually sure if it would work in a full mpi environment. Problem is hping3 requires root. – lt_katana Jan 08 '15 at 16:09
  • 1
    So your program should be executed by the root user, trying to use `sudo` from inside your program is not a good idea. – Iharob Al Asimi Jan 08 '15 at 16:10
  • I cant access root user on the pelican mpi environment i am forced to use. – lt_katana Jan 08 '15 at 16:13
  • If you can't do `sudo ./your-program` then how are you going to do it with `execv`? – Iharob Al Asimi Jan 08 '15 at 16:14
  • i can run sudo but i am not sure if this works with the mpi environment (sudo mpirun -hostfile temp/bhosts params) may not be executed as root on the other nodes in the cluster. I tried it with system() and sudo worked fine but i have to do this with some function of the exec family – lt_katana Jan 08 '15 at 16:21
  • Forget the fork problem for a while. What happens if you run on command line `sudo /usr/sbin/hping3 ...` ? Second remark, the way you are building the params array looks *uncommon*, you should print params at the time of forking to control that they are what you expect. And anyway, when forking `hping3`, you should use `execv("/usr/sbin/hping3",params + 1);` skipping the first element of params. – Serge Ballesta Jan 08 '15 at 16:23
  • maybe I am missing something from the previous comments but if you want to exec *sudo*, the first parameter of `execv()` has to be *sudo* – Ingo Leonhardt Jan 08 '15 at 16:53

1 Answers1

0

The working solution for this problem was using execve. It would also work with execv. I had to call sudo with full path and pass hping3 and its params to the sudo command.

//Child, exec hping with params
execve("/usr/bin/sudo",params, NULL);
lt_katana
  • 148
  • 3
  • 12