1 /* l2tpns plugin control */
19 { "load_plugin", " PLUGIN Load named plugin", NSCTL_REQ_LOAD
},
20 { "unload_plugin", " PLUGIN Unload named plugin", NSCTL_REQ_UNLOAD
},
21 { "help", " List available commands", NSCTL_REQ_HELP
},
26 static int timeout
= 2; // 2 seconds
29 #define USAGE() fprintf(stderr, "Usage: %s [-d] [-h HOST[:PORT]] [-t TIMEOUT] COMMAND [ARG ...]\n", me)
31 static struct nsctl
*request(char *host
, int port
, int type
, int argc
, char *argv
[]);
33 int main(int argc
, char *argv
[])
42 if ((p
= strrchr((me
= argv
[0]), '/')))
46 while ((i
= getopt(argc
, argv
, "dh:t:")) != -1)
58 timeout
= atoi(optarg
);
69 if (argc
< 1 || !argv
[0][0])
78 if ((p
= strchr(host
, ':')))
83 fprintf(stderr
, "%s: invalid port `%s'\n", me
, p
+ 1);
94 for (i
= 0; !req_type
&& builtins
[i
].command
; i
++)
95 if (!strcmp(argv
[0], builtins
[i
].command
))
96 req_type
= builtins
[i
].action
;
98 if (req_type
== NSCTL_REQ_HELP
)
100 printf("Available commands:\n");
101 for (i
= 0; builtins
[i
].command
; i
++)
102 printf(" %s%s\n", builtins
[i
].command
, builtins
[i
].usage
);
112 req_type
= NSCTL_REQ_CONTROL
;
115 if ((res
= request(host
, port
, req_type
, argc
, argv
)))
117 FILE *stream
= stderr
;
118 int status
= EXIT_FAILURE
;
120 if (res
->type
== NSCTL_RES_OK
)
123 status
= EXIT_SUCCESS
;
126 for (i
= 0; i
< res
->argc
; i
++)
127 fprintf(stream
, "%s\n", res
->argv
[i
]);
135 static void sigalrm_handler(int sig
) { }
137 static struct nsctl
*request(char *host
, int port
, int type
, int argc
, char *argv
[])
139 static struct nsctl res
;
140 struct sockaddr_in peer
;
141 socklen_t len
= sizeof(peer
);
142 struct hostent
*h
= gethostbyname(host
);
144 uint8_t buf
[NSCTL_MAX_PKT_SZ
];
148 if (!h
|| h
->h_addrtype
!= AF_INET
)
150 fprintf(stderr
, "%s: invalid host `%s'\n", me
, host
);
154 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
)) < 0)
156 fprintf(stderr
, "%s: can't create udp socket (%s)\n", me
, strerror(errno
));
160 memset(&peer
, 0, len
);
161 peer
.sin_family
= AF_INET
;
162 peer
.sin_port
= htons(port
);
163 memcpy(&peer
.sin_addr
.s_addr
, h
->h_addr
, sizeof(peer
.sin_addr
.s_addr
));
165 if (connect(fd
, (struct sockaddr
*) &peer
, sizeof(peer
)) < 0)
167 fprintf(stderr
, "%s: udp connect failed (%s)\n", me
, strerror(errno
));
171 if ((sz
= pack_control(buf
, sizeof(buf
), type
, argc
, argv
)) < 0)
173 fprintf(stderr
, "%s: error packing request\n", me
);
180 if (unpack_control(&req
, buf
, sz
) == type
)
182 fprintf(stderr
, "Sending ");
183 dump_control(&req
, stderr
);
187 if (send(fd
, buf
, sz
, 0) < 0)
189 fprintf(stderr
, "%s: error sending request (%s)\n", me
, strerror(errno
));
196 struct sigaction alrm
;
197 alrm
.sa_handler
= sigalrm_handler
;
198 sigemptyset(&alrm
.sa_mask
);
201 sigaction(SIGALRM
, &alrm
, 0);
205 sz
= recv(fd
, buf
, sizeof(buf
), 0);
210 fprintf(stderr
, "%s: error receiving response (%s)\n", me
,
211 errno
== EINTR
? "timed out" : strerror(errno
));
216 if ((type
= unpack_control(&res
, buf
, sz
)) > 0 && type
& NSCTL_RESPONSE
)
220 fprintf(stderr
, "Received ");
221 dump_control(&res
, stderr
);
227 err
= "unknown error";
230 case NSCTL_ERR_SHORT
: err
= "short packet"; break;
231 case NSCTL_ERR_LONG
: err
= "extra data"; break;
232 case NSCTL_ERR_MAGIC
: err
= "bad magic"; break;
233 case NSCTL_ERR_TYPE
: err
= "invalid type"; break;
236 fprintf(stderr
, "%s: %s\n", me
, err
);