33 #include <sys/types.h>
35 # include <winsock2.h>
36 # include <ws2tcpip.h>
38 #define ip_mreqn ip_mreq
39 #define imr_address imr_multiaddr
40 #define s6_addr16 u.Word
41 #define close closesocket
43 # include <sys/socket.h>
44 # include <netinet/in.h>
93 g_return_val_if_fail(NULL !=
self, -1);
94 g_return_val_if_fail(NULL != self->giosock, -1);
95 return g_io_channel_unix_get_fd(self->giosock);
102 int chanflags = g_io_channel_get_flags(self->giosock);
104 int fcntlflags = fcntl (self->getfd(
self), F_GETFL, 0);
106 fcntlflags |= O_NONBLOCK;
108 fcntlflags &= ~O_NONBLOCK;
110 if (fcntl(self->getfd(
self), F_SETFL, fcntlflags) < 0) {
111 g_critical(
"%s.%d: fcntl(F_SETFL, 0x%x) failed: %s",
__FUNCTION__, __LINE__
112 , fcntlflags, g_strerror(errno));
117 chanflags |= G_IO_FLAG_NONBLOCK;
119 chanflags &= ~G_IO_FLAG_NONBLOCK;
121 g_io_channel_set_flags(self->giosock, chanflags, NULL);
136 g_warning(
"%s: Cannot join multicast group with non-multicast address"
141 g_warning(
"%s: Cannot join multicast group with differing address types"
147 struct ipv6_mreq multicast_request;
148 struct sockaddr_in6 saddr;
150 memset(&multicast_request, 0,
sizeof(multicast_request));
151 memcpy(&multicast_request.ipv6mr_multiaddr, &saddr
152 ,
sizeof(multicast_request.ipv6mr_multiaddr));
154 if (localaddr == NULL) {
155 genlocal =
self->boundaddr(
self);
156 localaddr = genlocal;
162 if (localaddr != NULL) {
163 struct sockaddr_in6 laddr;
165 memcpy(&multicast_request.ipv6mr_interface, &laddr.sin6_addr
166 ,
sizeof(multicast_request.ipv6mr_interface));
169 g_warning(
"%s: Cannot join v6 multicast group - local address not IPv6"
174 rc = setsockopt(self->getfd(
self), IPPROTO_IPV6, IPV6_JOIN_GROUP
175 , (gpointer)&multicast_request,
sizeof(multicast_request));
177 g_warning(
"%s: Cannot join v6 multicast group [%s (errno:%d)]"
181 struct ip_mreqn multicast_request;
182 struct sockaddr_in saddr;
183 memset(&multicast_request, 0,
sizeof(multicast_request));
185 memcpy(&multicast_request.imr_multiaddr, &saddr.sin_addr
186 ,
sizeof(multicast_request.imr_multiaddr));
188 if (localaddr == NULL) {
189 genlocal =
self->boundaddr(
self);
190 localaddr = genlocal;
196 g_warning(
"%s: Cannot join v4 multicast group - local address not IPv4"
201 if (localaddr != NULL) {
202 struct sockaddr_in laddr;
204 memcpy(&multicast_request.imr_address, &laddr.sin_addr
205 ,
sizeof(multicast_request.imr_address));
208 rc = setsockopt(self->getfd(
self), IPPROTO_IP, IP_ADD_MEMBERSHIP
209 , (gpointer)&multicast_request,
sizeof(multicast_request));
211 g_warning(
"%s: Cannot join v4 multicast group [%s (errno:%d)]"
215 self->setmcast_ttl(
self, 31);
240 return setsockopt(self->getfd(
self), IPPROTO_IP, IP_MULTICAST_TTL, (
char *)&ttl,
sizeof(ttl) == 0);
258 struct sockaddr_in6 saddr;
260 g_return_val_if_fail(NULL !=
self, FALSE);
261 g_return_val_if_fail(NULL != self->giosock, FALSE);
262 sockfd =
self->getfd(
self);
265 g_warning(
"%s: Attempt to bind to multicast address.",
__FUNCTION__);
268 memset(&saddr, 0x00,
sizeof(saddr));
269 saddr.sin6_family = AF_INET6;
270 saddr.sin6_port = src->
port(src);
274 rc = bind(sockfd, (
struct sockaddr*)&saddr,
sizeof(saddr));
275 if (rc != 0 && !silent) {
276 g_warning(
"%s: Cannot bind to address [%s (errno:%d)]"
285 gint sockfd =
self->getfd(
self);
286 struct sockaddr_in6 saddr;
287 socklen_t saddrlen =
sizeof(saddr);
288 socklen_t retsize = saddrlen;
291 if (getsockname(sockfd, (
struct sockaddr*)&saddr, &retsize) < 0) {
292 g_warning(
"%s: Cannot retrieve bound address [%s]",
__FUNCTION__, g_strerror(errno));
295 if (retsize != saddrlen) {
296 g_warning(
"%s: Truncated getsockname() return [%d/%d bytes]",
__FUNCTION__, retsize, saddrlen);
309 g_io_channel_shutdown(self->giosock, TRUE, NULL);
310 g_io_channel_unref(self->giosock);
311 self->giosock = NULL;
313 if (self->_signframe) {
316 if (self->_cryptframe) {
317 UNREF(self->_cryptframe);
319 if (self->_compressframe) {
320 UNREF(self->_compressframe);
322 if (self->_decoder) {
323 UNREF(self->_decoder);
328 g_hash_table_destroy(self->aliases);
329 self->aliases = NULL;
338 return self->_maxpktsize;
346 self->_maxpktsize = maxpktsize;
347 return self->getmaxpktsize(
self);
352 return self->_compressframe;
357 return self->_cryptframe;
363 return self->_signframe;
376 if (objsize <
sizeof(
NetIO)) {
377 objsize =
sizeof(
NetIO);
410 g_return_val_if_fail(f != NULL, NULL);
430 gconstpointer packet,
431 gconstpointer pktend,
434 struct sockaddr_in6 v6addr = destaddr->
ipv6sockaddr(destaddr);
435 gssize length = (
const guint8*)pktend - (
const guint8*)packet;
438 g_return_if_fail(length > 0);
440 if (self->_shouldlosepkts) {
441 if (g_random_double() < self->_xmitloss) {
442 g_message(
"%s.%d: Threw away %"G_GSSIZE_FORMAT
" byte output packet"
448 rc = sendto(self->getfd(
self), packet, (size_t)length, flags, (
const struct sockaddr*)&v6addr,
sizeof(v6addr));
449 DEBUGMSG3(
"%s.%d: sendto(%d, %ld, [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x], port=%d) returned %ld"
450 ,
__FUNCTION__, __LINE__, self->getfd(
self), (long)length
451 , ntohs(v6addr.sin6_addr.s6_addr16[0])
452 , ntohs(v6addr.sin6_addr.s6_addr16[1])
453 , ntohs(v6addr.sin6_addr.s6_addr16[2])
454 , ntohs(v6addr.sin6_addr.s6_addr16[3])
455 , ntohs(v6addr.sin6_addr.s6_addr16[4])
456 , ntohs(v6addr.sin6_addr.s6_addr16[5])
457 , ntohs(v6addr.sin6_addr.s6_addr16[6])
458 , ntohs(v6addr.sin6_addr.s6_addr16[7])
459 , ntohs(v6addr.sin6_port)
461 self->stats.sendcalls ++;
462 self->stats.pktswritten ++;
466 "%s: sendto returned %"G_GSSIZE_FORMAT
" vs %"G_GSSIZE_FORMAT
" with errno %s"
468 g_warning(
"%s: destaddr:[%s] ",
__FUNCTION__, tostring);
469 g_free(tostring); tostring = NULL;
471 g_return_if_fail(rc == length);
484 g_return_if_fail(
self != NULL);
485 g_return_if_fail(framesets != NULL);
486 g_return_if_fail(destaddr != NULL);
487 g_return_if_fail(self->_signframe != NULL);
492 for (curfsl=framesets; curfsl != NULL; curfsl=curfsl->next) {
494 SignFrame* signframe =
self->signframe(
self);
495 Frame* cryptframe =
self->cryptframe(
self);
496 Frame* compressframe =
self->compressframe(
self);
505 self->stats.fswritten++;
514 SignFrame* signframe =
self->signframe(
self);
515 Frame* cryptframe =
self->cryptframe(
self);
516 Frame* compressframe =
self->compressframe(
self);
517 g_return_if_fail(
self != NULL);
518 g_return_if_fail(self->_signframe != NULL);
519 g_return_if_fail(frameset != NULL);
520 g_return_if_fail(destaddr != NULL);
530 , (
long)(((guint8*)frameset->
pktend-(guint8*)frameset->
packet)));
546 struct sockaddr_in6* srcaddr,
551 # define __FUNCTION__ "_netio_recvapacket"
559 *addrlen =
sizeof(*srcaddr);
560 memset(srcaddr, 0,
sizeof(*srcaddr));
561 msglen = recvfrom(self->getfd(
self), dummy, 1, MSG_DONTWAIT|MSG_PEEK|MSG_TRUNC,
562 (
struct sockaddr*)srcaddr, addrlen);
563 self->stats.recvcalls ++;
565 if (errno != EAGAIN) {
566 g_warning(
"recvfrom(%d, ... MSG_PEEK) failed: %s (in %s:%s:%d)",
567 self->getfd(
self), g_strerror(errno), __FILE__,
__FUNCTION__, __LINE__);
572 g_warning(
"recvfrom(%d, ... MSG_PEEK) returned zero: %s (in %s:%s:%d)"
573 , self->getfd(
self), g_strerror(errno), __FILE__,
__FUNCTION__, __LINE__);
581 *addrlen =
sizeof(*srcaddr);
582 msglen2 = recvfrom(self->getfd(
self), msgbuf, msglen, MSG_DONTWAIT|MSG_TRUNC,
583 (
struct sockaddr *)srcaddr, addrlen);
584 self->stats.recvcalls ++;
588 g_warning(
"recvfrom(%d, ... MSG_DONTWAIT) failed: %s (in %s:%s:%d)"
589 , self->getfd(
self), g_strerror(errno), __FILE__,
__FUNCTION__, __LINE__);
590 FREE(msgbuf); msgbuf = NULL;
594 if (msglen2 != msglen) {
595 g_warning(
"recvfrom(%d, ... MSG_DONTWAIT) returned %"G_GSSIZE_FORMAT
" instead of %"G_GSSIZE_FORMAT
" (in %s:%s:%d)"
596 , self->getfd(
self), msglen2, msglen, __FILE__,
__FUNCTION__ , __LINE__);
597 FREE(msgbuf); msgbuf = NULL;
603 #define __u6_addr8 Byte
606 if (memcmp(srcaddr->sin6_addr.__in6_u.__u6_addr8, v4any,
sizeof(v4any)) == 0) {
610 memcpy(srcaddr->sin6_addr.__in6_u.__u6_addr8, localhost,
sizeof(localhost));
614 *pktend = (
void*) (msgbuf + msglen);
616 if (self->_shouldlosepkts) {
617 if (g_random_double() < self->_rcvloss) {
618 g_message(
"%s: Threw away %"G_GSSIZE_FORMAT
" byte input packet"
624 self->stats.pktsread ++;
637 struct sockaddr_in6 srcaddr;
643 ret =
self->_decoder->pktdata_to_framesetlist(self->_decoder, pkt, pktend);
648 if (NULL != (aliasaddr = g_hash_table_lookup(self->aliases, *src))) {
650 aliasaddr->
toIPv6(aliasaddr);
652 aliasaddr->
_addrport = (*src)->_addrport;
657 g_warning(
"Received a %lu byte packet that didn't make any FrameSets"
658 , (
unsigned long)((guint8*)pktend-(guint8*)pkt));
659 FREE(ret); ret = NULL;
664 self->stats.fsreads += g_slist_length(ret);
672 self->_rcvloss = rcvloss;
673 self->_xmitloss = xmitloss;
680 self->_shouldlosepkts = enable;
696 static gboolean computed_yet = FALSE;
697 static gboolean retval = FALSE;
701 struct protoent*proto;
706 proto = getprotobyname(
"ipv6");
707 #ifdef HAVE_ENDPROTOENT
710 g_return_val_if_fail(proto != NULL, FALSE);
712 sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
713 g_return_val_if_fail(sockfd >= 0, FALSE);
715 optlen =
sizeof(retval);
717 if (getsockopt(sockfd, proto->p_proto, IPV6_V6ONLY, (
char *)&optval, &optlen) < 0) {
718 g_warning(
"%s.%d: getsockopt failed: %s", __FUNCTION__, __LINE__
719 , g_strerror(errno));
723 if (optlen !=
sizeof(retval)) {
725 g_warning(
"%s.%d: getsockopt returned incorrect optlen: %d vs %zd"
726 , __FUNCTION__, __LINE__, optlen,
sizeof(retval));
735 if (setsockopt(sockfd, proto->p_proto, IPV6_V6ONLY, (
char *)&optval, optlen) < 0) {
757 (void)
self; (void)dest; (void)queueid; (void)frameset;
764 (void)
self; (void)dest; (void)queueid; (void)fslist;
771 (void)
self; (void)dest; (void)frameset;
772 g_warning(
"%s.%d: Object does not support ACKing of messages",
__FUNCTION__, __LINE__);
784 (void)
self; (void)destaddr; (void)qid;
801 DUMP3(
"Aliasing from this address", &fromaddr->
baseclass,
" to the next address");
802 DUMP3(
"Aliasing to this address", &toaddr->
baseclass,
" from the previous address");
805 g_hash_table_insert(self->aliases, fromaddr, toaddr);