c359d8487dfc9a7e9955184207fc87b8535d474b
[tpg/acess2.git] / Tools / NetTest_Runner / stack.c
1 /*
2  */
3 #define _POSIX_C_SOURCE 200809L
4 #include "stack.h"
5 #include <unistd.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <errno.h>
10 #include <assert.h>
11 #include <stdarg.h>
12
13 #include <fcntl.h>
14 #include <spawn.h>
15
16 #define MAX_ARGS        16
17
18 extern char **environ;
19
20 // === GLOBALS ===
21 pid_t   giStack_PID;
22  int    giStack_InFD = -1;
23  int    giNumStackArgs = 1;
24 char    *gasStackArgs[MAX_ARGS] = {"nettest",NULL};
25
26 // === CODE ===
27 void Stack_AddDevice(const char *Ident, const void *MacAddr)
28 {
29         Stack_AddArg("-dev");
30         Stack_AddArg("%02x%02x%02x%02x%02x%02x:unix:%s",
31                 ((uint8_t*)MacAddr)[0],
32                 ((uint8_t*)MacAddr)[1],
33                 ((uint8_t*)MacAddr)[2],
34                 ((uint8_t*)MacAddr)[3],
35                 ((uint8_t*)MacAddr)[4],
36                 ((uint8_t*)MacAddr)[5],
37                 Ident);
38 }
39
40 void Stack_AddInterface(const char *Name, int AddrType, const void *Addr, int MaskBits)
41 {
42         Stack_AddArg("-ip");
43         switch(AddrType)
44         {
45         case 4:
46                 Stack_AddArg("%s,%i.%i.%i.%i/%i", Name,
47                         ((uint8_t*)Addr)[0],
48                         ((uint8_t*)Addr)[1],
49                         ((uint8_t*)Addr)[2],
50                         ((uint8_t*)Addr)[3],
51                         MaskBits
52                         );
53                 break;
54         default:
55                 assert(AddrType == 4);
56                 exit(1);
57         }
58 }
59
60 void Stack_AddRoute(int Type, const void *Network, int MaskBits, const void *NextHop)
61 {
62 }
63
64 void Stack_AddArg(const char *Fmt, ...)
65 {
66         va_list args;
67         va_start(args, Fmt);
68         size_t len = vsnprintf(NULL, 0, Fmt, args);
69         va_end(args);
70         char *arg = malloc(len+1);
71         va_start(args, Fmt);
72         vsnprintf(arg, len+1, Fmt, args);
73         va_end(args);
74         gasStackArgs[giNumStackArgs++] = arg;
75 }
76
77 void sigchld_handler(int signum)
78 {
79          int status;
80         wait(&status);
81         fprintf(stderr, "FAILURE: Child exited (%i)\n", status);
82 }
83
84 int Stack_Start(const char *Subcommand)
85 {
86         Stack_AddArg(Subcommand);
87         
88         for( int i = 3; i < 16; i ++ )
89                 fcntl(i, F_SETFD, FD_CLOEXEC);
90
91         //signal(SIGCHLD, sigchld_handler);
92
93          int    fds_in[2];
94         pipe(fds_in);
95         giStack_InFD = fds_in[1];
96         fcntl(giStack_InFD, F_SETFD, FD_CLOEXEC);
97
98         FILE    *fp;
99         fp = fopen("stdout.txt", "a"); fprintf(fp, "--- Startup\n"); fclose(fp);
100         fp = fopen("stderr.txt", "a"); fprintf(fp, "--- Startup\n"); fclose(fp);
101
102         posix_spawn_file_actions_t      fa;
103         posix_spawn_file_actions_init(&fa);
104         posix_spawn_file_actions_adddup2(&fa, fds_in[0], 0);
105         posix_spawn_file_actions_addopen(&fa, 1, "stdout.txt", O_CREAT|O_APPEND|O_WRONLY, 0644);
106         posix_spawn_file_actions_addopen(&fa, 2, "stderr.txt", O_CREAT|O_APPEND|O_WRONLY, 0644);
107
108         int rv = posix_spawn(&giStack_PID, "./nettest", &fa, NULL, gasStackArgs, environ);
109         if(rv) {
110                 giStack_PID = 0;
111                 fprintf(stderr, "posix_spawn failed: %s", strerror(rv));
112                 return 1;
113         }
114
115         return 0;
116 }
117 void Stack_Kill(void)
118 {
119         if( giStack_PID )
120         {
121                 kill(giStack_PID, SIGTERM);
122                 giStack_PID = 0;
123         }
124 }
125
126 int Stack_SendCommand(const char *CommandString)
127 {
128         write(giStack_InFD, CommandString, strlen(CommandString));
129         write(giStack_InFD, "\n", 1);
130         return 0;
131 }
132

UCC git Repository :: git.ucc.asn.au