Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ping6 implementation

215 views
Skip to first unread message

and Windows APIs@discussions.microsoft.com IPv6 and Windows APIs

unread,
Apr 25, 2006, 12:06:04 AM4/25/06
to
I'm trying to implement a ping6 in MS WindowsXP sp2. Basically, it's a raw
socket network program. But problem is base on RFC3542 ("Advanced Sockets
Application Program Interface (API) for IPv6"), if I create a raw ipv6 socket
with protocol set to IPPROTO_ICMPV6, it's the kernel not me to set the icmpv6
checksum byte, but in fact it doesn't work. I refer to one of the working
ping.c program in MS platform. It seems in Microsoft platform, the programmer
have to calculate the checksum for ICMP. But in ICMPV6 case, the checksum
calculated by source address too, which cann't obtain before it comes to the
IP stack and routes to figure out which interface to use. So I cann't
calcultate the checksum as the old ping.c does.

I even have tried setsockopt IPV6_CHECKSUM, but it still doesn't work.

So how to solve this problem? Microsoft has api to calculate IPv6 Checksum
or not? I need a ping6 whith flood options in MS windows platform.

Remi Denis-Courmont

unread,
Apr 25, 2006, 5:00:00 AM4/25/06
to
Le Mardi 25 Avril 2006 06:06, IPv6 and Windows APIs a écrit :

> I'm trying to implement a ping6 in MS WindowsXP sp2. Basically, it's a raw
> socket network program. But problem is base on RFC3542 ("Advanced Sockets
> Application Program Interface (API) for IPv6"), if I create a raw ipv6
> socket with protocol set to IPPROTO_ICMPV6, it's the kernel not me to set
> the icmpv6 checksum byte, but in fact it doesn't work.

The kernel is not supposed to set the checksum unless you enable the
IPV6_CHECKSUM option.

> I refer to one of the working ping.c program in MS platform.
> It seems in Microsoft platform, the programmer have to calculate the
> checksum for ICMP. But in ICMPV6 case, the checksum calculated by source
> address too, which cann't obtain before it comes to the IP stack and
> routes to figure out which interface to use.

Yeah, the checksum depends on the source, destination, payload length and
next header. The last 3 fields are known. The first one could be
guessed/forced while binding to a specific local address via bind().

One very portable way to achieve this properly consists of allocating a
standard UDP socket, and connect()ing it to the wanted destination (this is
non-blocking, contrary to TCP connect()). Then you can get a suitable
source address via getsockname() upon the UDP socket, and you can bind the
ICMPv6 raw socket to the same socket address (don't forget to clear the
sin6_port field). That should work fine and in a very portable fashion,
unless the IPv6 routing setup changed in between the connect() and bind()
calls, which is very unlikely.

> I even have tried setsockopt IPV6_CHECKSUM, but it still doesn't work.

How did you check that it doesn't work? Running a packet sniffer on the
emitting host might show incorrect checksums even if they are actually
correct on the wire. Which value did you pass to IPV6_CHECKSUM (it should
be 2 for ICMPv6)?

I'm not saying you did it wrong - I've never actually tried.

--
Rémi Denis-Courmont
http://www.simphalempin.com/home/

Remi Denis-Courmont

unread,
Apr 25, 2006, 5:32:11 AM4/25/06
to
Le Mardi 25 Avril 2006 11:00, Remi Denis-Courmont a écrit :

> Yeah, the checksum depends on the source, destination, payload length and
> next header. The last 3 fields are known. The first one could be
> guessed/forced while binding to a specific local address via bind().

If you don't intend to received any packet that does not come from the host
you're pinging, you can simply connect() the ICMPv6 socket first, and then
call getsockname() on it to find out your source IPv6 address. That's
cleaner and more straight-forward than the UDP thing I suggested earlier.

IPv6 and Windows APIs

unread,
Apr 25, 2006, 7:31:02 PM4/25/06
to
"Remi Denis-Courmont" wrote:

> Le Mardi 25 Avril 2006 06:06, IPv6 and Windows APIs a écrit :
>
> > I'm trying to implement a ping6 in MS WindowsXP sp2. Basically, it's a raw
> > socket network program. But problem is base on RFC3542 ("Advanced Sockets
> > Application Program Interface (API) for IPv6"), if I create a raw ipv6
> > socket with protocol set to IPPROTO_ICMPV6, it's the kernel not me to set
> > the icmpv6 checksum byte, but in fact it doesn't work.
>
> The kernel is not supposed to set the checksum unless you enable the
> IPV6_CHECKSUM option.

No, in section 3.1 of RFC3542, it says
" The kernel will calculate and insert the ICMPv6 checksum for ICMPv6
raw sockets, since this checksum is mandatory."

Actually I have already tried that in Linux and NetBSD, it works fine and
also I found ICMPv6 checksum addition codes in Linux kernel.

>
> > I refer to one of the working ping.c program in MS platform.
> > It seems in Microsoft platform, the programmer have to calculate the
> > checksum for ICMP. But in ICMPV6 case, the checksum calculated by source
> > address too, which cann't obtain before it comes to the IP stack and
> > routes to figure out which interface to use.
>
> Yeah, the checksum depends on the source, destination, payload length and
> next header. The last 3 fields are known. The first one could be
> guessed/forced while binding to a specific local address via bind().

I don't want to do any modification to the ping6 command line. I want to get
that source address automatically.



>
> One very portable way to achieve this properly consists of allocating a
> standard UDP socket, and connect()ing it to the wanted destination (this is
> non-blocking, contrary to TCP connect()). Then you can get a suitable
> source address via getsockname() upon the UDP socket, and you can bind the
> ICMPv6 raw socket to the same socket address (don't forget to clear the
> sin6_port field). That should work fine and in a very portable fashion,
> unless the IPv6 routing setup changed in between the connect() and bind()
> calls, which is very unlikely.
>
> > I even have tried setsockopt IPV6_CHECKSUM, but it still doesn't work.
>
> How did you check that it doesn't work? Running a packet sniffer on the
> emitting host might show incorrect checksums even if they are actually
> correct on the wire. Which value did you pass to IPV6_CHECKSUM (it should
> be 2 for ICMPv6)?

int offset = 2;
if (setsockopt(s, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)) <
0) {
perror("ping6, checksum");
}

the output is
"ping6, checksum: Protocol not available"

It seems like IPPROTO_IPV6 setsockopt is not supported.

IPv6 and Windows APIs

unread,
Apr 25, 2006, 7:34:03 PM4/25/06
to
Great hint. I'll use this connect() and getsockname() method. Thanks Remi!

Blyth@discussions.microsoft.com Mark Blyth

unread,
May 22, 2008, 8:30:01 AM5/22/08
to
Am I right in assuming Microsoft are not going to fix this lack of
functionallity in the setsockopt function?

@discussions.microsoft.com Bharath

unread,
May 6, 2010, 10:04:01 AM5/6/10
to
Were u successful in the end?
What approach did u take to resolve this
We are having the same issue.

"IPv6 and Windows APIs" wrote:

0 new messages