if passed sockaddr has family AF_UNSPEC, use socket family of the socket
the sockaddr is used for this fixes bind() problem in Linux version of Theocracy, testing by Thomas Klausner
This commit is contained in:
parent
4d38f47519
commit
9cc50db4c5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: linux_socket.c,v 1.52 2004/09/05 09:38:17 jdolecek Exp $ */
|
||||
/* $NetBSD: linux_socket.c,v 1.53 2004/09/12 15:32:55 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.52 2004/09/05 09:38:17 jdolecek Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.53 2004/09/12 15:32:55 jdolecek Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_inet.h"
|
||||
|
@ -60,6 +60,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.52 2004/09/05 09:38:17 jdolecek E
|
|||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/domain.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
|
@ -114,8 +115,8 @@ int linux_to_bsd_ip_sockopt __P((int));
|
|||
int linux_to_bsd_tcp_sockopt __P((int));
|
||||
int linux_to_bsd_udp_sockopt __P((int));
|
||||
int linux_getifhwaddr __P((struct proc *, register_t *, u_int, void *));
|
||||
static int linux_sa_get __P((struct proc *, caddr_t *sgp, struct sockaddr **sap,
|
||||
const struct osockaddr *osa, int *osalen));
|
||||
static int linux_sa_get __P((struct proc *, int, caddr_t *, struct sockaddr **,
|
||||
const struct osockaddr *, int *));
|
||||
static int linux_sa_put __P((struct osockaddr *osa));
|
||||
static int linux_to_bsd_msg_flags __P((int));
|
||||
static int bsd_to_linux_msg_flags __P((int));
|
||||
|
@ -386,7 +387,9 @@ linux_sys_sendto(l, v, retval)
|
|||
int error;
|
||||
caddr_t sg = stackgap_init(p, 0);
|
||||
|
||||
if ((error = linux_sa_get(p, &sg, &sa, SCARG(uap, to), &tolen)))
|
||||
error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
|
||||
SCARG(uap, to), &tolen);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
SCARG(&bsa, to) = sa;
|
||||
|
@ -440,7 +443,7 @@ linux_sys_sendmsg(l, v, retval)
|
|||
struct sockaddr *sa;
|
||||
sg = stackgap_init(p, 0);
|
||||
|
||||
error = linux_sa_get(p, &sg, &sa,
|
||||
error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
|
||||
(struct osockaddr *) msg.msg_name, &msg.msg_namelen);
|
||||
if (error)
|
||||
goto done;
|
||||
|
@ -1322,7 +1325,8 @@ linux_sys_connect(l, v, retval)
|
|||
int namlen;
|
||||
|
||||
namlen = SCARG(uap, namelen);
|
||||
error = linux_sa_get(p, &sg, &sa, SCARG(uap, name), &namlen);
|
||||
error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
|
||||
SCARG(uap, name), &namlen);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
|
@ -1381,7 +1385,8 @@ linux_sys_bind(l, v, retval)
|
|||
struct sockaddr *sa;
|
||||
caddr_t sg = stackgap_init(p, 0);
|
||||
|
||||
error = linux_sa_get(p, &sg, &sa, SCARG(uap, name), &namlen);
|
||||
error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
|
||||
SCARG(uap, name), &namlen);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
|
@ -1443,8 +1448,9 @@ linux_sys_getpeername(l, v, retval)
|
|||
* the converted structure there, address on stackgap returned in sap.
|
||||
*/
|
||||
static int
|
||||
linux_sa_get(p, sgp, sap, osa, osalen)
|
||||
linux_sa_get(p, s, sgp, sap, osa, osalen)
|
||||
struct proc *p;
|
||||
int s;
|
||||
caddr_t *sgp;
|
||||
struct sockaddr **sap;
|
||||
const struct osockaddr *osa;
|
||||
|
@ -1520,8 +1526,31 @@ linux_sa_get(p, sgp, sap, osa, osalen)
|
|||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the family is unspecified, use address family of the
|
||||
* socket. This avoid triggering COMPAT_43 struct socket family check
|
||||
* in sockargs() on little-endian machines, and strict family checks
|
||||
* in netinet/in_pcb.c et.al.
|
||||
*/
|
||||
if (bdom == AF_UNSPEC) {
|
||||
struct file *fp;
|
||||
struct socket *so;
|
||||
|
||||
/* getsock() will use the descriptor for us */
|
||||
if ((error = getsock(p->p_fd, s, &fp)) != 0)
|
||||
goto out;
|
||||
|
||||
so = (struct socket *)fp->f_data;
|
||||
bdom = so->so_proto->pr_domain->dom_family;
|
||||
|
||||
FILE_UNUSE(fp, p);
|
||||
|
||||
DPRINTF(("AF_UNSPEC family adjusted to %d\n", bdom));
|
||||
}
|
||||
|
||||
if (bdom == AF_INET) {
|
||||
alloclen = sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue