static int server_port = 0;
static int packet_code = 0;
-static lrad_ipaddr_t server_ipaddr;
+static uint32_t server_ipaddr = 0;
static int resend_count = 1;
static int done = 1;
static radclient_t *radclient_tail = NULL;
-static void usage(void)
+static void NEVER_RETURNS usage(void)
{
fprintf(stderr, "Usage: radclient [options] server[:port] <command> [<secret>]\n");
fprintf(stderr, " -t timeout Wait 'timeout' seconds before retrying (may be a floating point number).\n");
fprintf(stderr, " -v Show program version information.\n");
fprintf(stderr, " -x Debugging mode.\n");
- fprintf(stderr, " -4 Use IPv4 address of server\n");
- fprintf(stderr, " -6 Use IPv6 address of server.\n");
exit(1);
}
* Keep a copy of the the User-Password attribute.
*/
if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
- strNcpy(radclient->password, (char *)vp->strvalue, sizeof(vp->strvalue));
+ strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
/*
* Otherwise keep a copy of the CHAP-Password attribute.
*/
} else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
- strNcpy(radclient->password, (char *)vp->strvalue, sizeof(vp->strvalue));
+ strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
} else {
radclient->password[0] = '\0';
}
radclient->request->dst_port = (vp->lvalue & 0xffff);
break;
- case PW_PACKET_DST_IP_ADDRESS:
- radclient->request->dst_ipaddr.af = AF_INET;
- radclient->request->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
- break;
-
- case PW_PACKET_DST_IPV6_ADDRESS:
- radclient->request->dst_ipaddr.af = AF_INET6;
- memcpy(&radclient->request->dst_ipaddr.ipaddr.ip6addr,
- vp->strvalue,
- sizeof(radclient->request->dst_ipaddr.ipaddr.ip6addr));
- break;
-
- case PW_PACKET_SRC_PORT:
- radclient->request->src_port = (vp->lvalue & 0xffff);
- break;
-
- case PW_PACKET_SRC_IP_ADDRESS:
- radclient->request->src_ipaddr.af = AF_INET;
- radclient->request->src_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
- break;
-
- case PW_PACKET_SRC_IPV6_ADDRESS:
- radclient->request->src_ipaddr.af = AF_INET6;
- memcpy(&radclient->request->src_ipaddr.ipaddr.ip6addr,
- vp->strvalue,
- sizeof(radclient->request->src_ipaddr.ipaddr.ip6addr));
- break;
-
case PW_DIGEST_REALM:
case PW_DIGEST_NONCE:
case PW_DIGEST_METHOD:
if (radclient->request->dst_port == 0) {
radclient->request->dst_port = server_port;
}
- if (radclient->request->dst_ipaddr.af == AF_UNSPEC) {
- if (server_ipaddr.af == AF_UNSPEC) {
- fprintf(stderr, "radclient: No server was given, but request %d in file %s did not contain Packet-Dst-IP-Address\n",
- radclient->packet_number, radclient->filename);
- return -1;
- }
- radclient->request->dst_ipaddr = server_ipaddr;
- }
+ radclient->request->dst_ipaddr = server_ipaddr;
+
if (radclient->request->code == 0) {
if (packet_code == -1) {
fprintf(stderr, "radclient: Request was \"auto\", but request %d in file %s did not contain Packet-Type\n",
*/
static int request_cmp(const void *one, const void *two)
{
- int rcode;
const radclient_t *a = one;
const radclient_t *b = two;
if (a->request->id < b->request->id) return -1;
if (a->request->id > b->request->id) return +1;
- if (a->request->dst_ipaddr.af < b->request->dst_ipaddr.af) return -1;
- if (a->request->dst_ipaddr.af > b->request->dst_ipaddr.af) return +1;
-
- switch (a->request->dst_ipaddr.af) {
- case AF_INET:
- rcode = memcmp(&a->request->dst_ipaddr.ipaddr.ip4addr,
- &b->request->dst_ipaddr.ipaddr.ip4addr,
- sizeof(a->request->dst_ipaddr.ipaddr.ip4addr));
- break;
- case AF_INET6:
- rcode = memcmp(&a->request->dst_ipaddr.ipaddr.ip6addr,
- &b->request->dst_ipaddr.ipaddr.ip6addr,
- sizeof(a->request->dst_ipaddr.ipaddr.ip6addr));
- break;
- default: /* FIXME: die! */
- return -1;
- break;
- }
- if (rcode != 0) return rcode;
+ if (a->request->dst_ipaddr < b->request->dst_ipaddr) return -1;
+ if (a->request->dst_ipaddr > b->request->dst_ipaddr) return +1;
if (a->request->dst_port < b->request->dst_port) return -1;
if (a->request->dst_port > b->request->dst_port) return +1;
VALUE_PAIR *vp;
if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
- strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);
- vp->length = strlen(radclient->password);
+ strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
+ vp->length = strlen(vp->strvalue);
} else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
- strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);
- vp->length = strlen(radclient->password);
+ strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
+ vp->length = strlen(vp->strvalue);
rad_chap_encode(radclient->request, (char *) vp->strvalue, radclient->request->id, vp);
vp->length = 17;
/*
* Send the packet.
*/
- rad_send(radclient->request, NULL, secret);
+ if (rad_send(radclient->request, NULL, secret) < 0) {
+ fprintf(stderr, "radclient: Failed to send packet for ID %d: %s\n",
+ radclient->request->id, librad_errstr);
+ }
return 0;
}
*/
reply = rad_recv(sockfd);
if (!reply) {
- fprintf(stderr, "radclient: received bad packet: %s\n",
- librad_errstr);
+ fprintf(stderr, "radclient: received bad packet\n");
return -1; /* bad packet */
}
node = rbtree_find(request_tree, &myclient);
if (!node) {
fprintf(stderr, "radclient: received response to request we did not send.\n");
+ rad_free(&reply);
return -1; /* got reply to packet we didn't send */
}
if (rad_decode(reply, radclient->request, secret) != 0) {
librad_perror("rad_decode");
totallost++;
- return -1;
+ goto packet_done; /* shared secret is incorrect */
}
/* libradius debug already prints out the value pairs for us */
totaldeny++;
}
- if (radclient->reply) rad_free(&radclient->reply);
+packet_done:
+ rad_free(&radclient->reply);
/*
* Once we've sent the packet as many times as requested,
return 0;
}
-
static int getport(const char *name)
{
struct servent *svp;
int persec = 0;
int parallel = 1;
radclient_t *this;
- int force_af = AF_UNSPEC;
- int len = 0;
- struct sockaddr_storage ss;
- struct sockaddr_in *s4;
librad_debug = 0;
exit(1);
}
- while ((c = getopt(argc, argv, "46c:d:f:hi:n:p:qr:sS:t:vx")) != EOF) switch(c) {
- case '4':
- force_af = AF_INET;
- break;
- case '6':
- force_af = AF_INET6;
- break;
+ while ((c = getopt(argc, argv, "c:d:f:hi:n:p:qr:sS:t:vx")) != EOF) switch(c) {
case 'c':
if (!isdigit((int) *optarg))
usage();
}
/*
- * Resolve hostname.
+ * Strip port from hostname if needed.
*/
- server_ipaddr.af = force_af;
- if (strcmp(argv[1], "-") != 0) {
- const char *hostname = argv[1];
- const char *portname = argv[1];
- char buffer[256];
-
- if (*argv[1] == '[') { /* IPv6 URL encoded */
- p = strchr(argv[1], ']');
- if ((p - argv[1]) >= sizeof(buffer)) {
- usage();
- }
-
- memcpy(buffer, argv[1] + 1, p - argv[1] - 1);
- buffer[p - argv[1] - 1] = '\0';
-
- hostname = buffer;
- portname = p + 1;
-
- }
- p = strchr(portname, ':');
- if (p && (strchr(p + 1, ':') == NULL)) {
- *p = '\0';
- portname = p + 1;
- } else {
- portname = NULL;
- }
-
- if (ip_hton(hostname, force_af, &server_ipaddr) < 0) {
- fprintf(stderr, "radclient: Failed to find IP address for host %s: %s\n", argv[1], strerror(errno));
- exit(1);
- }
-
- /*
- * Strip port from hostname if needed.
- */
- if (portname) server_port = atoi(portname);
+ if ((p = strchr(argv[1], ':')) != NULL) {
+ *p++ = 0;
+ server_port = atoi(p);
}
+ /*
+ * Grab the socket.
+ */
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ perror("radclient: socket: ");
+ exit(1);
+ }
memset(radius_id, 0, sizeof(radius_id));
/*
}
/*
+ * Resolve hostname.
+ */
+ server_ipaddr = ip_getaddr(argv[1]);
+ if (server_ipaddr == INADDR_NONE) {
+ fprintf(stderr, "radclient: Failed to find IP address for host %s\n", argv[1]);
+ exit(1);
+ }
+
+ /*
* Add the secret.
*/
if (argv[3]) secret = argv[3];
}
/*
- * Bind only if Packet-Src-IP(v6)Address Attribute is found
- */
- switch (radclient_head->request->src_ipaddr.af) {
- case AF_UNSPEC:
- default:
- /*
- * Grab the socket.
- */
- if ((sockfd = socket(server_ipaddr.af, SOCK_DGRAM, 0)) < 0) {
- perror("radclient: socket: ");
- exit(1);
- }
- break;
-
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
- case AF_INET6:
- {
- struct sockaddr_in6 *s6;
- s6 = (struct sockaddr_in6 *)&ss;
- len = sizeof(struct sockaddr_in6);
- s6->sin6_family = AF_INET6;
- s6->sin6_flowinfo = 0;
- s6->sin6_port = htons(radclient_head->request->src_port);
- memcpy(&s6->sin6_addr, &radclient_head->request->src_ipaddr.ipaddr, 16);
- }
- goto sock_bind;
-#endif
-
- case AF_INET:
- s4 = (struct sockaddr_in *)&ss;
- len = sizeof(struct sockaddr_in);
- s4->sin_family = AF_INET;
- s4->sin_port = htons(radclient_head->request->src_port);
- memcpy(&s4->sin_addr, &radclient_head->request->src_ipaddr.ipaddr, 4);
- goto sock_bind;
-
- sock_bind:
- if ((sockfd = socket(radclient_head->request->src_ipaddr.af,
- SOCK_DGRAM, 0)) < 0) {
-
- perror("radclient: socket: ");
- exit(1);
- }
- if (bind(sockfd, (struct sockaddr *)&ss, len) < 0) {
- perror("radclient: bind: ");
- exit(1);
- }
- break;
- }
-
- /*
* Walk over the list of packets, sanity checking
* everything.
*/