2 * $Id: recv.c,v 1.14 2011/02/06 03:41:38 reubenhwk Exp $
5 * Pedro Roque <roque@di.fc.ul.pt>
6 * Lars Fenneberg <lf@elemental.net>
8 * This software is Copyright 1996,1997 by the above mentioned author(s),
11 * The license which is distributed with this software in the file COPYRIGHT
12 * applies to this software. If your distribution is missing this file, you
13 * may request it from <pekkas@netcore.fi>.
22 recv_rs_ra(unsigned char *msg
, struct sockaddr_in6
*addr
,
23 struct in6_pktinfo
**pkt_info
, int *hoplimit
)
28 static unsigned char *chdr
= NULL
;
29 static unsigned int chdrlen
= 0;
35 chdrlen
= CMSG_SPACE(sizeof(struct in6_pktinfo
)) +
36 CMSG_SPACE(sizeof(int));
37 if ((chdr
= malloc(chdrlen
)) == NULL
) {
38 flog(LOG_ERR
, "recv_rs_ra: malloc: %s", strerror(errno
));
44 FD_SET( sock
, &rfds
);
46 if( select( sock
+1, &rfds
, NULL
, NULL
, NULL
) < 0 )
49 flog(LOG_ERR
, "select: %s", strerror(errno
));
54 iov
.iov_len
= MSG_SIZE_RECV
;
55 iov
.iov_base
= (caddr_t
) msg
;
57 memset(&mhdr
, 0, sizeof(mhdr
));
58 mhdr
.msg_name
= (caddr_t
)addr
;
59 mhdr
.msg_namelen
= sizeof(*addr
);
62 mhdr
.msg_control
= (void *)chdr
;
63 mhdr
.msg_controllen
= chdrlen
;
65 len
= recvmsg(sock
, &mhdr
, 0);
70 flog(LOG_ERR
, "recvmsg: %s", strerror(errno
));
77 for (cmsg
= CMSG_FIRSTHDR(&mhdr
); cmsg
!= NULL
; cmsg
= CMSG_NXTHDR(&mhdr
, cmsg
))
79 if (cmsg
->cmsg_level
!= IPPROTO_IPV6
)
82 switch(cmsg
->cmsg_type
)
86 if ((cmsg
->cmsg_len
== CMSG_LEN(sizeof(int))) &&
87 (*(int *)CMSG_DATA(cmsg
) >= 0) &&
88 (*(int *)CMSG_DATA(cmsg
) < 256))
90 *hoplimit
= *(int *)CMSG_DATA(cmsg
);
94 flog(LOG_ERR
, "received a bogus IPV6_HOPLIMIT from the kernel! len=%d, data=%d",
95 cmsg
->cmsg_len
, *(int *)CMSG_DATA(cmsg
));
99 #endif /* IPV6_HOPLIMIT */
101 if ((cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct in6_pktinfo
))) &&
102 ((struct in6_pktinfo
*)CMSG_DATA(cmsg
))->ipi6_ifindex
)
104 *pkt_info
= (struct in6_pktinfo
*)CMSG_DATA(cmsg
);
108 flog(LOG_ERR
, "received a bogus IPV6_PKTINFO from the kernel! len=%d, index=%d",
109 cmsg
->cmsg_len
, ((struct in6_pktinfo
*)CMSG_DATA(cmsg
))->ipi6_ifindex
);
116 dlog(LOG_DEBUG
, 4, "recvmsg len=%d", len
);