Date: Wed, 15 Nov 2000 13:38:38 +0100 (MET) From: Jean-Luc Richier <Jean-Luc.Richier@imag.fr> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/22868: Returned mail: see transcript for details Message-ID: <200011151238.NAA08683@horus.imag.fr>
next in thread | raw e-mail | index | archive | help
>Number: 22868
>Category: kern
>Synopsis: getsockname may return an incorrect address
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Nov 15 04:40:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Jean-Luc Richier
>Release: FreeBSD 4.1.1-RELEASE i386
>Organization:
LSR-IMAG, Grenoble, France
>Environment:
FreeBSD >= 4.1 with INET6 support (native or kame)
Bug is still in FreeBSD-current and kame-20001106-freebsd41-snap
>Description:
With a udp/tcp INET6 socket which is bounded to the :: address and
IPv4 compatible, getsockname return an address ::fff:0.0.0.0 (that
is the any IPv4 address in AF_INET6 IPv4-mapped format) instead of ::
>How-To-Repeat:
- create an AF_INET6 udp socket
- call getsockname on it and print the returned address
cf the program:
------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct sockaddr_in6 sa;
main(argc,argv)
int argc;
char **argv;
{
int fd, l;
char buf[100];
if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
sa.sin6_family = AF_INET6;
l = sa.sin6_len = sizeof sa;
if (bind(fd, (struct sockaddr *)&sa, l) < 0)
err(1, "bind");
if (getsockname(fd, (struct sockaddr *)&sa, &l) < 0)
err(1, "getsockname");
inet_ntop(AF_INET6, &sa.sin6_addr, buf, sizeof buf);
printf("sock %d %d %d %s\n", l, sa.sin6_len, sa.sin6_family, buf);
}
-->
tuna# ./a.out
sock 28 28 28 ::ffff:0.0.0.0
>Fix:
The problem is in in6_pcb.c, function in6_mapped_sockaddr.
This function returns a IPv4-mapped address if the INP_IPV4 is set.
It should use IPv4-mapped address only if V6 is not possible, that
is, if INP_IPV6 is not set.
I suggest the following patch. By symetry I made the same change in
in6_mapped_peeraddr.
*** netinet6/in6_pcb.c.DIST Sat Jul 15 09:14:33 2000
--- netinet6/in6_pcb.c Wed Nov 15 12:59:08 2000
***************
*** 721,727 ****
if (inp == NULL)
return EINVAL;
! if (inp->inp_vflag & INP_IPV4) {
error = in_setsockaddr(so, nam);
if (error == 0)
in6_sin_2_v4mapsin6_in_sock(nam);
--- 721,727 ----
if (inp == NULL)
return EINVAL;
! if ((inp->inp_vflag & INP_IPV6) == NULL) {
error = in_setsockaddr(so, nam);
if (error == 0)
in6_sin_2_v4mapsin6_in_sock(nam);
***************
*** 739,745 ****
if (inp == NULL)
return EINVAL;
! if (inp->inp_vflag & INP_IPV4) {
error = in_setpeeraddr(so, nam);
if (error == 0)
in6_sin_2_v4mapsin6_in_sock(nam);
--- 739,745 ----
if (inp == NULL)
return EINVAL;
! if ((inp->inp_vflag & INP_IPV6) == NULL) {
error = in_setpeeraddr(so, nam);
if (error == 0)
in6_sin_2_v4mapsin6_in_sock(nam);
--
Jean-Luc RICHIER (Jean-Luc.Richier@Imag.Fr richier@imag.fr)
Laboratoire Logiciels, Systemes et Reseaux (LSR-IMAG)
IMAG-CAMPUS, BP 72, F-38402 St Martin d'Heres Cedex
Tel : +33 4 76 82 72 32 Fax : +33 4 76 82 72 87
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011151238.NAA08683>
