--- openobex-1.3/lib/inobex.c 2006-02-12 10:51:14.000000000 +0100 +++ openobex-1.3mzk/lib/inobex.c 2007-08-28 11:27:12.000000000 +0200 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sat Apr 17 16:50:35 1999 - * CVS ID: $Id: inobex.c,v 1.16 2006/02/12 09:51:14 holtmann Exp $ + * CVS ID: $Id: inobex.c 297 2007-01-25 00:23:37Z holtmann $ * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. * @@ -35,19 +35,51 @@ #include #ifdef _WIN32 -#include +#include +#include #else #include #include #include #include +#include #endif /*_WIN32*/ #include "obex_main.h" #define OBEX_PORT 650 +static void map_ip4to6(struct sockaddr_in *in, struct sockaddr_in6 *out) +{ + out->sin6_family = AF_INET6; + if (in->sin_port == 0) + out->sin6_port = htons(OBEX_PORT); + else + out->sin6_port = in->sin_port; + out->sin6_flowinfo = 0; + + /* default, matches IN6ADDR_ANY */ + memset(out->sin6_addr.s6_addr, 0, sizeof(out->sin6_addr.s6_addr)); + switch (in->sin_addr.s_addr) { + case INADDR_ANY: + /* does not work, so use IN6ADDR_ANY + * which includes INADDR_ANY + */ + break; + default: + /* map the IPv4 address to [::FFFF:] + * see RFC2373 and RFC2553 for details + */ + out->sin6_addr.s6_addr16[10/2] = 0xFFFF; + out->sin6_addr.s6_addr[12] = (in->sin_addr.s_addr >> 0) & 0xFF; + out->sin6_addr.s6_addr[13] = (in->sin_addr.s_addr >> 8) & 0xFF; + out->sin6_addr.s6_addr[14] = (in->sin_addr.s_addr >> 16) & 0xFF; + out->sin6_addr.s6_addr[15] = (in->sin_addr.s_addr >> 24) & 0xFF; + break; + } +} + /* * Function inobex_prepare_connect (self, service) * @@ -56,10 +88,30 @@ */ void inobex_prepare_connect(obex_t *self, struct sockaddr *saddr, int addrlen) { - memcpy(&self->trans.peer, saddr, addrlen); - /* Override to be safe... */ - self->trans.peer.inet.sin_family = AF_INET; - self->trans.peer.inet.sin_port = htons(OBEX_PORT); + struct sockaddr_in6 addr = { + .sin6_family = AF_INET6, + .sin6_port = htons(OBEX_PORT), +#ifdef _WIN32 + .sin6_addr.s6_addr = IN6ADDR_LOOPBACK_INIT, +#else + .sin6_addr = IN6ADDR_LOOPBACK_INIT, +#endif + .sin6_flowinfo = 0 + }; + if (saddr == NULL) + saddr = (struct sockaddr*)(&addr); + else + switch (saddr->sa_family){ + case AF_INET6: + break; + case AF_INET: + map_ip4to6((struct sockaddr_in*)saddr,&addr); + /* no break */ + default: + saddr = (struct sockaddr*)(&addr); + break; + } + memcpy(&self->trans.peer.inet6, saddr, sizeof(self->trans.self.inet6)); } /* @@ -68,12 +120,33 @@ void inobex_prepare_connect(obex_t *self * Prepare for INET-listen * */ -void inobex_prepare_listen(obex_t *self) +void inobex_prepare_listen(obex_t *self, struct sockaddr *saddr, int addrlen) { + struct sockaddr_in6 addr = { + .sin6_family = AF_INET6, + .sin6_port = htons(OBEX_PORT), +#ifdef _WIN32 + .sin6_addr.s6_addr = IN6ADDR_ANY_INIT, +#else + .sin6_addr = IN6ADDR_ANY_INIT, +#endif + .sin6_flowinfo = 0 + }; /* Bind local service */ - self->trans.self.inet.sin_family = AF_INET; - self->trans.self.inet.sin_port = htons(OBEX_PORT); - self->trans.self.inet.sin_addr.s_addr = INADDR_ANY; + if (saddr == NULL) + saddr = (struct sockaddr *) &addr; + else + switch (saddr->sa_family) { + case AF_INET6: + break; + case AF_INET: + map_ip4to6((struct sockaddr_in *) saddr, &addr); + /* no break */ + default: + saddr = (struct sockaddr *) &addr; + break; + } + memcpy(&self->trans.self.inet6, saddr, sizeof(self->trans.self.inet6)); } /* @@ -86,7 +159,7 @@ int inobex_listen(obex_t *self) { DEBUG(4, "\n"); - self->serverfd = obex_create_socket(self, AF_INET); + self->serverfd = obex_create_socket(self, AF_INET6); if(self->serverfd < 0) { DEBUG(0, "Cannot create server-socket\n"); return -1; @@ -94,9 +167,8 @@ int inobex_listen(obex_t *self) //printf("TCP/IP listen %d %X\n", self->trans.self.inet.sin_port, // self->trans.self.inet.sin_addr.s_addr); - if (bind(self->serverfd, (struct sockaddr*) &self->trans.self.inet, - sizeof(struct sockaddr_in))) - { + if (bind(self->serverfd, (struct sockaddr *) &self->trans.self.inet6, + sizeof(struct sockaddr_in6))) { DEBUG(0, "bind() Failed\n"); return -1; } @@ -120,10 +192,11 @@ int inobex_listen(obex_t *self) */ int inobex_accept(obex_t *self) { - socklen_t addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in6); - self->fd = accept(self->serverfd, (struct sockaddr *) - &self->trans.peer.inet, &addrlen); + self->fd = accept(self->serverfd, + (struct sockaddr *) &self->trans.peer.inet6, + &addrlen); if(self->fd < 0) return -1; @@ -142,26 +215,30 @@ int inobex_accept(obex_t *self) */ int inobex_connect_request(obex_t *self) { - unsigned char *addr; + char addr[INET6_ADDRSTRLEN]; int ret; - self->fd = obex_create_socket(self, AF_INET); + self->fd = obex_create_socket(self, AF_INET6); if(self->fd < 0) return -1; /* Set these just in case */ - self->trans.peer.inet.sin_family = AF_INET; - if (self->trans.peer.inet.sin_port == 0) - self->trans.peer.inet.sin_port = htons(OBEX_PORT); - - addr = (unsigned char *) &self->trans.peer.inet.sin_addr.s_addr; - - DEBUG(2, "peer addr = %d.%d.%d.%d\n", - addr[0], addr[1], addr[2], addr[3]); + if (self->trans.peer.inet6.sin6_port == 0) + self->trans.peer.inet6.sin6_port = htons(OBEX_PORT); +#ifndef _WIN32 + if (!inet_ntop(AF_INET6,&self->trans.peer.inet6.sin6_addr, + addr,sizeof(addr))) { + DEBUG(4, "Adress problem\n"); + obex_delete_socket(self, self->fd); + self->fd = -1; + return -1; + } + DEBUG(2, "peer addr = [%s]:%u\n",addr,ntohs(self->trans.peer.inet6.sin6_port)); +#endif - ret = connect(self->fd, (struct sockaddr*) &self->trans.peer.inet, - sizeof(struct sockaddr_in)); + ret = connect(self->fd, (struct sockaddr *) &self->trans.peer.inet6, + sizeof(struct sockaddr_in6)); if (ret < 0) { DEBUG(4, "Connect failed\n"); obex_delete_socket(self, self->fd); --- openobex-1.3/lib/inobex.h 2002-10-28 22:51:18.000000000 +0100 +++ openobex-1.3mzk/lib/inobex.h 2007-08-24 16:33:00.000000000 +0200 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Mon Apr 26 13:55:27 1999 - * CVS ID: $Id: inobex.h,v 1.7 2002/10/28 21:51:18 holtmann Exp $ + * CVS ID: $Id: inobex.h 297 2007-01-25 00:23:37Z holtmann $ * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. * @@ -31,7 +31,7 @@ #define INOBEX_H void inobex_prepare_connect(obex_t *self, struct sockaddr *saddr, int addrlen); -void inobex_prepare_listen(obex_t *self); +void inobex_prepare_listen(obex_t *self, struct sockaddr *saddr, int addrlen); int inobex_listen(obex_t *self); int inobex_accept(obex_t *self); int inobex_connect_request(obex_t *self); --- openobex-1.3/lib/obex.c 2006-05-25 20:09:41.000000000 +0200 +++ openobex-1.3mzk/lib/obex.c 2007-08-24 16:37:10.000000000 +0200 @@ -933,7 +933,7 @@ int InOBEX_ServerRegister(obex_t *self) obex_return_val_if_fail(self != NULL, -1); - inobex_prepare_listen(self); + inobex_prepare_listen(self, NULL, 0); return obex_transport_listen(self); } --- openobex-1.3/lib/obex_transport.c 2006-05-04 13:24:21.000000000 +0200 +++ openobex-1.3mzk/lib/obex_transport.c 2007-08-27 15:57:22.000000000 +0200 @@ -191,6 +191,13 @@ int obex_transport_connect_request(obex_ break; #endif /*HAVE_IRDA*/ case OBEX_TRANS_INET: + /* needed as compat for apps that call OBEX_TransportConnect + * instead of InOBEX_TransportConnect (e.g. obexftp) + */ + if (self->trans.peer.inet6.sin6_family == AF_INET) + inobex_prepare_connect(self, + (struct sockaddr*) &self->trans.peer.inet6, + sizeof(self->trans.peer.inet6)); ret = inobex_connect_request(self); break; case OBEX_TRANS_CUSTOM: --- openobex-1.3/lib/obex_transport.h 2006-05-04 13:24:21.000000000 +0200 +++ openobex-1.3mzk/lib/obex_transport.h 2007-08-27 16:06:51.000000000 +0200 @@ -53,7 +53,7 @@ typedef union { #ifdef HAVE_IRDA struct sockaddr_irda irda; #endif /*HAVE_IRDA*/ - struct sockaddr_in inet; + struct sockaddr_in6 inet6; #ifdef HAVE_BLUETOOTH struct sockaddr_rc rfcomm; #endif /*HAVE_BLUETOOTH*/