From: Laurent Vivier <laur...@vivier.eu> in PACKET(7) : protocol is the IEEE 802.3 protocol number in network order. See the <linux/if_ether.h> include file for a list of allowed protocols. When protocol is set to htons(ETH_P_ALL) then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel.
Signed-off-by: Laurent Vivier <laur...@vivier.eu> --- include/exec/user/abitypes.h | 22 ++++++++++++++++++++++ linux-user/syscall.c | 8 +++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/exec/user/abitypes.h b/include/exec/user/abitypes.h index fe7f662..f4f526a 100644 --- a/include/exec/user/abitypes.h +++ b/include/exec/user/abitypes.h @@ -15,6 +15,15 @@ static inline abi_ulong tswapal(abi_ulong v) return tswap32(v); } +static inline abi_ulong abi_ntohl(abi_ulong v) +{ +#if defined(HOST_BIG_ENDIAN) + return v; +#else + return bswap_32(v); +#endif +} + #else typedef target_ulong abi_ulong; typedef target_long abi_long; @@ -32,5 +41,18 @@ static inline abi_ulong tswapal(abi_ulong v) return tswapl(v); } +static inline abi_ulong abi_ntohl(abi_ulong v) +{ +#if defined(HOST_BIG_ENDIAN) + return v; +#else +#if TARGET_LONG_SIZE == 4 + return bswap_32(v); +#else + return bswap_64(v); +#endif +#endif +} + #endif #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 000b640..29151a6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1874,7 +1874,7 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr, } /* do_socket() Must return target values and target errnos. */ -static abi_long do_socket(int domain, int type, int protocol) +static abi_long do_socket(int domain, int type, abi_ulong protocol) { #if defined(TARGET_MIPS) switch(type) { @@ -1900,6 +1900,12 @@ static abi_long do_socket(int domain, int type, int protocol) #endif if (domain == PF_NETLINK) return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */ + if (type == SOCK_PACKET) { + /* in this case, socket() needs a network endian short */ + protocol = tswapal(protocol); /* restore network endian long */ + protocol = abi_ntohl(protocol); /* a host endian long */ + protocol = htons(protocol); /* network endian short */ + } return get_errno(socket(domain, type, protocol)); } -- 1.7.10.4