bf641a8d480f28507443858b46e0d1166e046a41
[freeradius.git] / src / main / radclient.c
1 /*
2  * radclient.c  General radius packet debug tool.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006,2014  The FreeRADIUS server project
21  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
22  * Copyright 2000  Alan DeKok <aland@ox.org>
23  */
24
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radclient.h>
28 #include <freeradius-devel/radpaths.h>
29 #include <freeradius-devel/conf.h>
30 #include <ctype.h>
31
32 #ifdef HAVE_GETOPT_H
33 #  include <getopt.h>
34 #endif
35
36 #include <assert.h>
37
38 typedef struct REQUEST REQUEST; /* to shut up warnings about mschap.h */
39
40 #include "smbdes.h"
41 #include "mschap.h"
42
43 static int retries = 3;
44 static float timeout = 5;
45 static char const *secret = NULL;
46 static bool do_output = true;
47
48 static rc_stats_t stats;
49
50 static uint16_t server_port = 0;
51 static int packet_code = 0;
52 static fr_ipaddr_t server_ipaddr;
53 static int resend_count = 1;
54 static bool done = true;
55 static bool print_filename = false;
56
57 static fr_ipaddr_t client_ipaddr;
58 static uint16_t client_port = 0;
59
60 static int sockfd;
61 static int last_used_id = -1;
62
63 #ifdef WITH_TCP
64 char const *proto = NULL;
65 #endif
66 static int ipproto = IPPROTO_UDP;
67
68 static rbtree_t *filename_tree = NULL;
69 static fr_packet_list_t *pl = NULL;
70
71 static int sleep_time = -1;
72
73 static rc_request_t *request_head = NULL;
74 static rc_request_t *rc_request_tail = NULL;
75
76 static int rc_debug_flag;
77
78 char const *radclient_version = "radclient version " RADIUSD_VERSION_STRING
79 #ifdef RADIUSD_VERSION_COMMIT
80 " (git #" STRINGIFY(RADIUSD_VERSION_COMMIT) ")"
81 #endif
82 ", built on " __DATE__ " at " __TIME__;
83
84 static void NEVER_RETURNS usage(void)
85 {
86         fprintf(stderr, "Usage: radclient [options] server[:port] <command> [<secret>]\n");
87
88         fprintf(stderr, "  <command>              One of auth, acct, status, coa, or disconnect.\n");
89         fprintf(stderr, "  -4                     Use IPv4 address of server\n");
90         fprintf(stderr, "  -6                     Use IPv6 address of server.\n");
91         fprintf(stderr, "  -c <count>             Send each packet 'count' times.\n");
92         fprintf(stderr, "  -d <raddb>             Set user dictionary directory (defaults to " RADDBDIR ").\n");
93         fprintf(stderr, "  -D <dictdir>           Set main dictionary directory (defaults to " DICTDIR ").\n");
94         fprintf(stderr, "  -f <file>[:<file>]     Read packets from file, not stdin.\n");
95         fprintf(stderr, "                         If a second file is provided, it will be used to verify responses\n");
96         fprintf(stderr, "  -F                     Print the file name, packet number and reply code.\n");
97         fprintf(stderr, "  -h                     Print usage help information.\n");
98         fprintf(stderr, "  -i <id>                Set request id to 'id'.  Values may be 0..255\n");
99         fprintf(stderr, "  -n <num>               Send N requests/s\n");
100         fprintf(stderr, "  -p <num>               Send 'num' packets from a file in parallel.\n");
101         fprintf(stderr, "  -q                     Do not print anything out.\n");
102         fprintf(stderr, "  -r <retries>           If timeout, retry sending the packet 'retries' times.\n");
103         fprintf(stderr, "  -s                     Print out summary information of auth results.\n");
104         fprintf(stderr, "  -S <file>              read secret from file, not command line.\n");
105         fprintf(stderr, "  -t <timeout>           Wait 'timeout' seconds before retrying (may be a floating point number).\n");
106         fprintf(stderr, "  -v                     Show program version information.\n");
107         fprintf(stderr, "  -x                     Debugging mode.\n");
108
109 #ifdef WITH_TCP
110         fprintf(stderr, "  -P <proto>             Use proto (tcp or udp) for transport.\n");
111 #endif
112
113         exit(1);
114 }
115
116 static const FR_NAME_NUMBER request_types[] = {
117         { "auth",       PW_CODE_AUTHENTICATION_REQUEST },
118         { "challenge",  PW_CODE_ACCESS_CHALLENGE },
119         { "acct",       PW_CODE_ACCOUNTING_REQUEST },
120         { "status",     PW_CODE_STATUS_SERVER },
121         { "disconnect", PW_CODE_DISCONNECT_REQUEST },
122         { "coa",        PW_CODE_COA_REQUEST },
123         { "auto",       PW_CODE_UNDEFINED },
124
125         { NULL, 0}
126 };
127
128 /*
129  *      Free a radclient struct, which may (or may not)
130  *      already be in the list.
131  */
132 static int _rc_request_free(rc_request_t *request)
133 {
134         rc_request_t *prev, *next;
135
136         prev = request->prev;
137         next = request->next;
138
139         if (prev) {
140                 assert(request_head != request);
141                 prev->next = next;
142         } else if (request_head) {
143                 assert(request_head == request);
144                 request_head = next;
145         }
146
147         if (next) {
148                 assert(rc_request_tail != request);
149                 next->prev = prev;
150         } else if (rc_request_tail) {
151                 assert(rc_request_tail == request);
152                 rc_request_tail = prev;
153         }
154
155         return 0;
156 }
157
158 static int mschapv1_encode(RADIUS_PACKET *packet, VALUE_PAIR **request,
159                            char const *password)
160 {
161         unsigned int i;
162         uint8_t *p;
163         VALUE_PAIR *challenge, *reply;
164         uint8_t nthash[16];
165
166         challenge = paircreate(packet, PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT);
167         if (!challenge) {
168                 return 0;
169         }
170
171         pairadd(request, challenge);
172         challenge->length = 8;
173         challenge->vp_octets = p = talloc_array(challenge, uint8_t, challenge->length);
174         for (i = 0; i < challenge->length; i++) {
175                 p[i] = fr_rand();
176         }
177
178         reply = paircreate(packet, PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT);
179         if (!reply) {
180                 return 0;
181         }
182
183         pairadd(request, reply);
184         reply->length = 50;
185         reply->vp_octets = p = talloc_array(reply, uint8_t, reply->length);
186         memset(p, 0, reply->length);
187
188         p[1] = 0x01; /* NT hash */
189
190         if (mschap_ntpwdhash(nthash, password) < 0) {
191                 return 0;
192         }
193
194         smbdes_mschap(nthash, challenge->vp_octets, p + 26);
195         return 1;
196 }
197
198
199 static int getport(char const *name)
200 {
201         struct  servent *svp;
202
203         svp = getservbyname(name, "udp");
204         if (!svp) {
205                 return 0;
206         }
207
208         return ntohs(svp->s_port);
209 }
210
211 /*
212  *      Set a port from the request type if we don't already have one
213  */
214 static void radclient_get_port(PW_CODE type, uint16_t *port)
215 {
216         switch (type) {
217         default:
218         case PW_CODE_AUTHENTICATION_REQUEST:
219         case PW_CODE_ACCESS_CHALLENGE:
220         case PW_CODE_STATUS_SERVER:
221                 if (*port == 0) *port = getport("radius");
222                 if (*port == 0) *port = PW_AUTH_UDP_PORT;
223                 return;
224
225         case PW_CODE_ACCOUNTING_REQUEST:
226                 if (*port == 0) *port = getport("radacct");
227                 if (*port == 0) *port = PW_ACCT_UDP_PORT;
228                 return;
229
230         case PW_CODE_DISCONNECT_REQUEST:
231                 if (*port == 0) *port = PW_POD_UDP_PORT;
232
233         case PW_CODE_COA_REQUEST:
234                 if (*port == 0) *port = PW_COA_UDP_PORT;
235                 return;
236
237         case PW_CODE_UNDEFINED:
238                 if (*port == 0) *port = 0;
239         }
240 }
241
242 /*
243  *      Resolve a port to a request type
244  */
245 static PW_CODE radclient_get_code(port)
246 {
247         if ((port == getport("radius")) || (port == PW_AUTH_UDP_PORT) || (port == PW_AUTH_UDP_PORT_ALT)) {
248                 return PW_CODE_AUTHENTICATION_REQUEST;
249         }
250         if ((port == getport("radacct")) || (port == PW_ACCT_UDP_PORT) || (port == PW_ACCT_UDP_PORT_ALT)) {
251                 return PW_CODE_ACCOUNTING_REQUEST;
252         }
253         if (port == PW_COA_UDP_PORT) return PW_CODE_COA_REQUEST;
254         if (port == PW_POD_UDP_PORT) return PW_CODE_DISCONNECT_REQUEST;
255
256         return PW_CODE_UNDEFINED;
257 }
258
259 /*
260  *      Initialize a radclient data structure and add it to
261  *      the global linked list.
262  */
263 static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files)
264 {
265         FILE *packets, *filters = NULL;
266
267         vp_cursor_t cursor;
268         VALUE_PAIR *vp;
269         rc_request_t *request;
270         bool packets_done = false;
271         uint64_t num = 0;
272
273         assert(files->packets != NULL);
274
275         /*
276          *      Determine where to read the VP's from.
277          */
278         if (strcmp(files->packets, "stdin") != 0) {
279                 packets = fopen(files->packets, "r");
280                 if (!packets) {
281                         ERROR("Error opening %s: %s", files->packets, strerror(errno));
282                         return 0;
283                 }
284
285                 /*
286                  *      Read in the pairs representing the expected response.
287                  */
288                 if (files->filters) {
289                         filters = fopen(files->filters, "r");
290                         if (!filters) {
291                                 ERROR("Error opening %s: %s", files->filters, strerror(errno));
292                                 fclose(packets);
293                                 return 0;
294                         }
295                 }
296         } else {
297                 packets = stdin;
298         }
299
300
301         /*
302          *      Loop until the file is done.
303          */
304         do {
305                 /*
306                  *      Allocate it.
307                  */
308                 request = talloc_zero(ctx, rc_request_t);
309                 if (!request) {
310                         ERROR("Out of memory");
311                         goto error;
312                 }
313
314                 request->packet = rad_alloc(request, 1);
315                 if (!request->packet) {
316                         ERROR("Out of memory");
317                         goto error;
318                 }
319
320 #ifdef WITH_TCP
321                 request->packet->src_ipaddr = client_ipaddr;
322                 request->packet->src_port = client_port;
323                 request->packet->dst_ipaddr = server_ipaddr;
324                 request->packet->dst_port = server_port;
325                 request->packet->proto = ipproto;
326 #endif
327
328                 request->files = files;
329                 request->packet->id = -1; /* allocate when sending */
330                 request->num = num++;
331
332                 /*
333                  *      Read the request VP's.
334                  */
335                 if (readvp2(&request->packet->vps, request->packet, packets, &packets_done) < 0) {
336                         REDEBUG("Error parsing \"%s\"", files->packets);
337                         goto error;
338                 }
339
340                 /*
341                  *      Skip empty entries
342                  */
343                 if (!request->packet->vps) {
344                         talloc_free(request);
345                         continue;
346                 }
347
348                 /*
349                  *      Read in filter VP's.
350                  */
351                 if (filters) {
352                         bool filters_done;
353
354                         if (readvp2(&request->filter, request, filters, &filters_done) < 0) {
355                                 REDEBUG("Error parsing \"%s\"", files->filters);
356                                 goto error;
357                         }
358
359                         if (filters_done && !packets_done) {
360                                 REDEBUG("Differing number of packets/filters in %s:%s "
361                                         "(too many requests))", files->packets, files->filters);
362                                 goto error;
363                         }
364
365                         if (!filters_done && packets_done) {
366                                 REDEBUG("Differing number of packets/filters in %s:%s "
367                                         "(too many filters))", files->packets, files->filters);
368                                 goto error;
369                         }
370
371                         /*
372                          *      xlat expansions aren't supported here
373                          */
374                         for (vp = fr_cursor_init(&cursor, &request->filter);
375                              vp;
376                              vp = fr_cursor_next(&cursor)) {
377                                 if (vp->type == VT_XLAT) {
378                                         vp->type = VT_DATA;
379                                         vp->vp_strvalue = vp->value.xlat;
380                                         vp->length = talloc_array_length(vp->vp_strvalue) - 1;
381                                 }
382
383                                 if (vp->da->vendor == 0 ) switch (vp->da->attr) {
384                                 case PW_RESPONSE_PACKET_TYPE:
385                                 case PW_PACKET_TYPE:
386                                         fr_cursor_remove(&cursor);      /* so we don't break the filter */
387                                         request->filter_code = vp->vp_integer;
388                                         talloc_free(vp);
389
390                                 default:
391                                         break;
392                                 }
393                         }
394
395                         /*
396                          *      This allows efficient list comparisons later
397                          */
398                         pairsort(&request->filter, attrtagcmp);
399                 }
400
401                 request->password[0] = '\0';
402                 /*
403                  *      Process special attributes
404                  */
405                 for (vp = fr_cursor_init(&cursor, &request->packet->vps);
406                      vp;
407                      vp = fr_cursor_next(&cursor)) {
408                         /*
409                          *      Double quoted strings get marked up as xlat expansions,
410                          *      but we don't support that in request.
411                          */
412                         if (vp->type == VT_XLAT) {
413                                 vp->type = VT_DATA;
414                                 vp->vp_strvalue = vp->value.xlat;
415                                 vp->length = talloc_array_length(vp->vp_strvalue) - 1;
416                         }
417
418                         if (!vp->da->vendor) switch (vp->da->attr) {
419                         default:
420                                 break;
421
422                         /*
423                          *      Allow it to set the packet type in
424                          *      the attributes read from the file.
425                          */
426                         case PW_PACKET_TYPE:
427                                 request->packet->code = vp->vp_integer;
428                                 break;
429
430                         case PW_PACKET_DST_PORT:
431                                 request->packet->dst_port = (vp->vp_integer & 0xffff);
432                                 break;
433
434                         case PW_PACKET_DST_IP_ADDRESS:
435                                 request->packet->dst_ipaddr.af = AF_INET;
436                                 request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
437                                 break;
438
439                         case PW_PACKET_DST_IPV6_ADDRESS:
440                                 request->packet->dst_ipaddr.af = AF_INET6;
441                                 request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
442                                 break;
443
444                         case PW_PACKET_SRC_PORT:
445                                 request->packet->src_port = (vp->vp_integer & 0xffff);
446                                 break;
447
448                         case PW_PACKET_SRC_IP_ADDRESS:
449                                 request->packet->src_ipaddr.af = AF_INET;
450                                 request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
451                                 break;
452
453                         case PW_PACKET_SRC_IPV6_ADDRESS:
454                                 request->packet->src_ipaddr.af = AF_INET6;
455                                 request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
456                                 break;
457
458                         case PW_DIGEST_REALM:
459                         case PW_DIGEST_NONCE:
460                         case PW_DIGEST_METHOD:
461                         case PW_DIGEST_URI:
462                         case PW_DIGEST_QOP:
463                         case PW_DIGEST_ALGORITHM:
464                         case PW_DIGEST_BODY_DIGEST:
465                         case PW_DIGEST_CNONCE:
466                         case PW_DIGEST_NONCE_COUNT:
467                         case PW_DIGEST_USER_NAME:
468                         /* overlapping! */
469                         {
470                                 DICT_ATTR const *da;
471                                 uint8_t *p, *q;
472
473                                 p = talloc_array(vp, uint8_t, vp->length + 2);
474
475                                 memcpy(p + 2, vp->vp_octets, vp->length);
476                                 p[0] = vp->da->attr - PW_DIGEST_REALM + 1;
477                                 vp->length += 2;
478                                 p[1] = vp->length;
479
480                                 da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0);
481                                 if (!da) {
482                                         ERROR("Out of memory");
483                                         goto error;
484                                 }
485                                 vp->da = da;
486
487                                 /*
488                                  *      Re-do pairmemsteal ourselves,
489                                  *      because we play games with
490                                  *      vp->da, and pairmemsteal goes
491                                  *      to GREAT lengths to sanitize
492                                  *      and fix and change and
493                                  *      double-check the various
494                                  *      fields.
495                                  */
496                                 memcpy(&q, &vp->vp_octets, sizeof(q));
497                                 talloc_free(q);
498
499                                 vp->vp_octets = talloc_steal(vp, p);
500                                 vp->type = VT_DATA;
501
502                                 VERIFY_VP(vp);
503                         }
504                                 break;
505
506                         /*
507                          *      Keep a copy of the the password attribute.
508                          */
509                         case PW_USER_PASSWORD:
510                         case PW_CHAP_PASSWORD:
511                         case PW_MS_CHAP_PASSWORD:
512                                 strlcpy(request->password, vp->vp_strvalue, sizeof(request->password));
513                                 break;
514
515                         case PW_RADCLIENT_TEST_NAME:
516                                 request->name = vp->vp_strvalue;
517                                 break;
518                         }
519                 } /* loop over the VP's we read in */
520
521                 /*
522                  *      Use the default set on the command line
523                  */
524                 if (request->packet->code == PW_CODE_UNDEFINED) {
525                         request->packet->code = packet_code;
526                 }
527
528                 /*
529                  *      Default to the filename
530                  */
531                 if (!request->name) {
532                         request->name = request->files->packets;
533                 }
534
535                 /*
536                  *      Automatically set the response code from the request code
537                  *      (if one wasn't already set).
538                  */
539                 if (request->filter_code == PW_CODE_UNDEFINED) {
540                         switch (request->packet->code) {
541                         case PW_CODE_AUTHENTICATION_REQUEST:
542                                 request->filter_code = PW_CODE_AUTHENTICATION_ACK;
543                                 break;
544
545                         case PW_CODE_ACCOUNTING_REQUEST:
546                                 request->filter_code = PW_CODE_ACCOUNTING_RESPONSE;
547                                 break;
548
549                         case PW_CODE_COA_REQUEST:
550                                 request->filter_code = PW_CODE_COA_ACK;
551                                 break;
552
553                         case PW_CODE_DISCONNECT_REQUEST:
554                                 request->filter_code = PW_CODE_DISCONNECT_ACK;
555                                 break;
556
557                         case PW_CODE_STATUS_SERVER:
558                                 switch (radclient_get_code(request->packet->dst_port)) {
559                                 case PW_CODE_AUTHENTICATION_REQUEST:
560                                         request->filter_code = PW_CODE_AUTHENTICATION_ACK;
561                                         break;
562
563                                 case PW_CODE_ACCOUNTING_REQUEST:
564                                         request->filter_code = PW_CODE_ACCOUNTING_RESPONSE;
565                                         break;
566
567                                 default:
568                                         REDEBUG("Can't determine expected response to Status-Server request, specify "
569                                                 "a well known RADIUS port, or a response filter with a "
570                                                 "Response-Packet-Type attribute");
571                                         goto error;
572                                 }
573
574                         case PW_CODE_UNDEFINED:
575                                 REDEBUG("Both Packet-Type and Response-Packet-Type, specify at least one, or a well "
576                                         "known RADIUS port");
577                                 goto error;
578
579                         default:
580                                 REDEBUG("Can't determine expected Response-Packet-Type for Packet-Type %i",
581                                         request->packet->code);
582                                 goto error;
583                         }
584                 /*
585                  *      Automatically set the request code from the response code
586                  *      (if one wasn't already set).
587                  */
588                 } else if (request->packet->code == PW_CODE_UNDEFINED) {
589                         switch (request->filter_code) {
590                         case PW_CODE_AUTHENTICATION_ACK:
591                         case PW_CODE_AUTHENTICATION_REJECT:
592                                 request->packet->code = PW_CODE_AUTHENTICATION_REQUEST;
593                                 break;
594
595                         case PW_CODE_ACCOUNTING_RESPONSE:
596                                 request->packet->code = PW_CODE_ACCOUNTING_REQUEST;
597                                 break;
598
599                         case PW_CODE_DISCONNECT_ACK:
600                         case PW_CODE_DISCONNECT_NAK:
601                                 request->packet->code = PW_CODE_DISCONNECT_REQUEST;
602                                 break;
603
604                         case PW_CODE_COA_ACK:
605                         case PW_CODE_COA_NAK:
606                                 request->packet->code = PW_CODE_COA_REQUEST;
607                                 break;
608
609                         default:
610                                 REDEBUG("Can't determine expected Packet-Type for Response-Packet-Type %i",
611                                         request->filter_code);
612                                 goto error;
613                         }
614                 }
615
616                 /*
617                  *      Automatically set the dst port (if one wasn't already set).
618                  */
619                 if (request->packet->dst_port == 0) {
620                         radclient_get_port(request->packet->code, &request->packet->dst_port);
621                         if (request->packet->dst_port == 0) {
622                                 REDEBUG("Can't determine destination port");
623                                 goto error;
624                         }
625                 }
626
627                 /*
628                  *      Add it to the tail of the list.
629                  */
630                 if (!request_head) {
631                         assert(rc_request_tail == NULL);
632                         request_head = request;
633                         request->prev = NULL;
634                 } else {
635                         assert(rc_request_tail->next == NULL);
636                         rc_request_tail->next = request;
637                         request->prev = rc_request_tail;
638                 }
639                 rc_request_tail = request;
640                 request->next = NULL;
641
642                 /*
643                  *      Set the destructor so it removes itself from the
644                  *      request list when freed. We don't set this until
645                  *      the packet is actually in the list, else we trigger
646                  *      the asserts in the free callback.
647                  */
648                 talloc_set_destructor(request, _rc_request_free);
649         } while (!packets_done); /* loop until the file is done. */
650
651         if (packets != stdin) fclose(packets);
652         if (filters) fclose(filters);
653
654         /*
655          *      And we're done.
656          */
657         return 1;
658
659 error:
660         talloc_free(request);
661
662         if (packets != stdin) fclose(packets);
663         if (filters) fclose(filters);
664
665         return 0;
666 }
667
668
669 /*
670  *      Sanity check each argument.
671  */
672 static int radclient_sane(rc_request_t *request)
673 {
674         if (request->packet->dst_port == 0) {
675                 request->packet->dst_port = server_port;
676         }
677         if (request->packet->dst_ipaddr.af == AF_UNSPEC) {
678                 if (server_ipaddr.af == AF_UNSPEC) {
679                         ERROR("No server was given, and request %" PRIu64 " in file %s did not contain "
680                               "Packet-Dst-IP-Address", request->num, request->files->packets);
681                         return -1;
682                 }
683                 request->packet->dst_ipaddr = server_ipaddr;
684         }
685         if (request->packet->code == 0) {
686                 if (packet_code == -1) {
687                         ERROR("Request was \"auto\", and request %" PRIu64 " in file %s did not contain Packet-Type",
688                               request->num, request->files->packets);
689                         return -1;
690                 }
691                 request->packet->code = packet_code;
692         }
693         request->packet->sockfd = -1;
694
695         return 0;
696 }
697
698
699 /*
700  *      For request handling.
701  */
702 static int filename_cmp(void const *one, void const *two)
703 {
704         int cmp;
705
706         rc_file_pair_t const *a = one;
707         rc_file_pair_t const *b = two;
708
709         cmp = strcmp(a->packets, b->packets);
710         if (cmp != 0) return cmp;
711
712         return strcmp(a->filters, b->filters);
713 }
714
715 static int filename_walk(UNUSED void *context, void *data)
716 {
717         rc_file_pair_t *files = data;
718
719         /*
720          *      Read request(s) from the file.
721          */
722         if (!radclient_init(files, files)) {
723                 return -1;      /* stop walking */
724         }
725
726         return 0;
727 }
728
729
730 /*
731  *      Deallocate packet ID, etc.
732  */
733 static void deallocate_id(rc_request_t *request)
734 {
735         if (!request || !request->packet ||
736             (request->packet->id < 0)) {
737                 return;
738         }
739
740         /*
741          *      One more unused RADIUS ID.
742          */
743         fr_packet_list_id_free(pl, request->packet, true);
744
745         /*
746          *      If we've already sent a packet, free up the old one,
747          *      and ensure that the next packet has a unique
748          *      authentication vector.
749          */
750         if (request->packet->data) {
751                 TALLOC_FREE(request->packet->data);
752         }
753
754         if (request->reply) rad_free(&request->reply);
755 }
756
757 /*
758  *      Send one packet.
759  */
760 static int send_one_packet(rc_request_t *request)
761 {
762         assert(request->done == false);
763
764         /*
765          *      Remember when we have to wake up, to re-send the
766          *      request, of we didn't receive a reply.
767          */
768         if ((sleep_time == -1) || (sleep_time > (int) timeout)) {
769                 sleep_time = (int) timeout;
770         }
771
772         /*
773          *      Haven't sent the packet yet.  Initialize it.
774          */
775         if (request->packet->id == -1) {
776                 int i;
777                 bool rcode;
778
779                 assert(request->reply == NULL);
780
781                 /*
782                  *      Didn't find a free packet ID, we're not done,
783                  *      we don't sleep, and we stop trying to process
784                  *      this packet.
785                  */
786         retry:
787                 request->packet->src_ipaddr.af = server_ipaddr.af;
788                 rcode = fr_packet_list_id_alloc(pl, ipproto,
789                                                 &request->packet, NULL);
790                 if (!rcode) {
791                         int mysockfd;
792
793 #ifdef WITH_TCP
794                         if (proto) {
795                                 mysockfd = fr_tcp_client_socket(NULL,
796                                                                 &request->packet->dst_ipaddr,
797                                                                 request->packet->dst_port);
798                         } else
799 #endif
800                         mysockfd = fr_socket(&client_ipaddr, 0);
801                         if (mysockfd < 0) {
802                                 ERROR("Failed opening socket");
803                                 exit(1);
804                         }
805                         if (!fr_packet_list_socket_add(pl, mysockfd, ipproto,
806                                                        &request->packet->dst_ipaddr,
807                                                        request->packet->dst_port, NULL)) {
808                                 ERROR("Can't add new socket");
809                                 exit(1);
810                         }
811                         goto retry;
812                 }
813
814                 assert(request->packet->id != -1);
815                 assert(request->packet->data == NULL);
816
817                 for (i = 0; i < 4; i++) {
818                         ((uint32_t *) request->packet->vector)[i] = fr_rand();
819                 }
820
821                 /*
822                  *      Update the password, so it can be encrypted with the
823                  *      new authentication vector.
824                  */
825                 if (request->password[0] != '\0') {
826                         VALUE_PAIR *vp;
827
828                         if ((vp = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY)) != NULL) {
829                                 pairstrcpy(vp, request->password);
830
831                         } else if ((vp = pairfind(request->packet->vps, PW_CHAP_PASSWORD, 0, TAG_ANY)) != NULL) {
832                                 bool already_hex = false;
833
834                                 /*
835                                  *      If it's 17 octets, it *might* be already encoded.
836                                  *      Or, it might just be a 17-character password (maybe UTF-8)
837                                  *      Check it for non-printable characters.  The odds of ALL
838                                  *      of the characters being 32..255 is (1-7/8)^17, or (1/8)^17,
839                                  *      or 1/(2^51), which is pretty much zero.
840                                  */
841                                 if (vp->length == 17) {
842                                         for (i = 0; i < 17; i++) {
843                                                 if (vp->vp_octets[i] < 32) {
844                                                         already_hex = true;
845                                                         break;
846                                                 }
847                                         }
848                                 }
849
850                                 /*
851                                  *      Allow the user to specify ASCII or hex CHAP-Password
852                                  */
853                                 if (!already_hex) {
854                                         uint8_t *p;
855                                         size_t len, len2;
856
857                                         len = len2 = strlen(request->password);
858                                         if (len2 < 17) len2 = 17;
859
860                                         p = talloc_zero_array(vp, uint8_t, len2);
861
862                                         memcpy(p, request->password, len);
863
864                                         rad_chap_encode(request->packet,
865                                                         p,
866                                                         fr_rand() & 0xff, vp);
867                                         vp->vp_octets = p;
868                                         vp->length = 17;
869                                 }
870                         } else if (pairfind(request->packet->vps, PW_MS_CHAP_PASSWORD, 0, TAG_ANY) != NULL) {
871                                 mschapv1_encode(request->packet,
872                                                 &request->packet->vps,
873                                                 request->password);
874                         } else {
875                                 DEBUG("WARNING: No password in the request");
876                         }
877                 }
878
879                 request->timestamp = time(NULL);
880                 request->tries = 1;
881                 request->resend++;
882
883 #ifdef WITH_TCP
884                 /*
885                  *      WTF?
886                  */
887                 if (client_port == 0) {
888                         client_ipaddr = request->packet->src_ipaddr;
889                         client_port = request->packet->src_port;
890                 }
891 #endif
892
893         } else {                /* request->packet->id >= 0 */
894                 time_t now = time(NULL);
895
896                 /*
897                  *      FIXME: Accounting packets are never retried!
898                  *      The Acct-Delay-Time attribute is updated to
899                  *      reflect the delay, and the packet is re-sent
900                  *      from scratch!
901                  */
902
903                 /*
904                  *      Not time for a retry, do so.
905                  */
906                 if ((now - request->timestamp) < timeout) {
907                         /*
908                          *      When we walk over the tree sending
909                          *      packets, we update the minimum time
910                          *      required to sleep.
911                          */
912                         if ((sleep_time == -1) ||
913                             (sleep_time > (now - request->timestamp))) {
914                                 sleep_time = now - request->timestamp;
915                         }
916                         return 0;
917                 }
918
919                 /*
920                  *      We're not trying later, maybe the packet is done.
921                  */
922                 if (request->tries == retries) {
923                         assert(request->packet->id >= 0);
924
925                         /*
926                          *      Delete the request from the tree of
927                          *      outstanding requests.
928                          */
929                         fr_packet_list_yank(pl, request->packet);
930
931                         REDEBUG("No reply from server for ID %d socket %d",
932                                 request->packet->id, request->packet->sockfd);
933                         deallocate_id(request);
934
935                         /*
936                          *      Normally we mark it "done" when we've received
937                          *      the reply, but this is a special case.
938                          */
939                         if (request->resend == resend_count) {
940                                 request->done = true;
941                         }
942                         stats.lost++;
943                         return -1;
944                 }
945
946                 /*
947                  *      We are trying later.
948                  */
949                 request->timestamp = now;
950                 request->tries++;
951         }
952
953         /*
954          *      Send the packet.
955          */
956         if (rad_send(request->packet, NULL, secret) < 0) {
957                 REDEBUG("Failed to send packet for ID %d", request->packet->id);
958         }
959
960         return 0;
961 }
962
963 /*
964  *      Receive one packet, maybe.
965  */
966 static int recv_one_packet(int wait_time)
967 {
968         fd_set          set;
969         struct timeval  tv;
970         rc_request_t    *request;
971         RADIUS_PACKET   *reply, **packet_p;
972         volatile int max_fd;
973
974         /* And wait for reply, timing out as necessary */
975         FD_ZERO(&set);
976
977         max_fd = fr_packet_list_fd_set(pl, &set);
978         if (max_fd < 0) exit(1); /* no sockets to listen on! */
979
980         if (wait_time <= 0) {
981                 tv.tv_sec = 0;
982         } else {
983                 tv.tv_sec = wait_time;
984         }
985         tv.tv_usec = 0;
986
987         /*
988          *      No packet was received.
989          */
990         if (select(max_fd, &set, NULL, NULL, &tv) <= 0) {
991                 return 0;
992         }
993
994         /*
995          *      Look for the packet.
996          */
997         reply = fr_packet_list_recv(pl, &set);
998         if (!reply) {
999                 ERROR("Received bad packet");
1000 #ifdef WITH_TCP
1001                 /*
1002                  *      If the packet is bad, we close the socket.
1003                  *      I'm not sure how to do that now, so we just
1004                  *      die...
1005                  */
1006                 if (proto) exit(1);
1007 #endif
1008                 return -1;      /* bad packet */
1009         }
1010
1011         /*
1012          *      udpfromto issues.  We may have bound to "*",
1013          *      and we want to find the replies that are sent to
1014          *      (say) 127.0.0.1.
1015          *
1016          *      This only works if were not using any of the
1017          *      Packet-* attributes, or running with 'auto'.
1018          */
1019         reply->dst_ipaddr = client_ipaddr;
1020         reply->dst_port = client_port;
1021 #ifdef WITH_TCP
1022         if (server_port > 0) {
1023                 reply->src_ipaddr = server_ipaddr;
1024                 reply->src_port = server_port;
1025         }
1026 #endif
1027
1028         packet_p = fr_packet_list_find_byreply(pl, reply);
1029         if (!packet_p) {
1030                 ERROR("Received reply to request we did not send. (id=%d socket %d)",
1031                       reply->id, reply->sockfd);
1032                 rad_free(&reply);
1033                 return -1;      /* got reply to packet we didn't send */
1034         }
1035         request = fr_packet2myptr(rc_request_t, packet, packet_p);
1036
1037         /*
1038          *      Fails the signature validation: not a real reply.
1039          *      FIXME: Silently drop it and listen for another packet.
1040          */
1041         if (rad_verify(reply, request->packet, secret) < 0) {
1042                 REDEBUG("Reply verification failed");
1043                 stats.lost++;
1044                 goto packet_done; /* shared secret is incorrect */
1045         }
1046
1047         if (print_filename) {
1048                 RDEBUG("%s response code %d", request->files->packets, reply->code);
1049         }
1050
1051         deallocate_id(request);
1052         request->reply = reply;
1053         reply = NULL;
1054
1055         /*
1056          *      If this fails, we're out of memory.
1057          */
1058         if (rad_decode(request->reply, request->packet, secret) != 0) {
1059                 REDEBUG("Reply decode failed");
1060                 stats.lost++;
1061                 goto packet_done;
1062         }
1063
1064         /*
1065          *      Increment counters...
1066          */
1067         switch (request->reply->code) {
1068         case PW_CODE_AUTHENTICATION_ACK:
1069         case PW_CODE_ACCOUNTING_RESPONSE:
1070         case PW_CODE_COA_ACK:
1071         case PW_CODE_DISCONNECT_ACK:
1072                 stats.accepted++;
1073                 break;
1074
1075         case PW_CODE_ACCESS_CHALLENGE:
1076                 break;
1077
1078         default:
1079                 stats.rejected++;
1080         }
1081
1082         /*
1083          *      If we had an expected response code, check to see if the
1084          *      packet matched that.
1085          */
1086         if (request->reply->code != request->filter_code) {
1087                 if (is_radius_code(request->reply->code)) {
1088                         REDEBUG("%s: Expected %s got %s", request->name, fr_packet_codes[request->filter_code],
1089                                 fr_packet_codes[request->reply->code]);
1090                 } else {
1091                         REDEBUG("%s: Expected %u got %i", request->name, request->filter_code,
1092                                 request->reply->code);
1093                 }
1094                 stats.failed++;
1095         /*
1096          *      Check if the contents of the packet matched the filter
1097          */
1098         } else if (!request->filter) {
1099                 stats.passed++;
1100         } else {
1101                 VALUE_PAIR const *failed[2];
1102
1103                 pairsort(&request->reply->vps, attrtagcmp);
1104                 if (pairvalidate(failed, request->filter, request->reply->vps)) {
1105                         RDEBUG("%s: Response passed filter", request->name);
1106                         stats.passed++;
1107                 } else {
1108                         pairvalidate_debug(request, failed);
1109                         REDEBUG("%s: Response for failed filter", request->name);
1110                         stats.failed++;
1111                 }
1112         }
1113
1114         if (request->resend == resend_count) {
1115                 request->done = true;
1116         }
1117
1118 packet_done:
1119         rad_free(&request->reply);
1120         rad_free(&reply);       /* may be NULL */
1121
1122         return 0;
1123 }
1124
1125 int main(int argc, char **argv)
1126 {
1127         int c;
1128         char const *radius_dir = RADDBDIR;
1129         char const *dict_dir = DICTDIR;
1130         char filesecret[256];
1131         FILE *fp;
1132         int do_summary = false;
1133         int persec = 0;
1134         int parallel = 1;
1135         rc_request_t    *this;
1136         int force_af = AF_UNSPEC;
1137
1138         /*
1139          *      It's easier having two sets of flags to set the
1140          *      verbosity of library calls and the verbosity of
1141          *      radclient.
1142          */
1143         rc_debug_flag = 1;
1144         fr_debug_flag = 0;
1145         fr_log_fp = stdout;
1146
1147 #ifndef NDEBUG
1148         if (fr_fault_setup(getenv("PANIC_ACTION"), argv[0]) < 0) {
1149                 fr_perror("radclient");
1150                 exit(EXIT_FAILURE);
1151         }
1152 #endif
1153
1154         talloc_set_log_stderr();
1155
1156         filename_tree = rbtree_create(filename_cmp, NULL, 0);
1157         if (!filename_tree) {
1158         oom:
1159                 ERROR("Out of memory");
1160                 exit(1);
1161         }
1162
1163         while ((c = getopt(argc, argv, "46c:d:D:f:Fhi:n:p:qr:sS:t:vx"
1164 #ifdef WITH_TCP
1165                 "P:"
1166 #endif
1167                            )) != EOF) switch(c) {
1168                 case '4':
1169                         force_af = AF_INET;
1170                         break;
1171                 case '6':
1172                         force_af = AF_INET6;
1173                         break;
1174                 case 'c':
1175                         if (!isdigit((int) *optarg))
1176                                 usage();
1177                         resend_count = atoi(optarg);
1178                         break;
1179                 case 'D':
1180                         dict_dir = optarg;
1181                         break;
1182                 case 'd':
1183                         radius_dir = optarg;
1184                         break;
1185                 case 'f':
1186                 {
1187                         char const *p;
1188                         rc_file_pair_t *files;
1189
1190                         files = talloc(talloc_autofree_context(), rc_file_pair_t);
1191                         if (!files) goto oom;
1192
1193                         p = strchr(optarg, ':');
1194                         if (p) {
1195                                 files->packets = talloc_strndup(files, optarg, p - optarg);
1196                                 if (!files->packets) goto oom;
1197                                 files->filters = p + 1;
1198                         } else {
1199                                 files->packets = optarg;
1200                                 files->filters = NULL;
1201                         }
1202                         rbtree_insert(filename_tree, (void *) files);
1203                 }
1204                         break;
1205                 case 'F':
1206                         print_filename = true;
1207                         break;
1208                 case 'i':       /* currently broken */
1209                         if (!isdigit((int) *optarg))
1210                                 usage();
1211                         last_used_id = atoi(optarg);
1212                         if ((last_used_id < 0) || (last_used_id > 255)) {
1213                                 usage();
1214                         }
1215                         break;
1216
1217                 case 'n':
1218                         persec = atoi(optarg);
1219                         if (persec <= 0) usage();
1220                         break;
1221
1222                         /*
1223                          *      Note that sending MANY requests in
1224                          *      parallel can over-run the kernel
1225                          *      queues, and Linux will happily discard
1226                          *      packets.  So even if the server responds,
1227                          *      the client may not see the reply.
1228                          */
1229                 case 'p':
1230                         parallel = atoi(optarg);
1231                         if (parallel <= 0) usage();
1232                         break;
1233
1234 #ifdef WITH_TCP
1235                 case 'P':
1236                         proto = optarg;
1237                         if (strcmp(proto, "tcp") != 0) {
1238                                 if (strcmp(proto, "udp") == 0) {
1239                                         proto = NULL;
1240                                 } else {
1241                                         usage();
1242                                 }
1243                         } else {
1244                                 ipproto = IPPROTO_TCP;
1245                         }
1246                         break;
1247
1248 #endif
1249
1250                 case 'q':
1251                         do_output = false;
1252                         fr_log_fp = NULL; /* no output from you, either! */
1253                         break;
1254
1255                 case 'r':
1256                         if (!isdigit((int) *optarg))
1257                                 usage();
1258                         retries = atoi(optarg);
1259                         if ((retries == 0) || (retries > 1000)) usage();
1260                         break;
1261                 case 's':
1262                         do_summary = true;
1263                         break;
1264                 case 'S':
1265                 {
1266                         char *p;
1267                         fp = fopen(optarg, "r");
1268                         if (!fp) {
1269                                ERROR("Error opening %s: %s", optarg, fr_syserror(errno));
1270                                exit(1);
1271                         }
1272                         if (fgets(filesecret, sizeof(filesecret), fp) == NULL) {
1273                                ERROR("Error reading %s: %s", optarg, fr_syserror(errno));
1274                                exit(1);
1275                         }
1276                         fclose(fp);
1277
1278                         /* truncate newline */
1279                         p = filesecret + strlen(filesecret) - 1;
1280                         while ((p >= filesecret) &&
1281                               (*p < ' ')) {
1282                                *p = '\0';
1283                                --p;
1284                         }
1285
1286                         if (strlen(filesecret) < 2) {
1287                                ERROR("Secret in %s is too short", optarg);
1288                                exit(1);
1289                         }
1290                         secret = filesecret;
1291                 }
1292                        break;
1293                 case 't':
1294                         if (!isdigit((int) *optarg))
1295                                 usage();
1296                         timeout = atof(optarg);
1297                         break;
1298                 case 'v':
1299                         DEBUG("%s", radclient_version);
1300                         exit(0);
1301                         break;
1302                 case 'x':
1303                         fr_debug_flag++;
1304                         rc_debug_flag++;
1305                         break;
1306                 case 'h':
1307                 default:
1308                         usage();
1309                         break;
1310         }
1311         argc -= (optind - 1);
1312         argv += (optind - 1);
1313
1314         if ((argc < 3)  || ((secret == NULL) && (argc < 4))) {
1315                 ERROR("Insufficient arguments");
1316                 usage();
1317         }
1318         /*
1319          *      Mismatch between the binary and the libraries it depends on
1320          */
1321         if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
1322                 fr_perror("radclient");
1323                 return 1;
1324         }
1325
1326         if (dict_init(dict_dir, RADIUS_DICTIONARY) < 0) {
1327                 fr_perror("radclient");
1328                 return 1;
1329         }
1330
1331         if (dict_read(radius_dir, RADIUS_DICTIONARY) == -1) {
1332                 fr_perror("radclient");
1333                 return 1;
1334         }
1335         fr_strerror();  /* Clear the error buffer */
1336
1337
1338         /*
1339          *      Get the request type
1340          */
1341         if (!isdigit((int) argv[2][0])) {
1342                 packet_code = fr_str2int(request_types, argv[2], -2);
1343                 if (packet_code == -2) {
1344                         ERROR("Unrecognised request type \"%s\"", argv[2]);
1345                         usage();
1346                 }
1347         } else {
1348                 packet_code = atoi(argv[2]);
1349         }
1350
1351         /*
1352          *      Resolve hostname.
1353          */
1354         if (force_af == AF_UNSPEC) force_af = AF_INET;
1355         server_ipaddr.af = force_af;
1356         if (strcmp(argv[1], "-") != 0) {
1357                 char *p;
1358                 char const *hostname = argv[1];
1359                 char const *portname = argv[1];
1360                 char buffer[256];
1361
1362                 if (*argv[1] == '[') { /* IPv6 URL encoded */
1363                         p = strchr(argv[1], ']');
1364                         if ((size_t) (p - argv[1]) >= sizeof(buffer)) {
1365                                 usage();
1366                         }
1367
1368                         memcpy(buffer, argv[1] + 1, p - argv[1] - 1);
1369                         buffer[p - argv[1] - 1] = '\0';
1370
1371                         hostname = buffer;
1372                         portname = p + 1;
1373
1374                 }
1375                 p = strchr(portname, ':');
1376                 if (p && (strchr(p + 1, ':') == NULL)) {
1377                         *p = '\0';
1378                         portname = p + 1;
1379                 } else {
1380                         portname = NULL;
1381                 }
1382
1383                 if (ip_hton(&server_ipaddr, force_af, hostname, false) < 0) {
1384                         ERROR("Failed to find IP address for host %s: %s", hostname, strerror(errno));
1385                         exit(1);
1386                 }
1387
1388                 /*
1389                  *      Strip port from hostname if needed.
1390                  */
1391                 if (portname) server_port = atoi(portname);
1392
1393                 /*
1394                  *      Work backwards from the port to determine the packet type
1395                  */
1396                 if (packet_code == PW_CODE_UNDEFINED) packet_code = radclient_get_code(server_port);
1397         }
1398
1399         radclient_get_port(packet_code, &server_port);
1400
1401         /*
1402          *      Add the secret.
1403          */
1404         if (argv[3]) secret = argv[3];
1405
1406         /*
1407          *      If no '-f' is specified, we're reading from stdin.
1408          */
1409         if (rbtree_num_elements(filename_tree) == 0) {
1410                 rc_file_pair_t *files;
1411
1412                 files = talloc_zero(talloc_autofree_context(), rc_file_pair_t);
1413                 files->packets = "stdin";
1414                 if (!radclient_init(files, files)) {
1415                         exit(1);
1416                 }
1417         }
1418
1419         /*
1420          *      Walk over the list of filenames, creating the requests.
1421          */
1422         if (rbtree_walk(filename_tree, RBTREE_IN_ORDER, filename_walk, NULL) != 0) {
1423                 ERROR("Failed parsing input files");
1424                 exit(1);
1425         }
1426
1427         /*
1428          *      No packets read.  Die.
1429          */
1430         if (!request_head) {
1431                 ERROR("Nothing to send");
1432                 exit(1);
1433         }
1434
1435         /*
1436          *      Bind to the first specified IP address and port.
1437          *      This means we ignore later ones.
1438          */
1439         if (request_head->packet->src_ipaddr.af == AF_UNSPEC) {
1440                 memset(&client_ipaddr, 0, sizeof(client_ipaddr));
1441                 client_ipaddr.af = server_ipaddr.af;
1442                 client_port = 0;
1443         } else {
1444                 client_ipaddr = request_head->packet->src_ipaddr;
1445                 client_port = request_head->packet->src_port;
1446         }
1447 #ifdef WITH_TCP
1448         if (proto) {
1449                 sockfd = fr_tcp_client_socket(NULL, &server_ipaddr, server_port);
1450         } else
1451 #endif
1452         sockfd = fr_socket(&client_ipaddr, client_port);
1453         if (sockfd < 0) {
1454                 ERROR("Error opening socket");
1455                 exit(1);
1456         }
1457
1458         pl = fr_packet_list_create(1);
1459         if (!pl) {
1460                 ERROR("Out of memory");
1461                 exit(1);
1462         }
1463
1464         if (!fr_packet_list_socket_add(pl, sockfd, ipproto, &server_ipaddr,
1465                                        server_port, NULL)) {
1466                 ERROR("Out of memory");
1467                 exit(1);
1468         }
1469
1470         /*
1471          *      Walk over the list of packets, sanity checking
1472          *      everything.
1473          */
1474         for (this = request_head; this != NULL; this = this->next) {
1475                 this->packet->src_ipaddr = client_ipaddr;
1476                 this->packet->src_port = client_port;
1477                 if (radclient_sane(this) != 0) {
1478                         exit(1);
1479                 }
1480         }
1481
1482         /*
1483          *      Walk over the packets to send, until
1484          *      we're all done.
1485          *
1486          *      FIXME: This currently busy-loops until it receives
1487          *      all of the packets.  It should really have some sort of
1488          *      send packet, get time to wait, select for time, etc.
1489          *      loop.
1490          */
1491         do {
1492                 int n = parallel;
1493                 rc_request_t *next;
1494                 char const *filename = NULL;
1495
1496                 done = true;
1497                 sleep_time = -1;
1498
1499                 /*
1500                  *      Walk over the packets, sending them.
1501                  */
1502
1503                 for (this = request_head; this != NULL; this = next) {
1504                         next = this->next;
1505
1506                         /*
1507                          *      If there's a packet to receive,
1508                          *      receive it, but don't wait for a
1509                          *      packet.
1510                          */
1511                         recv_one_packet(0);
1512
1513                         /*
1514                          *      This packet is done.  Delete it.
1515                          */
1516                         if (this->done) {
1517                                 talloc_free(this);
1518                                 continue;
1519                         }
1520
1521                         /*
1522                          *      Packets from multiple '-f' are sent
1523                          *      in parallel.
1524                          *
1525                          *      Packets from one file are sent in
1526                          *      series, unless '-p' is specified, in
1527                          *      which case N packets from each file
1528                          *      are sent in parallel.
1529                          */
1530                         if (this->files->packets != filename) {
1531                                 filename = this->files->packets;
1532                                 n = parallel;
1533                         }
1534
1535                         if (n > 0) {
1536                                 n--;
1537
1538                                 /*
1539                                  *      Send the current packet.
1540                                  */
1541                                 send_one_packet(this);
1542
1543                                 /*
1544                                  *      Wait a little before sending
1545                                  *      the next packet, if told to.
1546                                  */
1547                                 if (persec) {
1548                                         struct timeval tv;
1549
1550                                         /*
1551                                          *      Don't sleep elsewhere.
1552                                          */
1553                                         sleep_time = 0;
1554
1555                                         if (persec == 1) {
1556                                                 tv.tv_sec = 1;
1557                                                 tv.tv_usec = 0;
1558                                         } else {
1559                                                 tv.tv_sec = 0;
1560                                                 tv.tv_usec = 1000000/persec;
1561                                         }
1562
1563                                         /*
1564                                          *      Sleep for milliseconds,
1565                                          *      portably.
1566                                          *
1567                                          *      If we get an error or
1568                                          *      a signal, treat it like
1569                                          *      a normal timeout.
1570                                          */
1571                                         select(0, NULL, NULL, NULL, &tv);
1572                                 }
1573
1574                                 /*
1575                                  *      If we haven't sent this packet
1576                                  *      often enough, we're not done,
1577                                  *      and we shouldn't sleep.
1578                                  */
1579                                 if (this->resend < resend_count) {
1580                                         done = false;
1581                                         sleep_time = 0;
1582                                 }
1583                         } else { /* haven't sent this packet, we're not done */
1584                                 assert(this->done == false);
1585                                 assert(this->reply == NULL);
1586                                 done = false;
1587                         }
1588                 }
1589
1590                 /*
1591                  *      Still have outstanding requests.
1592                  */
1593                 if (fr_packet_list_num_elements(pl) > 0) {
1594                         done = false;
1595                 } else {
1596                         sleep_time = 0;
1597                 }
1598
1599                 /*
1600                  *      Nothing to do until we receive a request, so
1601                  *      sleep until then.  Once we receive one packet,
1602                  *      we go back, and walk through the whole list again,
1603                  *      sending more packets (if necessary), and updating
1604                  *      the sleep time.
1605                  */
1606                 if (!done && (sleep_time > 0)) {
1607                         recv_one_packet(sleep_time);
1608                 }
1609         } while (!done);
1610
1611         rbtree_free(filename_tree);
1612         fr_packet_list_free(pl);
1613         while (request_head) TALLOC_FREE(request_head);
1614         dict_free();
1615
1616         if (do_summary) {
1617                 DEBUG("Packet summary:\n"
1618                       "\tAccepted      : %" PRIu64 "\n"
1619                       "\tRejected      : %" PRIu64 "\n"
1620                       "\tLost          : %" PRIu64 "\n"
1621                       "\tPassed filter : %" PRIu64 "\n"
1622                       "\tFailed filter : %" PRIu64,
1623                       stats.accepted,
1624                       stats.rejected,
1625                       stats.lost,
1626                       stats.passed,
1627                       stats.failed
1628                 );
1629         }
1630
1631         if ((stats.lost > 0) || (stats.failed > 0)) {
1632                 exit(1);
1633         }
1634         exit(0);
1635 }