diff options
| author | Bill Fenner <fenner@FreeBSD.org> | 2001-10-26 23:10:08 +0000 |
|---|---|---|
| committer | Bill Fenner <fenner@FreeBSD.org> | 2001-10-26 23:10:08 +0000 |
| commit | 4730796ca1fe8ad0edc89e03a54da3267e4612b9 (patch) | |
| tree | 7ca4135fcd8b2c0eed5ba3a21c5d4cb9647f75e2 /sys/compat/linux/linux_socket.c | |
| parent | 3f5f44ebe8fdf8efe22b01d4bc57a8677f1ca177 (diff) | |
Notes
Diffstat (limited to 'sys/compat/linux/linux_socket.c')
| -rw-r--r-- | sys/compat/linux/linux_socket.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index de740546ba27..c09c0bdd3f9a 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -54,6 +54,27 @@ #include <compat/linux/linux_socket.h> #include <compat/linux/linux_util.h> +/* + * FreeBSD's socket calls require the sockaddr struct length to agree + * with the address family. Linux does not, so we must force it. + */ +static int +linux_to_bsd_namelen(caddr_t name, int namelen) +{ + uint16_t family; /* XXX must match Linux sockaddr */ + + if (copyin(name, &family, sizeof(family))) + return namelen; + + switch (family) { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + } + return namelen; +} + #ifndef __alpha__ static int linux_to_bsd_domain(int domain) @@ -373,7 +394,7 @@ linux_bind(struct thread *td, struct linux_bind_args *args) bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; - bsd_args.namelen = linux_args.namelen; + bsd_args.namelen = linux_to_bsd_namelen(bsd_args.name, linux_args.namelen); return (bind(td, &bsd_args)); } @@ -407,7 +428,7 @@ linux_connect(struct thread *td, struct linux_connect_args *args) bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; - bsd_args.namelen = linux_args.namelen; + bsd_args.namelen = linux_to_bsd_namelen(bsd_args.name, linux_args.namelen); error = connect(td, &bsd_args); if (error != EISCONN) return (error); |
