2 * radclient General radius packet debug tool.
10 #include <sys/types.h>
17 #include <sys/socket.h>
19 #include <netinet/in.h>
22 # include <sys/select.h>
34 #include "libradius.h"
38 * Read valuepairs from the fp up to End-Of-File.
40 VALUE_PAIR *readvp(FILE *fp)
51 while (!error && fgets(buf, sizeof(buf), fp) != NULL) {
55 if ((vp = pairread(&p, &eol)) == NULL) {
56 librad_perror("radclient:");
63 return error ? NULL: list;
68 fprintf(stderr, "Usage: radclient [-d raddb ] [-f file] [-r retries] [-t timeout] [-nx]\n server acct|auth <secret>\n");
72 int getport(char *name)
76 svp = getservbyname (name, "udp");
81 return ntohs(svp->s_port);
84 int main(int argc, char **argv)
87 RADIUS_PACKET *rep = NULL;
90 char *secret = "secret";
97 char *radius_dir = RADDBDIR;
98 char *filename = NULL;
101 while ((c = getopt(argc, argv, "d:f:nt:r:xv")) != EOF) switch(c) {
115 if (!isdigit(*optarg)) usage();
116 retries = atoi(optarg);
119 if (!isdigit(*optarg)) usage();
120 timeout = atof(optarg);
123 printf("radclient: $Id$ built on " __DATE__ "\n");
130 argc -= (optind - 1);
131 argv += (optind - 1);
137 if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
138 librad_perror("radclient");
142 if ((req = rad_alloc(1)) == NULL) {
143 librad_perror("radclient");
150 req->id = getpid() & 0xFF;
153 memset(req->vector, 0, sizeof(req->vector));
157 * Strip port from hostname if needed.
159 if ((p = strchr(argv[1], ':')) != NULL) {
165 * See what kind of request we want to send.
167 if (strcmp(argv[2], "auth") == 0) {
168 if (port == 0) port = getport("radius");
169 if (port == 0) port = PW_AUTH_UDP_PORT;
170 req->code = PW_AUTHENTICATION_REQUEST;
171 } else if (strcmp(argv[2], "acct") == 0) {
172 if (port == 0) port = getport("radacct");
173 if (port == 0) port = PW_ACCT_UDP_PORT;
174 req->code = PW_ACCOUNTING_REQUEST;
175 } else if (isdigit(argv[2][0])) {
176 if (port == 0) port = PW_AUTH_UDP_PORT;
177 port = atoi(argv[2]);
185 req->dst_port = port;
186 req->dst_ipaddr = ip_getaddr(argv[1]);
187 if (req->dst_ipaddr == 0) {
188 librad_perror("radclient: %s: ", argv[1]);
195 if (argv[3]) secret = argv[3];
199 * Maybe read them, from stdin, if there's no
200 * filename, or if the filename is '-'.
202 if (filename && (strcmp(filename, "-") != 0)) {
203 fp = fopen(filename, "r");
205 fprintf(stderr, "radclient: Error opening %s: %s\n",
206 filename, strerror(errno));
213 if ((req->vps = readvp(fp)) == NULL) {
220 if ((req->sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
221 perror("radclient: socket: ");
225 for (i = 0; i < retries; i++) {
228 rad_send(req, secret);
230 /* And wait for reply, timing out as necessary */
232 FD_SET(req->sockfd, &rdfdesc);
234 tv.tv_sec = (int)timeout;
235 tv.tv_usec = 1000000 * (timeout - (int)timeout);
237 /* Something's wrong if we don't get exactly one fd. */
238 if (select(req->sockfd + 1, &rdfdesc, NULL, NULL, &tv) != 1) {
242 rep = rad_recv(req->sockfd);
245 } else { /* NULL: couldn't receive the packet */
246 librad_perror("radclient:");
251 /* No response or no data read (?) */
253 fprintf(stderr, "radclient: no response from server\n");
257 if (rad_decode(rep, secret) != 0) {
258 librad_perror("rad_decode");
262 /* libradius debug already prints out the value pairs for us */
263 if (!librad_debug && do_output)
264 vp_printlist(stdout, rep->vps);