#include <assert.h>
-static int retries = 10;
-static float timeout = 3;
+static int success = 0;
+static int retries = 3;
+static float timeout = 5;
static const char *secret = NULL;
static int do_output = 1;
static int totalapp = 0;
static int sockfd;
static int last_used_id = -1;
+#ifdef WITH_TCP
+const char *proto = NULL;
+#endif
+static int ipproto = IPPROTO_UDP;
+
static rbtree_t *filename_tree = NULL;
static fr_packet_list_t *pl = NULL;
fprintf(stderr, " -x Debugging mode.\n");
fprintf(stderr, " -4 Use IPv4 address of server\n");
fprintf(stderr, " -6 Use IPv6 address of server.\n");
+#ifdef WITH_TCP
+ fprintf(stderr, " -P proto Use proto (tcp or udp) for transport.\n");
+#endif
exit(1);
}
return 0;
}
+#ifdef WITH_TCP
+ radclient->request->src_ipaddr = client_ipaddr;
+ radclient->request->src_port = client_port;
+ radclient->request->dst_ipaddr = server_ipaddr;
+ radclient->request->dst_port = server_port;
+#endif
+
radclient->filename = filename;
radclient->request->id = -1; /* allocate when sending */
radclient->packet_number = packet_number++;
* this packet.
*/
retry:
- rcode = fr_packet_list_id_alloc(pl, radclient->request);
+ radclient->request->src_ipaddr.af = server_ipaddr.af;
+ rcode = fr_packet_list_id_alloc(pl, ipproto,
+ radclient->request, NULL);
if (rcode < 0) {
int mysockfd;
+#ifdef WITH_TCP
+ if (proto) {
+ mysockfd = fr_tcp_client_socket(NULL,
+ &server_ipaddr,
+ server_port);
+ } else
+#endif
mysockfd = fr_socket(&client_ipaddr, 0);
if (!mysockfd) {
fprintf(stderr, "radclient: Can't open new socket\n");
exit(1);
}
- if (!fr_packet_list_socket_add(pl, mysockfd)) {
+ if (!fr_packet_list_socket_add(pl, mysockfd, ipproto,
+ &server_ipaddr,
+ server_port, NULL)) {
fprintf(stderr, "radclient: Can't add new socket\n");
exit(1);
}
assert(0 == 1);
}
+#ifdef WITH_TCP
+ /*
+ * WTF?
+ */
+ if (client_port == 0) {
+ client_ipaddr = radclient->request->src_ipaddr;
+ client_port = radclient->request->src_port;
+ }
+#endif
+
} else { /* radclient->request->id >= 0 */
time_t now = time(NULL);
/*
* Look for the packet.
*/
+
reply = fr_packet_list_recv(pl, &set);
if (!reply) {
fprintf(stderr, "radclient: received bad packet: %s\n",
fr_strerror());
+#ifdef WITH_TCP
+ /*
+ * If the packet is bad, we close the socket.
+ * I'm not sure how to do that now, so we just
+ * die...
+ */
+ if (proto) exit(1);
+#endif
return -1; /* bad packet */
}
* (say) 127.0.0.1.
*/
reply->dst_ipaddr = client_ipaddr;
+ reply->dst_port = client_port;
+#ifdef WITH_TCP
+ reply->src_ipaddr = server_ipaddr;
+ reply->src_port = server_port;
+#endif
if (fr_debug_flag > 2) print_hex(reply);
reply->code);
deallocate_id(radclient);
radclient->reply = reply;
+ reply = NULL;
/*
* If this fails, we're out of memory.
*/
- if (rad_decode(reply, radclient->request, secret) != 0) {
+ if (rad_decode(radclient->reply, radclient->request, secret) != 0) {
fr_perror("rad_decode");
totallost++;
goto packet_done;
/* libradius debug already prints out the value pairs for us */
if (!fr_debug_flag && do_output) {
- printf("Received response ID %d, code %d, length = %d\n",
- reply->id, reply->code, reply->data_len);
- vp_printlist(stdout, reply->vps);
+ printf("Received response ID %d, code %d, length = %ld\n",
+ radclient->reply->id, radclient->reply->code,
+ radclient->reply->data_len);
+ vp_printlist(stdout, radclient->reply->vps);
}
- if (reply->code != PW_AUTHENTICATION_REJECT) {
+
+ if ((radclient->reply->code == PW_AUTHENTICATION_ACK) ||
+ (radclient->reply->code == PW_ACCOUNTING_RESPONSE) ||
+ (radclient->reply->code == PW_COA_ACK) ||
+ (radclient->reply->code == PW_DISCONNECT_ACK)) {
+ success = 1; /* have a good response */
totalapp++;
} else {
totaldeny++;
packet_done:
rad_free(&radclient->reply);
+ rad_free(&reply); /* may be NULL */
return 0;
}
exit(1);
}
- while ((c = getopt(argc, argv, "46c:d:f:Fhi:n:p:qr:sS:t:vx")) != EOF) switch(c) {
+ while ((c = getopt(argc, argv, "46c:d:f:Fhi:n:p:qr:sS:t:vx"
+#ifdef WITH_TCP
+ "P:"
+#endif
+ )) != EOF) switch(c) {
case '4':
force_af = AF_INET;
break;
if (parallel <= 0) usage();
break;
+#ifdef WITH_TCP
+ case 'P':
+ proto = optarg;
+ if (strcmp(proto, "tcp") != 0) {
+ if (strcmp(proto, "udp") == 0) {
+ proto = NULL;
+ } else {
+ usage();
+ }
+ } else {
+ ipproto = IPPROTO_TCP;
+ }
+ break;
+
+#endif
+
case 'q':
do_output = 0;
fr_log_fp = NULL; /* no output from you, either! */
/*
* Resolve hostname.
*/
+ if (force_af == AF_UNSPEC) force_af = AF_INET;
server_ipaddr.af = force_af;
if (strcmp(argv[1], "-") != 0) {
const char *hostname = argv[1];
packet_code = PW_STATUS_SERVER;
} else if (strcmp(argv[2], "disconnect") == 0) {
- if (server_port == 0) server_port = PW_POD_UDP_PORT;
+ if (server_port == 0) server_port = PW_COA_UDP_PORT;
packet_code = PW_DISCONNECT_REQUEST;
} else if (strcmp(argv[2], "coa") == 0) {
- if (server_port == 0) server_port = PW_POD_UDP_PORT;
+ if (server_port == 0) server_port = PW_COA_UDP_PORT;
packet_code = PW_COA_REQUEST;
} else if (strcmp(argv[2], "auto") == 0) {
client_ipaddr = radclient_head->request->src_ipaddr;
client_port = radclient_head->request->src_port;
}
+#ifdef WITH_TCP
+ if (proto) {
+ sockfd = fr_tcp_client_socket(NULL, &server_ipaddr, server_port);
+ } else
+#endif
sockfd = fr_socket(&client_ipaddr, client_port);
if (sockfd < 0) {
fprintf(stderr, "radclient: socket: %s\n", fr_strerror());
exit(1);
}
- if (!fr_packet_list_socket_add(pl, sockfd)) {
+ if (!fr_packet_list_socket_add(pl, sockfd, ipproto, &server_ipaddr,
+ server_port, NULL)) {
fprintf(stderr, "radclient: Out of memory\n");
exit(1);
}
printf("\t Total lost auths: %d\n", totallost);
}
- return 0;
+ if (success) return 0;
+
+ return 1;
}