IPv6 TCP socket: Network Unreachable

Hi everyone!

I'd like some help on a little issue. I'm learning to use sockets at college. I'm using the following setup: a desktop, running Windows 7 x64, running a virtual Debian Wheezy x32. It's connected through Ethernet to a router. This router is connected through Ethernet to a netbook, also running Debian Wheezy x32.

I've successfully communicated between the two Debians using IPv6 UDP sockets, using the link-local addresses. IPv4 TCP also worked, but IPv6 TCP gives me a "Network Unreachable". No packets are captured using Wireshark. I'm using code provided by my teacher, written for IPv4, modified by me to use IPv6. Remember that this modification by me worked for UDP.

Here's the code for the IPv6 TCP sockets:

client:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

int main(int argc, char *argv[]) {

	/* ESTAÇÃO REMOTA */
	char *rem_hostname;
	int rem_port;
	/* Estrutura: família + endereço IP + porta */
	struct sockaddr_in6 rem_addr;
	int rem_sockfd;
	char linha[81];

	if (argc != 3) {
		printf("Parametros:<remote_host> <remote_port> \n");
		exit(1);
	}

	/* Construção da estrutura do endereço local */
	/* Preenchendo a estrutura socket loc_addr (família, IP, porta) */
	rem_hostname = argv[1];
	rem_port = atoi(argv[2]);
	rem_addr.sin6_family = AF_INET6; /* familia do protocolo*/
    // configura endereço IP
//	rem_addr.sin6_addr.s6_addr = inet_addr(rem_hostname); /* endereco IP local */
    if (inet_pton(AF_INET6, rem_hostname, &(rem_addr.sin6_addr.s6_addr)) != 1) {
        return 0;
    };
	rem_addr.sin6_port = htons(rem_port); /* porta local  */
    // configura escopo da interface
    rem_addr.sin6_scope_id = if_nametoindex("eth0");

   	/* Cria o socket para enviar e receber datagramas */
	/* parâmetros(família, tipo, protocolo) */
	rem_sockfd = socket(AF_INET6, SOCK_STREAM, 0);

	if (rem_sockfd < 0) {
		perror("Criando stream socket");
		exit(1);
	}
	printf("> Conectando no servidor '%s:%d'\n", rem_hostname, rem_port);
	strcpy(linha,"Hello World!\0");
   	/* Estabelece uma conexão remota */
	/* parâmetros(descritor socket, estrutura do endereço remoto, comprimento do endereço) */
	if (connect(rem_sockfd, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) {
		perror("Conectando stream socket");
		exit(1);
	}
		/* parâmetros(descritor socket, endereço da memória, tamanho da memória, flag) */
		send(rem_sockfd, &linha, sizeof(linha), 0);
	/* fechamento do socket remota */
	close(rem_sockfd);
}


server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {

	/* Variaveis Locais */
	int loc_sockfd, loc_newsockfd, tamanho;
	char linha[81];
	/* Estrutura: família + endereço IP + porta */
	struct sockaddr_in6 loc_addr;

	if (argc != 2) {
		printf("Parametros: <local_port> \n");
		exit(1);
	}

   	/* Cria o socket para enviar e receber datagramas */
	/* parâmetros(família, tipo, protocolo) */
	loc_sockfd = socket(AF_INET6, SOCK_STREAM, 0);

	if (loc_sockfd < 0) {
		perror("Criando stream socket");
		exit(1);
	}

	/* Construção da estrutura do endereço local */
	/* Preenchendo a estrutura socket loc_addr (família, IP, porta) */
	loc_addr.sin6_family = AF_INET6; /* familia do protocolo */
    // configura IP local

    // ou esse
//	loc_addr.sin6_addr = in6addr_any; /* endereco IP local */

    // ou esse
    char ip[80];
    strcpy(ip, "fe80::7aac:c0ff:feff:93d7\0");
    if (inet_pton(AF_INET6, ip, &(loc_addr.sin6_addr.s6_addr)) != 1) {
        return 0;
    };

	loc_addr.sin6_port = htons(atoi(argv[1])); /* porta local  */
//	bzero(&(loc_addr.sin6_zero), 8);
    // configura escopo da interface
    loc_addr.sin6_scope_id = if_nametoindex("eth0");

   	/* Bind para o endereço local*/
	/* parâmetros(descritor socket, estrutura do endereço local, comprimento do endereço) */
	if (bind(loc_sockfd, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) {
		perror("Ligando stream socket");
		exit(1);
	}

	/* parâmetros(descritor socket,
	números de conexões em espera sem serem aceites pelo accept)*/
	listen(loc_sockfd, 5);
	printf("> aguardando conexao\n");

	tamanho = sizeof(struct sockaddr_in);
   	/* Accept permite aceitar um pedido de conexão, devolve um novo "socket" já ligado ao emissor do pedido e o "socket" original*/
	/* parâmetros(descritor socket, estrutura do endereço local, comprimento do endereço)*/
       	loc_newsockfd =	accept(loc_sockfd, (struct sockaddr *)&loc_addr, &tamanho);

		/* parâmetros(descritor socket, endereço da memória, tamanho da memória, flag) */
 		recv(loc_newsockfd, &linha, sizeof(linha), 0);
		printf("Recebi %s\n", linha);
	/* fechamento do socket local */
	close(loc_sockfd);
	close(loc_newsockfd);
}


So, why doesn't it work?

Thanks in advance.
Topic archived. No new replies allowed.