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);
/* 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",
+ 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);
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];
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);
}