Re: ping6 implementation
Am I right in assuming Microsoft are not going to fix this lack of
functionallity in the setsockopt function?
"IPv6 and Windows APIs" wrote:
> "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.
>
> >
> > I'm not saying you did it wrong - I've never actually tried.
> >
> > --
> > Rémi Denis-Courmont
> > http://www.simphalempin.com/home/
> >
date: Thu, 22 May 2008 05:30:01 -0700
author: Mark Blyth Mark