icmpv6(ping6)の応答を受信できない
ipv6、ipv4のpingの送受信ができる、ipv4ipv6pingexampleと言うソースをダウンロードし実行したのですが、ipv6の受信のみが出来ません。
スニファーソフトで見ると、ping6の応答は帰っているが、受信(WSARecvFrom)でタイムアウトとなる。
確認のため、icmpv6(ping6)の応答を受信する部分のみ作成してテストしても、同様になります。
受信ソケットのbindの引数のaddrinfoに原因があるのではと試しましたがうまくいきません。
アドバイスをお願いいたします。
環境
windowsXP(SP3)、VC++2008
ping先は家のルータ、DOSウィンドウからping6を入力
ipv4は受信できる。スニファーソフトで見ると、ping6の応答は帰っている。
以下は確認用のコード
#include <stdio.h>
#include "winsock2.h"
#include <ws2tcpip.h>
#include "iphdrv2.h"
#pragma comment(lib, "ws2_32.lib")
void main() {
WSADATA wsaData;
SOCKET RecvSocket;
char RecvBuf[1024];
int BufLen = 1024;
SOCKADDR_STORAGE from;
int fromsize = sizeof(from);
struct addrinfo hints, *local=NULL;
int rc;
// for ipv4
//int af = PF_INET, type = SOCK_RAW, proto = IPPROTO_ICMP;
// for ipv6
int af = PF_INET6, type = SOCK_RAW, proto = IPPROTO_ICMPV6;
// Winsock を初期化します。
WSAStartup(MAKEWORD(2,2), &wsaData);
// データ受信用のソケットを作成します。
RecvSocket = socket(af, type, proto);
// struct addrinfo { *
// int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
// int ai_family; /* PF_xxx */
// int ai_socktype; /* SOCK_xxx */
// int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
// size_t ai_addrlen; /* length of ai_addr */
// char *ai_canonname; /* canonical name for nodename */
// struct sockaddr *ai_addr; /* binary address */
// struct addrinfo *ai_next; /* next structure in linked list */
// };
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = af;
hints.ai_socktype = type;
hints.ai_protocol = proto;
//rc = getaddrinfo(addr, port, &hints, &res);
rc = getaddrinfo(NULL, "0", &hints, &local);
if (rc != 0) {
printf("getaddrinfo() failed with error code %d\n", rc);
printf("Unable to obtain the bind address! with error code %d\n", WSAGetLastError());
getchar();
return ;
}
//bind
rc = bind(RecvSocket, local->ai_addr, local->ai_addrlen);
if (rc == SOCKET_ERROR) {
fprintf(stderr, "bind() failed with error code %d\n", WSAGetLastError());
getchar();
return ;
}
// データを受信します。
printf("データの受信中……\n");
rc =recvfrom(RecvSocket,RecvBuf,BufLen,0,(SOCKADDR *)&from,&fromsize);
//rc =recv(RecvSocket,RecvBuf,BufLen, 0);
if(rc == -1){
printf("Recv failed with error code %d\n", WSAGetLastError());
}
else {
printf("受信が完了しました。%d Byte\n",rc);
}
closesocket(RecvSocket);
printf("終了します。\n");
freeaddrinfo(local);
WSACleanup();
return;
}
お礼
無念ながら、、、そのようなマヌケなオチでした。。。 素晴らしいご指摘ありがとうございます。 ちなみに$titleと$siteurlをurlencodeしない方がエラーがなく、 goo.ne.jpのみはurlencodeが必要なようでした。