diff options
| author | dsl <dsl@NetBSD.org> | 2007-07-01 18:45:36 +0000 |
|---|---|---|
| committer | dsl <dsl@NetBSD.org> | 2007-07-01 18:45:36 +0000 |
| commit | 813e1c75844e8c6262dd2e1b1122e570af42e835 (patch) | |
| tree | 676a6263be3fc241ba5c79cbe5a254bb9175fe3c /sys/compat/linux/common/linux_socket.h | |
| parent | 6596e0c995d2e91a5158f36e3033273676e6a89e (diff) | |
Fix long-term breakage in the definition of 'control' data for linux.
cmsg->cmsg_len is 'size_t' not 'socklen_t' - so it is 8 bytes on 64bit
platforms instead of 4. There is also never padding after the header.
Redo linux sendmsg() so that it stands a chance of getting it right.
Redo linux recvmsg() so that it process control data directly from the mbuf
list. Allowing it to hack the data without using the stackgap.
Diffstat (limited to 'sys/compat/linux/common/linux_socket.h')
| -rw-r--r-- | sys/compat/linux/common/linux_socket.h | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/sys/compat/linux/common/linux_socket.h b/sys/compat/linux/common/linux_socket.h index b1f7b98823e..bdbdf7c514b 100644 --- a/sys/compat/linux/common/linux_socket.h +++ b/sys/compat/linux/common/linux_socket.h @@ -1,4 +1,4 @@ -/* $NetBSD: linux_socket.h,v 1.14 2007/03/04 06:01:24 christos Exp $ */ +/* $NetBSD: linux_socket.h,v 1.15 2007/07/01 18:45:36 dsl Exp $ */ /*- * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. @@ -154,21 +154,38 @@ /* * Linux alignment requirement for CMSG struct manipulation. - * Linux aligns on (long) boundary on all architectures. + * Linux aligns on (size_t) boundary on all architectures. + * Fortunately for linux, linux_cmsghdr is always size_t aligned ! + * since no padding is added between the header and data. + * XXX: this code isn't right for the compat32 code. */ +struct linux_cmsghdr { + size_t cmsg_len; /* NB not socklen_t */ + int cmsg_level; + int cmsg_type; + /* unsigned char __cmsg_data[0]; */ +}; + #define LINUX_CMSG_ALIGN(n) \ - (((n) + sizeof(long)-1) & ~(sizeof(long)-1)) + (((n) + sizeof(size_t)-1) & ~(sizeof(size_t)-1)) +/* Linux either uses this, or &((cmsg)->__cmsg_data) */ #define LINUX_CMSG_DATA(cmsg) \ - ((u_char *)(void *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr))) + ((u_char *)((struct linux_cmsghdr *)(cmsg) + 1)) #define LINUX_CMSG_NXTHDR(mhdr, cmsg) \ - (((char *)(cmsg) + LINUX_CMSG_ALIGN((cmsg)->cmsg_len) + \ - LINUX_CMSG_ALIGN(sizeof(struct cmsghdr)) > \ + ((((char *)(cmsg) + LINUX_CMSG_ALIGN((cmsg)->cmsg_len) + \ + sizeof(*(cmsg))) > \ (((char *)(mhdr)->msg_control) + (mhdr)->msg_controllen)) ? \ - (struct cmsghdr *)NULL : \ - (struct cmsghdr *)((char *)(cmsg) + \ + (struct linux_cmsghdr *)NULL : \ + (struct linux_cmsghdr *)((char *)(cmsg) + \ LINUX_CMSG_ALIGN((cmsg)->cmsg_len))) -#define LINUX_CMSG_ALIGNDIFF \ - (CMSG_ALIGN(sizeof(struct cmsghdr)) - LINUX_CMSG_ALIGN(sizeof(struct cmsghdr))) +/* This the number of bytes removed from each item (excl. final padding) */ +#define LINUX_CMSG_ALIGN_DELTA \ + (CMSG_ALIGN(sizeof(struct cmsghdr)) - sizeof(struct linux_cmsghdr)) + +#define LINUX_CMSG_FIRSTHDR(mhdr) \ + ((mhdr)->msg_controllen >= sizeof(struct linux_cmsghdr) ? \ + (struct linux_cmsghdr *)(mhdr)->msg_control : NULL) + /* * Machine specific definitions. |
