Subject: port-i386/37533: Client can not connect to any address with ipv6 address
To: None <port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <metallica2507@yahoo.com>
List: netbsd-bugs
Date: 12/13/2007 13:40:00
>Number:         37533
>Category:       port-i386
>Synopsis:       Client can not connect to any address with ipv6 address
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 13 13:40:00 +0000 2007
>Originator:     Nam Phan
>Release:        NetBSD netbsd 3.1.1 NetBSD 3.1.1
>Organization:
Global Cybersoft Ltd
>Environment:
NetBSD netbsd 3.1.1 NetBSD 3.1.1 (GENERIC) #0: Sun Jul  1 08:48:35 PDT 2007  builds@wb42:/home/builds/ab/netbsd-3-1-1-RELEASE/i386/200707010939Z-obj/home/builds/ab/netbsd-3-1-1-RELEASE/src/sys/arch/i386/compile/GENERIC i386

>Description:
Hi staff

I have an issue which I think this error is due to OS NetBSD.
I have written a small application to create socket and send/receive data package between server and client. In this application, I use IPv6 address to create socket. 
I have run server and client in two consoles on my computer which has OS NetBSD, I saw the error like that "Network is unreachable".
I also run this application on another computer that has OS Linux, the application can send and receive data successfully.

Maybe, I configured wrongly on the computer or OS NetBSD doesn't support.
Please help me fix this issue.
And here is my application

/*
 *  SERVER
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>

#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
void sigchld_handler(int s)
{
    while(waitpid(-1, NULL, WNOHANG) > 0);
}
int main(void)
{
    int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
    struct sockaddr_in6 my_addr; // my address information
    struct sockaddr_in6 *my_addrP = (struct sockaddr_in6*)&my_addr;
    struct sockaddr_in6 their_addr; // connector’s address information
    socklen_t sin_size;
    char caddr[16];
    int i=0;
    struct sigaction sa;
    int yes=1;
    int len = 28;

    if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }
    
    if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
        perror("setsockopt");
        exit(1);
    }
    memset(&caddr, 0, 16);
    for(i=0; i< 16; i++)
        caddr[i] = 0;

    my_addrP->sin6_family = AF_INET6; // host byte order
    my_addrP->sin6_port = htons(MYPORT); // short, network byte order
    memcpy((void *)&(my_addrP->sin6_addr), caddr, 16 );
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)) == -1) {
        perror("bind");
        exit(1);
    }
    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }
    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
    perror("sigaction");
    exit(1);
    }
    while(1) { // main accept() loop
        sin_size = sizeof(struct sockaddr_in6);
        if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
            perror("accept");
            continue;
        }
        memcpy(caddr, (void *)&(their_addr.sin6_addr), 16 );
        printf("server: got connection from: ");
        for (i=0;i < 16; i++)
            printf(" %d", caddr[i]);
            printf("\n");
        if (!fork()) { // this is the child process
            close(sockfd); // child doesn’t need the listener
            if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
            perror("send");
            close(new_fd);
            exit(0);
        }
        close(new_fd); // parent doesn’t need this
    }
    return 0;
}


/*
 * CLIENT
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 3490 // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once
int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
char caddr[16];
int i=0;
    if (argc != 2) {
        fprintf(stderr,"usage: client hostname\n");
        exit(1);
    }
    if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
        herror("gethostbyname");
        exit(1);
    }
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    //their_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    their_addr.sin_family = AF_INET; // host byte order
    their_addr.sin_port = htons(PORT); // short, network byte order
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct*/
    if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr_in)) == -1) {
        perror("connect");
        exit(1);
    }
    /*if (connect(sockfd, (struct sockaddr *)&their_addr4, sizeof(struct sockaddr_in)) == -1) {
        perror("connect");
        exit(1);
    }*/


if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
    buf[numbytes] = '\0';
    printf("Received: %s",buf);
    close(sockfd);
    return 0;
}


Thanks and best regards

Nam Phan


>How-To-Repeat:
We use gcc compiler to compile application
Run them in two console
The bug always appears when client connects to server.
>Fix:
I really don't know