Witam.
Piszę prosty serwer TCP dla IPv6. kod wygląda tak:
int rc;
struct sockaddr_in6 serverSa;
int on = 1;
int family;
socklen_t serverSaSize;
int c;
char buf[INET6_ADDRSTRLEN];
int s = socket(PF_INET6,SOCK_STREAM,0);
if (s < 0)
{
fprintf(stderr, "IPv6 not active, falling back to IPv4...\n");
}
family = AF_INET6;
printf("socket descriptor is: %d ", s);
//setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
rc = setsockopt(s,IPPROTO_IPV6,IPV6_RECVPKTINFO,&on,sizeof(on));
int result = 8;
/* initialize the server's sockaddr */
memset(&serverSa,0,sizeof(serverSa));
serverSa.sin6_family = AF_INET6;
// serverSa.sin6_addr = "fe80::800:27ff:fe00:0";
serverSa.sin6_port = htons(serverPort);
tmp = (char*)(&serverSa.sin6_addr);
result = inet_pton6(addr, tmp);
printf ("\n result: %d \n", result);
serverSaSize = sizeof(struct sockaddr_in6);
rc = bind(s,(struct sockaddr *)&serverSa,serverSaSize);
if (rc < 0)
{
printf("\n TCP bind failed\n ");
exit(1);
} else {
printf("\n TCP Binding OK.\n " );
}
Kod niestety nie bind-uje mi sokcet'u. Wywala bład: "Unable to bind socket: invalid argument"
Po zakomentowaniu tej linijki:
result = inet_pton6(addr, tmp);
Jest już ok. Wygląda na to, że ta funkcja psuje coś strukturę adresową. inet_pton6 wygląda tak:
int inet_pton6(const char *src, char * dst)
{
static char xdigits[] = "0123456789abcdef";
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
const char *curtok;
int ch, saw_xdigit;
u_int val;
memset(tmp, '\0', NS_IN6ADDRSZ);
tp = tmp;
endp = tp + NS_IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = tolower (*src++)) != '\0') {
char * pch;
pch = strchr(xdigits, ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
} else if (*src == '\0') {
return (0);
}
if (tp + NS_INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, (char*)tp) > 0) {
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + NS_INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
if (tp == endp)
return (0);
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
memcpy(dst, tmp, NS_IN6ADDRSZ);
return (1);
}
Czy ktoś ma jakiś pomysł, dlaczego to może nie działać ?