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.