More context, in the form of self-promotion:
https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html

-rob


On Wed, Mar 11, 2020 at 9:42 PM Tom Parkin <tom.par...@gmail.com> wrote:

> On Tue, 10 Mar 2020 at 23:14, Ian Lance Taylor <i...@golang.org> wrote:
>
>> On Tue, Mar 10, 2020 at 4:03 PM Tom Parkin <tom.par...@gmail.com> wrote:
>> >
>> > I'm working on adding a new Linux socket type (L2TPIP) to the unix
>> package, and I noticed some code in there that appears on the face of it to
>> be assuming the endianess of the host.  The #networking channel on the
>> Gophers slack suggested I raise the question here.
>> >
>> > The code I am struggling with is in this file:
>> >
>> > https://github.com/golang/sys/blob/master/unix/syscall_linux.go
>> >
>> > So far as I can make out, this code implements a variety of system
>> calls for Linux generally, irrespective of GOARCH.
>> >
>> > In this file, there is a function anyToSockaddr which serves to convert
>> struct sockaddr from system calls such as getsockname(2) and accept4(2)
>> into Go representations of the various sockaddr types, for example
>> unix.SockaddrUnix and unix.SockaddrInet4.  The function anyToSockaddr
>> switches on the address family in the struct sockaddr, and then converts
>> based on that.
>> >
>> > I noticed for the AF_INET case in the switch statement of anyToSockaddr
>> that the struct sockaddr_in sin_port field is being unconditionally
>> byte-swapped during conversion:
>> >
>> >             pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
>> >             sa := new(SockaddrInet4)
>> >             p := (*[2]byte)(unsafe.Pointer(&pp.Port))
>> >             sa.Port = int(p[0])<<8 + int(p[1])
>> >             for i := 0; i < len(sa.Addr); i++ {
>> >                 sa.Addr[i] = pp.Addr[i]
>> >             }
>> >             return sa, nil
>> >
>> > (where 'rsa' is a pointer to a RawSockaddrAny).
>> >
>> > Now, ip(7) states of the struct sockaddr_in structure:
>> >
>> >   "Note that the address and the port are always stored in network byte
>> order.  In particular, this means that you need to call htons(3) on the
>> number that is assigned to a port."
>> >
>> > So the byte swapping that anyToSockaddr is doing makes sense, but only
>> if the host is a little-endian machine.  It seems as though this code would
>> do the wrong thing on a big-endian machine.
>> >
>> > Can anyone suggest what I'm missing here?  Is this code really assuming
>> that the host is a little-endian machine?
>>
>> This does not look like byte swapping to me.  Here pp.Port should be
>> in network byte order.  To set sa.Port we read the first byte of
>> pp.Port, left shift by 8, then or in the second byte of pp.Port.  That
>> is, we interpret pp.Port as a two-byte big-endian number, and compute
>> the value as a 16-bit integer.  That will work regardless of the
>> endianness of the host.
>>
>
> Thanks Ian for your answer.
>
> It took me a little bit of thinking to get there :-( but I see what you're
> saying now.
>
> For anyone else playing along at home who may be struggling like I was...
>
> By treating the uint16 pp.Port value as an array of bytes, the code can
> access the bytes in network byte order, since that's how byte arrays are
> laid out in memory (e.g. if &p[0] is address A, &p[1] is A+1, etc).
>
> The left shift and addition effectively convert to host byte order, since
> that's how uint16 value will be stored in memory.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CACzvQmaCcqfuZNyX43-%2Bb51z6bK8LLMrc7VxtLCMctBSg_fkJg%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CACzvQmaCcqfuZNyX43-%2Bb51z6bK8LLMrc7VxtLCMctBSg_fkJg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOXNBZRq0H8Mfyi6WyHdawKZvo4UN49VOYF5UrtybkTj079RCA%40mail.gmail.com.

Reply via email to