1 /* l2tpns plugin control */
20 { "load_plugin", " PLUGIN Load named plugin", NSCTL_REQ_LOAD
},
21 { "unload_plugin", " PLUGIN Unload named plugin", NSCTL_REQ_UNLOAD
},
22 { "help", " List available commands", NSCTL_REQ_HELP
},
27 static int timeout
= 2; // 2 seconds
30 #define USAGE() fprintf(stderr, "Usage: %s [-d] [-h HOST[:PORT]] [-t TIMEOUT] COMMAND [ARG ...]\n", me)
32 static struct nsctl
*request(char *host
, int port
, int type
, int argc
, char *argv
[]);
34 int main(int argc
, char *argv
[])
43 if ((p
= strrchr((me
= argv
[0]), '/')))
47 while ((i
= getopt(argc
, argv
, "dh:t:")) != -1)
59 timeout
= atoi(optarg
);
70 if (argc
< 1 || !argv
[0][0])
79 if ((p
= strchr(host
, ':')))
84 fprintf(stderr
, "%s: invalid port `%s'\n", me
, p
+ 1);
95 for (i
= 0; !req_type
&& builtins
[i
].command
; i
++)
96 if (!strcmp(argv
[0], builtins
[i
].command
))
97 req_type
= builtins
[i
].action
;
99 if (req_type
== NSCTL_REQ_HELP
)
101 printf("Available commands:\n");
102 for (i
= 0; builtins
[i
].command
; i
++)
103 printf(" %s%s\n", builtins
[i
].command
, builtins
[i
].usage
);
113 req_type
= NSCTL_REQ_CONTROL
;
116 if ((res
= request(host
, port
, req_type
, argc
, argv
)))
118 FILE *stream
= stderr
;
119 int status
= EXIT_FAILURE
;
121 if (res
->type
== NSCTL_RES_OK
)
124 status
= EXIT_SUCCESS
;
127 for (i
= 0; i
< res
->argc
; i
++)
128 fprintf(stream
, "%s\n", res
->argv
[i
]);
136 static void sigalrm_handler(int sig
) { }
138 static struct nsctl
*request(char *host
, int port
, int type
, int argc
, char *argv
[])
140 static struct nsctl res
;
141 struct sockaddr_in peer
;
142 socklen_t len
= sizeof(peer
);
143 struct hostent
*h
= gethostbyname(host
);
145 uint8_t buf
[NSCTL_MAX_PKT_SZ
];
149 if (!h
|| h
->h_addrtype
!= AF_INET
)
151 fprintf(stderr
, "%s: invalid host `%s'\n", me
, host
);
155 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
)) < 0)
157 fprintf(stderr
, "%s: can't create udp socket (%s)\n", me
, strerror(errno
));
161 memset(&peer
, 0, len
);
162 peer
.sin_family
= AF_INET
;
163 peer
.sin_port
= htons(port
);
164 memcpy(&peer
.sin_addr
.s_addr
, h
->h_addr
, sizeof(peer
.sin_addr
.s_addr
));
166 if (connect(fd
, (struct sockaddr
*) &peer
, sizeof(peer
)) < 0)
168 fprintf(stderr
, "%s: udp connect failed (%s)\n", me
, strerror(errno
));
172 if ((sz
= pack_control(buf
, sizeof(buf
), type
, argc
, argv
)) < 0)
174 fprintf(stderr
, "%s: error packing request\n", me
);
181 if (unpack_control(&req
, buf
, sz
) == type
)
183 fprintf(stderr
, "Sending ");
184 dump_control(&req
, stderr
);
188 if (send(fd
, buf
, sz
, 0) < 0)
190 fprintf(stderr
, "%s: error sending request (%s)\n", me
, strerror(errno
));
197 struct sigaction alrm
;
198 alrm
.sa_handler
= sigalrm_handler
;
199 sigemptyset(&alrm
.sa_mask
);
202 sigaction(SIGALRM
, &alrm
, 0);
206 sz
= recv(fd
, buf
, sizeof(buf
), 0);
211 fprintf(stderr
, "%s: error receiving response (%s)\n", me
,
212 errno
== EINTR
? "timed out" : strerror(errno
));
217 if ((type
= unpack_control(&res
, buf
, sz
)) > 0 && type
& NSCTL_RESPONSE
)
221 fprintf(stderr
, "Received ");
222 dump_control(&res
, stderr
);
228 err
= "unknown error";
231 case NSCTL_ERR_SHORT
: err
= "short packet"; break;
232 case NSCTL_ERR_LONG
: err
= "extra data"; break;
233 case NSCTL_ERR_MAGIC
: err
= "bad magic"; break;
234 case NSCTL_ERR_TYPE
: err
= "invalid type"; break;
237 fprintf(stderr
, "%s: %s\n", me
, err
);