2
2
* vqp.c Functions to send/receive VQP packets.
4
* Version: $Id: vqp.c,v 1.4 2008/01/05 17:58:44 nbk Exp $
6
6
* This library is free software; you can redistribute it and/or
7
7
* modify it under the terms of the GNU Lesser General Public
80
82
struct sockaddr_storage dst;
81
socklen_t sizeof_dst = sizeof(dst);
83
85
#ifdef WITH_UDPFROMTO
84
86
struct sockaddr_storage src;
85
socklen_t sizeof_src = sizeof(src);
87
memset(&src, 0, sizeof(src));
89
memset(&dst, 0, sizeof(dst));
94
if (dst_ipaddr->af == AF_INET) {
95
struct sockaddr_in *s4;
97
s4 = (struct sockaddr_in *)&dst;
98
sizeof_dst = sizeof(struct sockaddr_in);
100
s4->sin_family = AF_INET;
101
s4->sin_addr = dst_ipaddr->ipaddr.ip4addr;
102
s4->sin_port = htons(dst_port);
104
#ifdef WITH_UDPFROMTO
105
s4 = (struct sockaddr_in *)&src;
106
sizeof_src = sizeof(struct sockaddr_in);
108
s4->sin_family = AF_INET;
109
s4->sin_addr = src_ipaddr->ipaddr.ip4addr;
113
* IPv6 MAY be supported.
115
#ifdef HAVE_STRUCT_SOCKADDR_IN6
116
} else if (dst_ipaddr->af == AF_INET6) {
117
struct sockaddr_in6 *s6;
119
s6 = (struct sockaddr_in6 *)&dst;
120
sizeof_dst = sizeof(struct sockaddr_in6);
122
s6->sin6_family = AF_INET6;
123
s6->sin6_addr = dst_ipaddr->ipaddr.ip6addr;
124
s6->sin6_port = htons(dst_port);
126
#ifdef WITH_UDPFROMTO
127
return -1; /* UDPFROMTO && IPv6 are not supported */
129
s6 = (struct sockaddr_in6 *)&src;
130
sizeof_src = sizeof(struct sockaddr_in6);
132
s6->sin6_family = AF_INET6;
133
s6->sin6_addr = src_ipaddr->ipaddr.ip6addr;
135
#endif /* WITH_UDPFROMTO */
136
#endif /* HAVE_STRUCT_SOCKADDR_IN6 */
137
} else return -1; /* Unknown address family, Die Die Die! */
89
fr_ipaddr2sockaddr(src_ipaddr, 0, &src, &sizeof_src);
91
src_ipaddr = src_ipaddr; /* -Wunused */
94
if (!fr_ipaddr2sockaddr(dst_ipaddr, dst_port, &dst, &sizeof_dst)) {
95
return -1; /* Unknown address family, Die Die Die! */
139
98
#ifdef WITH_UDPFROMTO
289
* Check address families, and update src/dst ports, etc.
291
if (src.ss_family == AF_INET) {
292
struct sockaddr_in *s4;
294
s4 = (struct sockaddr_in *)&src;
295
src_ipaddr->af = AF_INET;
296
src_ipaddr->ipaddr.ip4addr = s4->sin_addr;
297
*src_port = ntohs(s4->sin_port);
299
s4 = (struct sockaddr_in *)&dst;
300
dst_ipaddr->af = AF_INET;
301
dst_ipaddr->ipaddr.ip4addr = s4->sin_addr;
302
*dst_port = ntohs(s4->sin_port);
304
#ifdef HAVE_STRUCT_SOCKADDR_IN6
305
} else if (src.ss_family == AF_INET6) {
306
struct sockaddr_in6 *s6;
308
s6 = (struct sockaddr_in6 *)&src;
309
src_ipaddr->af = AF_INET6;
310
src_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
311
*src_port = ntohs(s6->sin6_port);
313
s6 = (struct sockaddr_in6 *)&dst;
314
dst_ipaddr->af = AF_INET6;
315
dst_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
316
*dst_port = ntohs(s6->sin6_port);
248
if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, &port)) {
320
250
return -1; /* Unknown address family, Die Die Die! */
254
fr_sockaddr2ipaddr(&dst, sizeof_dst, dst_ipaddr, &port);
324
258
* Different address families should never happen.
347
281
* Allocate the new request data structure
349
283
if ((packet = malloc(sizeof(*packet))) == NULL) {
350
librad_log("out of memory");
284
fr_strerror_printf("out of memory");
353
287
memset(packet, 0, sizeof(*packet));
360
294
* Check for socket errors.
362
296
if (packet->data_len < 0) {
363
librad_log("Error receiving packet: %s", strerror(errno));
297
fr_strerror_printf("Error receiving packet: %s", strerror(errno));
364
298
/* packet->data is NULL */
430
364
* server reasons. Also, there's no reason
431
365
* for bigger lengths to exist... admins
432
366
* won't be typing in a 32K vlan name.
368
* Except for received ethernet frames...
369
* they get chopped to 253 internally.
434
if ((ptr[4] != 0) || (ptr[5] > 253)) {
435
librad_log("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
372
((ptr[4] != 0) || (ptr[5] > MAX_VMPS_LEN))) {
373
fr_strerror_printf("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
436
374
rad_free(&packet);
620
559
vp = pairfind(packet->vps, PW_VQP_PACKET_TYPE);
622
librad_log("Failed to find VQP-Packet-Type in response packet");
561
fr_strerror_printf("Failed to find VQP-Packet-Type in response packet");
626
565
code = vp->lvalue;
627
566
if ((code < 1) || (code > 4)) {
628
librad_log("Invalid value %d for VQP-Packet-Type", code);
567
fr_strerror_printf("Invalid value %d for VQP-Packet-Type", code);