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