/* System-specific socket constants and types. Hurd version.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If
- not, see <http://www.gnu.org/licenses/>. */
+ not, see <https://www.gnu.org/licenses/>. */
#ifndef __BITS_SOCKET_H
#define __BITS_SOCKET_H 1
#endif
#define __need_size_t
-#define __need_NULL
#include <stddef.h>
-#include <limits.h> /* XXX Is this allowed? */
-#include <bits/types.h>
+#include <bits/wordsize.h>
+#include <sys/types.h>
/* Type for length arguments in socket calls. */
#ifndef __socklen_t_defined
#define AF_APPLETALK PF_APPLETALK
#define AF_ROUTE PF_ROUTE
#define AF_LINK PF_LINK
-#define pseudo_AF_XTP PF_XTP
+#ifdef __USE_MISC
+# define pseudo_AF_XTP PF_XTP
+#endif
#define AF_COIP PF_COIP
#define AF_CNT PF_CNT
-#define pseudo_AF_RTIP PF_RTIP
+#ifdef __USE_MISC
+# define pseudo_AF_RTIP PF_RTIP
+#endif
#define AF_IPX PF_IPX
#define AF_SIP PF_SIP
-#define pseudo_AF_PIP PF_PIP
+#ifdef __USE_MISC
+# define pseudo_AF_PIP PF_PIP
+#endif
#define AF_INET6 PF_INET6
#define AF_MAX PF_MAX
/* Maximum queue length specifiable by listen. */
-#define SOMAXCONN 128 /* 5 on the origional 4.4 BSD. */
+#define SOMAXCONN 4096 /* 5 on the original 4.4 BSD. */
/* Get the definition of the macro to define the common sockaddr members. */
#include <bits/sockaddr.h>
/* Structure large enough to hold any socket address (with the historical
- exception of AF_UNIX). We reserve 128 bytes. */
-#if ULONG_MAX > 0xffffffff
+ exception of AF_UNIX). */
+#if __WORDSIZE == 64
# define __ss_aligntype __uint64_t
#else
# define __ss_aligntype __uint32_t
#endif
-#define _SS_SIZE 128
-#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
+#define _SS_PADSIZE \
+ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
struct sockaddr_storage
{
__SOCKADDR_COMMON (ss_); /* Address family, etc. */
- __ss_aligntype __ss_align; /* Force desired alignment. */
char __ss_padding[_SS_PADSIZE];
+ __ss_aligntype __ss_align; /* Force desired alignment. */
};
#define MSG_WAITALL MSG_WAITALL
MSG_DONTWAIT = 0x80, /* This message should be nonblocking. */
#define MSG_DONTWAIT MSG_DONTWAIT
- MSG_NOSIGNAL = 0x0400 /* Do not generate SIGPIPE on EPIPE. */
+ MSG_NOSIGNAL = 0x0400, /* Do not generate SIGPIPE on EPIPE. */
#define MSG_NOSIGNAL MSG_NOSIGNAL
+ MSG_CMSG_CLOEXEC = 0x40000 /* Atomically set close-on-exec flag
+ for file descriptors in SCM_RIGHTS. */
+#define MSG_CMSG_CLOEXEC MSG_CMSG_CLOEXEC
};
of cmsghdr structure. */
int cmsg_level; /* Originating protocol. */
int cmsg_type; /* Protocol specific type. */
-#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+#if __glibc_c99_flexarr_available
__extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data. */
#endif
};
/* Ancillary data object manipulation macros. */
-#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+#if __glibc_c99_flexarr_available
# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
#else
# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
#define CMSG_FIRSTHDR(mhdr) \
((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
- ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL)
+ ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
& (size_t) ~(sizeof (size_t) - 1))
+ CMSG_ALIGN (sizeof (struct cmsghdr)))
#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+/* Given a length, return the additional padding necessary such that
+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */
+#define __CMSG_PADDING(len) ((sizeof (size_t) \
+ - ((len) & (sizeof (size_t) - 1))) \
+ & (sizeof (size_t) - 1))
+
extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
struct cmsghdr *__cmsg) __THROW;
#ifdef __USE_EXTERN_INLINES
_EXTERN_INLINE struct cmsghdr *
__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
{
+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and
+ __mhdr->msg_controllen because the user is required to obtain the first
+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet
+ trust the value of __cmsg->cmsg_len and therefore do not use it in any
+ pointer arithmetic until we check its value. */
+
+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
+
+ size_t __size_needed = sizeof (struct cmsghdr)
+ + __CMSG_PADDING (__cmsg->cmsg_len);
+
+ /* The current header is malformed, too small to be a full header. */
if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
- /* The kernel header does this so there may be a reason. */
- return NULL;
+ return (struct cmsghdr *) 0;
+ /* There isn't enough space between __cmsg and the end of the buffer to
+ hold the current cmsg *and* the next one. */
+ if (((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
+ < __size_needed)
+ || ((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
+ - __size_needed)
+ < __cmsg->cmsg_len))
+
+ return (struct cmsghdr *) 0;
+
+ /* Now, we trust cmsg_len and can use it to find the next header. */
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
- + __mhdr->msg_controllen)
- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
- /* No more entries. */
- return NULL;
return __cmsg;
}
#endif /* Use `extern inline'. */
#define SCM_CREDS SCM_CREDS
};
+#ifdef __USE_MISC
/* Unfortunately, BSD practice dictates this structure be of fixed size.
If there are more than CMGROUP_MAX groups, the list is truncated.
(On GNU systems, the `cmcred_euid' field is just the first in the
int cmcred_ngroups;
__gid_t cmcred_groups[CMGROUP_MAX];
};
+#endif
/* Protocol number used to manipulate socket-level options
with `getsockopt' and `setsockopt'. */