Revision 75a354bb src/charon/network/socket.c
| b/src/charon/network/socket.c | ||
|---|---|---|
| 54 | 54 |
/* these are not defined on some platforms */ |
| 55 | 55 |
#ifndef SOL_IP |
| 56 | 56 |
#define SOL_IP IPPROTO_IP |
| 57 |
#endif |
|
| 58 |
#ifndef SOL_IPV6 |
|
| 57 | 59 |
#define SOL_IPV6 IPPROTO_IPV6 |
| 60 |
#endif |
|
| 61 |
#ifndef SOL_UDP |
|
| 58 | 62 |
#define SOL_UDP IPPROTO_UDP |
| 59 | 63 |
#endif |
| 60 | 64 |
|
| ... | ... | |
| 213 | 217 |
dest = host_create_from_sockaddr((sockaddr_t*)&dst); |
| 214 | 218 |
} |
| 215 | 219 |
if (cmsgptr->cmsg_level == SOL_IP && |
| 216 |
#ifdef IP_RECVDSTADDR |
|
| 220 |
#ifdef IP_PKTINFO |
|
| 221 |
cmsgptr->cmsg_type == IP_PKTINFO |
|
| 222 |
#elif defined(IP_RECVDSTADDR) |
|
| 217 | 223 |
cmsgptr->cmsg_type == IP_RECVDSTADDR |
| 218 | 224 |
#else |
| 219 |
cmsgptr->cmsg_type == IP_PKTINFO |
|
| 225 |
FALSE |
|
| 220 | 226 |
#endif |
| 221 | 227 |
) |
| 222 | 228 |
{
|
| 223 | 229 |
struct in_addr *addr; |
| 224 |
struct sockaddr_in dst; |
|
| 230 |
struct sockaddr_in dst; |
|
| 225 | 231 |
|
| 226 |
#ifdef IP_RECVDSTADDR |
|
| 227 |
addr = (struct in_addr*)CMSG_DATA(cmsgptr); |
|
| 228 |
#else |
|
| 232 |
#ifdef IP_PKTINFO |
|
| 229 | 233 |
struct in_pktinfo *pktinfo; |
| 230 | 234 |
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr); |
| 231 | 235 |
addr = &pktinfo->ipi_addr; |
| 236 |
#elif defined(IP_RECVDSTADDR) |
|
| 237 |
addr = (struct in_addr*)CMSG_DATA(cmsgptr); |
|
| 232 | 238 |
#endif |
| 233 | 239 |
memset(&dst, 0, sizeof(dst)); |
| 234 | 240 |
memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr)); |
| ... | ... | |
| 355 | 361 |
{
|
| 356 | 362 |
if (family == AF_INET) |
| 357 | 363 |
{
|
| 364 |
#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR) |
|
| 358 | 365 |
struct in_addr *addr; |
| 359 | 366 |
struct sockaddr_in *sin; |
| 360 |
#ifdef IP_SENDSRCADDR |
|
| 361 |
char buf[CMSG_SPACE(sizeof(struct in_addr))]; |
|
| 362 |
#else |
|
| 367 |
#ifdef IP_PKTINFO |
|
| 363 | 368 |
char buf[CMSG_SPACE(sizeof(struct in_pktinfo))]; |
| 364 | 369 |
struct in_pktinfo *pktinfo; |
| 370 |
#elif defined(IP_SENDSRCADDR) |
|
| 371 |
char buf[CMSG_SPACE(sizeof(struct in_addr))]; |
|
| 365 | 372 |
#endif |
| 366 | 373 |
msg.msg_control = buf; |
| 367 | 374 |
msg.msg_controllen = sizeof(buf); |
| 368 | 375 |
cmsg = CMSG_FIRSTHDR(&msg); |
| 369 | 376 |
cmsg->cmsg_level = SOL_IP; |
| 370 |
#ifdef IP_SENDSRCADDR |
|
| 371 |
cmsg->cmsg_type = IP_SENDSRCADDR; |
|
| 372 |
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); |
|
| 373 |
addr = (struct in_addr*)CMSG_DATA(cmsg); |
|
| 374 |
#else |
|
| 377 |
#ifdef IP_PKTINFO |
|
| 375 | 378 |
cmsg->cmsg_type = IP_PKTINFO; |
| 376 | 379 |
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); |
| 377 | 380 |
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); |
| 378 | 381 |
memset(pktinfo, 0, sizeof(struct in_pktinfo)); |
| 379 | 382 |
addr = &pktinfo->ipi_spec_dst; |
| 383 |
#elif defined(IP_SENDSRCADDR) |
|
| 384 |
cmsg->cmsg_type = IP_SENDSRCADDR; |
|
| 385 |
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); |
|
| 386 |
addr = (struct in_addr*)CMSG_DATA(cmsg); |
|
| 380 | 387 |
#endif |
| 381 | 388 |
sin = (struct sockaddr_in*)src->get_sockaddr(src); |
| 382 | 389 |
memcpy(addr, &sin->sin_addr, sizeof(struct in_addr)); |
| 390 |
#endif /* IP_PKTINFO || IP_SENDSRCADDR */ |
|
| 383 | 391 |
} |
| 384 | 392 |
else |
| 385 | 393 |
{
|
| ... | ... | |
| 419 | 427 |
int type = UDP_ENCAP_ESPINUDP; |
| 420 | 428 |
struct sockaddr_storage addr; |
| 421 | 429 |
socklen_t addrlen; |
| 422 |
u_int sol, pktinfo; |
|
| 430 |
u_int sol, pktinfo = 0; |
|
| 423 | 431 |
int skt; |
| 424 | 432 |
|
| 425 | 433 |
memset(&addr, 0, sizeof(addr)); |
| ... | ... | |
| 434 | 442 |
sin->sin_port = htons(port); |
| 435 | 443 |
addrlen = sizeof(struct sockaddr_in); |
| 436 | 444 |
sol = SOL_IP; |
| 437 |
#ifdef IP_RECVDSTADDR |
|
| 438 |
pktinfo = IP_RECVDSTADDR; |
|
| 439 |
#else |
|
| 445 |
#ifdef IP_PKTINFO |
|
| 440 | 446 |
pktinfo = IP_PKTINFO; |
| 447 |
#elif defined(IP_RECVDSTADDR) |
|
| 448 |
pktinfo = IP_RECVDSTADDR; |
|
| 441 | 449 |
#endif |
| 442 | 450 |
break; |
| 443 | 451 |
} |
| ... | ... | |
| 478 | 486 |
} |
| 479 | 487 |
|
| 480 | 488 |
/* get additional packet info on receive */ |
| 481 |
if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0) |
|
| 489 |
if (pktinfo > 0) |
|
| 482 | 490 |
{
|
| 483 |
DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno)); |
|
| 484 |
close(skt); |
|
| 485 |
return 0; |
|
| 491 |
if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0) |
|
| 492 |
{
|
|
| 493 |
DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno)); |
|
| 494 |
close(skt); |
|
| 495 |
return 0; |
|
| 496 |
} |
|
| 486 | 497 |
} |
| 487 | 498 |
|
| 488 | 499 |
/* enable UDP decapsulation globally, only for one socket needed */ |
Also available in: Unified diff