Subject: 6to4 using ::FFFF:0000:0000/96 (mail.comcast.net AAAA record weirdness)

From: Kevin Day <[email-masked]>
Date: Mon, 21 Jan 2008 18:58:18 -0600

We run a public 6to4 anycast relay. Today I received a complaint from  
a user that when he had his laptop connected to one ISP (that selected  
our anycast relay), he couldn't check his email. When he connected to  
a different ISP that used someone else's 6to4 relay, his email worked  
fine. I went around in circles with him for a while, because I  
couldn't understand how 6to4 was entering the equation when all his  
email access was going over v4. Sure enough, his v4 IP was talking to  
our 6to4 relay, and our relay was dropping the packets he was sending  
us.

After some digging, I added some debugging code to FreeBSD's 6to4  
relay module to display why certain packets were being dropped. In  
about 10 minutes I found that there were 53 unique v4 IPs using our  
6to4 relay that were attempting to send packets to ::ffff:3ff0:4c0a  
through the relay.

::ffff:3ff0:4c0a = 63.240.76.10 = mail.comcast.net

There were no other attempted accesses to anything  
using ::ffff:xxxx:xxxx, and FreeBSD's 6to4 code drops traffic to  
anything in that range. Doing a bit more digging, I discovered:

# nslookup -querytype=AAAA mail.comcast.net

Non-authoritative answer:
mail.comcast.net        canonical name = mail.g.comcast.net.
mail.g.comcast.net      has AAAA address ::ffff:63.240.76.10

This brings up a whole lot of questions....

1) What's Comcast trying to do with that AAAA record?

2) What 6to4 client implementation will try sending traffic to a v4  
address like that over v6?

3) How is this even possibly working when this user is going through  
someone else's relay? 6to4 can't NAT. :)

I'm also seeing some 6to4 clients trying to send packets to  :: 
7f00:0001 that I haven't even begun trying to figure out the source of.

-- Kevin

---

From: "Erik Kline" <[email-masked]>
Date: Wed, 23 Jan 2008 10:03:11 -0800

> 7f00:0001 that I haven't even begun trying to figure out the source of.

Does this not seem like an Operating System problem?  It seems to me
that ::ffff:0:0/96 should never really be seen on the wire.  Of course
the question of how this actually works is still very interesting.
One wonders what other 6to4 relays do with these packets.
Fascinating.

---

From: Alain Durand <[email-masked]>
Date: Wed, 23 Jan 2008 14:00:16 -0500

The AAAA records:

were not something we configured but were dynamically generated as a side
effect of a bug introduced by a certain piece of hardware in our network. A
temporary work around has been put in place until the bug is fixed. This is
just yet another confirmation that there should be no AAAA published (either
by configuration or dynamically generated) until all the pieces are in
place.

AAAA records containing IPv4 mapped addresses do not seem to be a good idea
anyway, it might be worth an addendum to RFC4472.

Thank you to those who pointed out this problem.

  - Alain.

---

From: Kevin Day <[email-masked]>
Date: Sun, 27 Jan 2008 14:21:21 -0600

On Jan 27, 2008, at 12:54 PM, Rémi Després wrote:

>
> 1.
>  I agree with Erik that this is an OS problem.
>  IMHO, he dual stack OS of the host, when it has to send a packet to  
> a mapped address, should use its IPv4 stack (ref RFC 2553 - 3.7)
>  If the application has selected this address as destination, it  
> must be because no IPv6 address other than IPv4 mapped was available  
> (no  address with a longer source-destination match,  in particular  
> none with  at least a 2000::/3 match).
>  It is therefore guaranteed that the destination is IPv4-only.
>  Using the IPv4 stack then works nicely.
>  Would FreeBDSD have done it, there not have been any problem.
>

Just to clarify, since I think I might have not stated this part  
clearly...

FreeBSD was running on the 6to4 relay server, the clients in  
question(the systems actually initiating the traffic) appeared to all  
be Windows based.

FreeBSD doesn't seem to ever try to send ::ffff:0:0/96 over a 6to4  
connection, which I believe is the correct thing to do. The original  
client shouldn't have used its v6 stack at all when accessing a v4  
mapped address.

On FreeBSD:

freebsd# nslookup -querytype=AAAA mappedtest.your.org

Non-authoritative answer:
mappedtest.your.org	has AAAA address ::ffff:204.9.48.81

send some test traffic to it:

freebsd# telnet mappedtest.your.org 6789
Trying ::ffff:204.9.48.81...
telnet: connect to address ::ffff:204.9.48.81: Connection refused
telnet: Unable to connect to remote host

then watch on tcpdump:

19:38:55.191823 IP freebsdbox.63865 > 204.9.48.81.6789: S  
811563213:811563213(0) win 65535 <mss 1460,nop,wscale  
4,nop,nop,timestamp 3955202055 0,sackOK,eol>
19:38:55.192043 IP 204.9.48.81.6789 > freebsdbox.63865: R 0:0(0) ack  
811563214 win 0

Nothing touched 6to4 there.

However, trying the same thing from an XP box using 6to4:

14:18:44.780353 IP 69.31.99.17 > 192.88.99.1: IP6 2002:451f:6311::451f: 
6311.1026 > ::ffff:204.9.48.81.6789: S 2991418190:2991418190(0) win  
16384 <mss[|tcp]>

So, I think it's XP not doing the right thing here... XP should be  
selecting its own v4 stack instead of trying to shove packets  
to ::ffff:0:0/96 down 6to4... correct?

I've got a contact in Microsoft that works with their v6  
implementation that I'll get in touch with to see if I can figure out  
why Windows is doing this.

-- Kevin

---

From: Brian E Carpenter <[email-masked]>
Date: Mon, 28 Jan 2008 10:16:08 +1300

On 2008-01-28 09:21, Kevin Day wrote:
...
> client shouldn't have used its v6 stack at all when accessing a v4

That isn't necessarily so. If the client is attempting to reach
a SIIT translator, such as a NAT-PT, the mapped address should
be used, and should be routed to the translator. In that case,
there's no reason that the path to the translator shouldn't start
out as 6to4. IMHO this needs to be a configurable behaviour.
It's unfortunate, to say the least, that mapped addresses have
these two different uses.

...
> selecting its own v4 stack instead of trying to shove packets to
> ::ffff:0:0/96 down 6to4... correct?

It seems to be a matter of taste which is the default.

    Brian

---

From: Florian Weimer <[email-masked]>
Date: Sun, 27 Jan 2008 22:32:55 +0100

> ::ffff:0:0/96 down 6to4... correct?

Yes, I think this would have been the correct approach.

---

From: Florian Weimer <[email-masked]>
Date: Sun, 27 Jan 2008 22:58:49 +0100

> It seems to be a matter of taste which is the default.

Uhm, I think for a public anycast gateway (that's what we're talking
about, right?), there's no other option than using the v4 stack instead.
So the sane default seems clear to me.

---

From: Kevin Day <[email-masked]>
Date: Sun, 27 Jan 2008 16:10:02 -0600

> these two different uses.

While I understand translation is a slightly different case, as a 6to4  
relay operator I'm still not sure what the relay is supposed to do  
with a mapped destination address.

The only options I see are:

1) The relay converts it back to a v4 packet and sends it off using  
the client's v4 address.

In my tcpdump example:

IP 69.31.99.17 > 192.88.99.1: IP6 2002:451f:6311::451f:6311.1026  
 > ::ffff:204.9.48.81.6789: S 2991418190:2991418190(0) win 16384 <mss[| 
tcp]>

would convert 2002:451f:6311::451f:6311 back to 69.31.99.17, and send  
that to 204.9.48.81.

This is going to fail because of RPF or other anti-spoofing methods.  
This also doesn't work because the client is considering this a v6  
connection, and is expecting replies back to 2002:451f:6311::451f:6311.

2) The relay passes the packet through to the gateway as though it  
were any other v6 packet.

draft-itojun-v6ops-v4mapped-harmful-00.txt seems to say that this is a  
bad idea. I realize it's was only a draft, but the BSD's were  
convinced by its arguments, won't accept or transmit v4 mapped  
addresses on the wire.

Just to confirm I'm not crazy, I forced some onto the wire and our  
Juniper routers just dropped them as well.

FreeBSD right now has the following code/comment in it that refuses  
any v4 mapped addresses coming into it from the outside at all:

         /*
          * The following check is not documented in specs.  A malicious
          * party may be able to use IPv4 mapped addr to confuse tcp/ 
udp stack
          * and bypass security checks (act as if it was from  
127.0.0.1 by using
          * IPv6 src ::ffff:127.0.0.1).  Be cautious.
          *
          * This check chokes if we are in an SIIT cloud.  As none of  
BSDs
          * support IPv4-less kernel compilation, we cannot support SIIT
          * environment at all.  So, it makes more sense for us to  
reject any
          * malicious packets for non-SIIT environment, than try to do a
          * partial support for SIIT environment.
          */
         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
                 ip6stat.ip6s_badscope++;
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
                 goto bad;
         }

The 6to4 relay code goes one step further and blocks both mapped AND  
compatible addresses:

         if (IN6_IS_ADDR_V4COMPAT(in6) || IN6_IS_ADDR_V4MAPPED(in6))
                 return -1;

So, to sum up:

A 6to4 relay can't convert the packet back to a v4 packet. The client  
is expecting a reply to come back to it on its v6 stack, and you'd be  
dictating that public 6to4 relays would have to be able to spoof  
traffic from the world.

A 6to4 relay can't just treat it like a normal v6 address, because  
relays (mine anyway) won't forward packets that are to v4 mapped  
addresses. Additionally, our router won't do anything with them either.

I understand SIIT and NAT-PT use them locally, but... I can't imagine  
a scenario where a SIIT box is going to be sending 6to4 encapsulated  
traffic to a 6to4 relay?

When you say "there's no reason that the path to the translator  
shouldn't start out as 6to4", do you mean v6 only boxes behind the  
translator? If so, they've got no reason to talk to a 6to4 relay at all.

I guess what I'm asking is, if you're saying that this really is  
desirable to do, what do you want a 6to4 relay to do with these packets?

-- Kevin

---

From: Brian E Carpenter <[email-masked]>
Date: Mon, 28 Jan 2008 14:34:58 +1300

> So the sane default seems clear to me.

I don't know any reason why one couldn't reach a NAT-PT via
an anycast-addressed 6to4 relay. The point is that we ended
up overloading the usage of the mapped-IPv4 prefix - not only
the sin of encoding semantics in the address bits, but also the
sin of doing so ambiguously. So no default can be "correct".
Probably local mapping to the IPv4 stack is slightly saner.

    Brian

---

From: "Erik Kline" <[email-masked]>
Date: Sun, 27 Jan 2008 19:16:30 -0800

> Probably local mapping to the IPv4 stack is slightly saner.

These are excellent points -- I hadn't thought about the case of an
IPv6-only client behind a dual-stack 6to4 host trying to reach
(through) a translator.  That seems perfectly legitimate to me.  I
would have to agree, though, that if the packet originates on a
dual-stack host then it should probably have defaulted to using its
own IPv4 stack.

Thanks for the clarification,
-Erik

---

From: Brian E Carpenter <[email-masked]>
Date: Mon, 28 Jan 2008 16:54:19 +1300

I think there are two other options for the relay.

3) Forward the packet to your local friendly NAT-PT box.
This is really a version of #2 - in fact it's the only
case I can think of where #2 would be useful. Of course,
most people don't have a local friendly NAT-PT.

4) Drop it. That would be my preference as a default.

    Brian

On 2008-01-28 11:10, Kevin Day wrote:
>>> mapped address
> relay operator I'm still not sure what the relay is supposed to do with
> a mapped destination address.
> 
> 1) The relay converts it back to a v4 packet and sends it off using the
> client's v4 address.
> 
> In my tcpdump example:
> 
> IP 69.31.99.17 > 192.88.99.1: IP6 2002:451f:6311::451f:6311.1026 >
> ::ffff:204.9.48.81.6789: S 2991418190:2991418190(0) win 16384 <mss[|tcp]>
> 
> 2) The relay passes the packet through to the gateway as though it were
> any other v6 packet.
> 
> bad idea. I realize it's was only a draft, but the BSD's were convinced
> by its arguments, won't accept or transmit v4 mapped addresses on the wire.
> 
> FreeBSD right now has the following code/comment in it that refuses any
> v4 mapped addresses coming into it from the outside at all:
> 
>         /*
>          * party may be able to use IPv4 mapped addr to confuse tcp/udp
> stack
>          * and bypass security checks (act as if it was from 127.0.0.1
> by using
>          * This check chokes if we are in an SIIT cloud.  As none of BSDs
>          * environment at all.  So, it makes more sense for us to reject
> any
> A 6to4 relay can't convert the packet back to a v4 packet. The client is
> expecting a reply to come back to it on its v6 stack, and you'd be
> dictating that public 6to4 relays would have to be able to spoof traffic
> from the world.
> 
> I understand SIIT and NAT-PT use them locally, but... I can't imagine a
> scenario where a SIIT box is going to be sending 6to4 encapsulated
> traffic to a 6to4 relay?
>

---

From: Kevin Day <[email-masked]>
Date: Sun, 27 Jan 2008 22:45:50 -0600

> most people don't have a local friendly NAT-PT.

That might be a little tough for those of us running public anycast  
relays to pull off, but perhaps locally sure. :)

I will say that this seems to be impossible for someone running a  
relay on any of the BSDs(Free/Net/Open/Dragonfly), or OS X.  They will  
not accept or route any mapped(::FFFF:0:0/96) addresses at any time,  
so it's not possible without removing some code from in_input.c to  
even forward packets to a NAT-PT box.

However, I think this is a bit dangerous to allow by default for  
forwarding. It's not too hard to imagine cases where networks are  
using tunnels to gain v6 connectivity, and don't have their firewalls  
or other security set up to handle v4 packets being injected into  
their network from their tunnel box.

All this said, I'm seeing even more "unusual" traffic on our 6to4  
relay that's outside mapped addresses showing up... In the past few  
days of watching, I've seen 6to4 clients try sending to the 6to4 relay  
packets with destination addresses in:

Unicast:

Link Local (FE80::)
Site Local (FEC0::)
v4 compatibility (::/96)
v4 mapped (::FFFF:0:0/96)
All zeros (::)
Loopback (::1)
Obviously invalid addresses (BBBB:BBBB:BBBB:BBBB:BBBB:BBBB:BBBB:BBBB,  
etc)

Multicast:

Unknown multicast (FF00::)
Node Local (FF01::)
Link Local (FF02::)
Site Local (FF05::)

I've been trying to trace the source of as many of these as is  
possible, but with the pretty anonymous nature of 6to4 it's a little  
difficult. Before I expend too much energy on this:

1) Has anyone already done this digging before?

2) Is it of interest to anyone other than myself? :)

For right now, the default action of our relay is to drop all of  
these, but I'm mostly interested in what the clients are trying to  
accomplish with traffic like this, and what (if anything) is breaking  
as a result of it.

-- Kevin

---

From: Iljitsch van Beijnum <[email-masked]>
Date: Mon, 28 Jan 2008 09:43:16 +0100

> most people don't have a local friendly NAT-PT.

Also, the use cases for NAT-PT and 6to4 are highly orthogonal: one  
supports reaching IPv4 for hosts with only IPv6 connectivity, the  
other supports reaching IPv6 for hosts with only IPv6 connectivity. So  
I guess NAT-PT and 6to4 together would be useful for hosts without  
_any_ connectivity?

A point about Windows XP: the IPv4 and IPv6 stacks are separate. So XP  
can't generate IPv4 packets when applications use the IPv6 socket  
calls. This is of course highly suboptimal but this means that "simply  
generate IPv4 packets for ::ffff:x.x.x.x AAAA records" is not a  
natural choice.

I would suggest that implementations ignore AAAA records with IPv4- 
mapped addresses. There are probably some other address ranges that  
shouldn't show up in the DNS too (multicast?).

---

From: Rémi Després <[email-masked]>
Date: Mon, 28 Jan 2008 10:20:37 +0100

1. The RFC on Basic Socket Interface Extensions for IPv6 (RFC 2553)
states in its section 3.7:
<< Applications may use PF_INET6 sockets to open TCP connections to IPv4
    nodes, or send UDP packets to IPv4 nodes, by simply encoding the
    destination's IPv4 address as an IPv4-mapped IPv6 address, and
    passing that address, within a sockaddr_in6 structure, in the
    connect() or sendto() call. >>

IMHO all clients have just to comply, and use their IPv4 stacks when
destinations are mapped addresses.
If XP had done it, no problem would have been identified by Kevin, and
6to4 would not have been in the loop.

2. My previous answer to Kevin and Erik was received by them, but not by
v6ops (apologies for that).
It also contained this comment, which I see as relevant:

>  I am very pleased that Kevin came up with this "fascinating" example
> which revives the "mapped AAAA" issue.
>  As a matter of fact, mapped addresses as IPv6 destinations are IMHO
> very useful for the future, as shows an earlier contribution on the 
subject:
> http://ops.ietf.org/lists/v6ops/v6ops.2007/msg01031.html
>
>  A particular application of mapped AAAA records is for IPv4-only Web
> servers to be reachable by  IPv6-only clients
>   - these servers have mapped AAAA in their DNS servers in addition to
> their As (feasible manually)
>   - these clients are in sites where CPEs support NAT v6-v4  (a fairly
> simple software evolution of a v4-v4).

Rémi

> be used, and should be routed to the translator. 
IMHO there is one case where a mapped destination address could reach a
SIIT.
That is if the source host is IPv6-only (not being dual stack, it is not
cocerned with the obligation of RFC-2553 sec. 3,7).
I believe we agree that this a useful case (as I believe we agree that
IPv6 to IPv4 NAT is very useful for graceful transition from IPv4 to IPv6)

> It seems to be a matter of taste which is the default.

NO, fortunately it isn't a matter of taste (see 1. above) :-).

---

From: Florian Weimer <[email-masked]>
Date: Mon, 28 Jan 2008 10:52:30 +0100

> generate IPv4 packets for ::ffff:x.x.x.x AAAA records" is not a

They could add a route to a local process that implements a NAT-PT
gateway, I guess.

---

From: Florian Weimer <[email-masked]>
Date: Mon, 28 Jan 2008 10:55:22 +0100

> even forward packets to a NAT-PT box.

And thanks to BCP38 filters, you actually need to run some kind of NAT,
which means that the gateway is no longer stateless.  Maybe this
wouldn't be a problem, but I fear that it doesn't really help to improve
reliability of that service.

---

From: Rémi Després <[email-masked]>
Date: Mon, 28 Jan 2008 11:17:47 +0100

Florian Weimer a écrit :
> * Rémi Després:
> How important is this feature in practice?  Could we deprecate it?
> 
> 
IMO deprecating it would be a bad step backward!

Rémi

---

From: David Malone <[email-masked]>
Date: Mon, 28 Jan 2008 11:40:07 +0000

> IMO deprecating it would be a bad step backward!

Yes - there is a (reasonable) school of thought that says that
draft-itojun-v6ops-v4mapped-harmful missed the mark, and that it
is actally better to write server applications to use a single
socket to accept both IPv4 and IPv6 clients. You then always use
mapped addresses to represent IPv4 addresses in ACLs/firewalls/...
Deprecating this would make life harder for people who have chosen
this model of managing dual-stacked applications.

	David.

---

From: Iljitsch van Beijnum <[email-masked]>
Date: Mon, 28 Jan 2008 13:53:41 +0100

> IMO deprecating it would be a bad step backward!

Indeed.

I can't say that I spend a lot of time writing applications, but I  
consider having a single interface to talk IPv4 and IPv6 extremely  
important. Without that, it's very easy to have bugs that only come up  
in one IP version and it is of course extra work to have two sets of  
socket calls. Worse, it's not possible to create IP version agnostic  
applications.

---

From: Jeroen Massar <[email-masked]>
Date: Mon, 28 Jan 2008 14:50:04 +0100

Iljitsch van Beijnum wrote:
[..]
> important.

Exactly because you don't write enough applications ;)

There is a single interface: BSD sockets.

getaddrinfo(), getnameinfo(), socket(), connect()/listen()/bind(), 
recv() & write().

Works for both IPv4 and IPv6, people just have to get used to using the 
select() function for using multiple sockets at the same time.

yes, that makes server-side programs (the ones that listen) a bit more 
difficult to write. Client programs stay the same, loop, try to connect 
and presto.

If you really want to solve the "I don't get this" problem, or the "I 
don't want to do this", use one of the many excellent libraries which 
wrap all around this. Maybe there is something that the IETF should do: 
publish a library which is in the public domain and AF and actually 
socket agnostic?

> Without that, it's very easy to have bugs that only come up 
> socket calls.

It indeed is very easy to have bugs when you are mixing IPv4 and IPv6.
eg a 'firewall' which only checks the first 32bits of the address. Or 
what about the original subject, trying to send from IPv4 over IPv6 to 
IPv4, auto-translating A records into AAAA. Not even going to the 
RBL-code reversing only the first

Yes, IPv4-mapped/compat was a good idea, and using it correctly 
internally in an application is probably a good move. But using it on 
the wire or when presenting it to users is definitely not.

> Worse, it's not possible to create IP version agnostic 
> applications.

(There is a word which starts with the letter B, which is the male 
version of a cow and then ends in what it produces, not talking about 
milk here)

Please read:
http://www.kame.net/newsletter/19980604/
http://gsyc.escet.urjc.es/~eva/IPv6-web/ipv6.html

Note that the first document is nearly TEN (that is 10) years old 
already. The second one by Eva definitely should be able to let any 
programmer understand how easy it is to write a perfectly fine socket 
program.

Greets,
  Jeroen

---

From: Iljitsch van Beijnum <[email-masked]>
Date: Mon, 28 Jan 2008 15:38:45 +0100

On 28 jan 2008, at 14:50, Jeroen Massar wrote:

Jeroen, I'm not quoting your message, because it doesn't make any  
sense to me.

What I was saying is that it's important to be able to do this, which  
I've lifted from the getnameinfo() and getaddrinfo() socket call  
manpages on my Mac with some minimal changes. This tries to set up a  
TCP session towards port 80 on www.kame.net, cycles through all  
available addresses and prints those when trying. The same code will  
do the same thing over IPv4 or IPv6, depending on A/AAAA records and  
local connectivity. Using this type of code of course does NOT mean  
that IPv6 packets with ::ffff:x.x.x.x addresses are either sent or  
received, those can/should be filtered.

For those not skilled in the art of C programming: note how cumbersome  
it is to do even simple stuff.

#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>

main()
{
  struct addrinfo hints, *res, *res0;
  int error;
  int s;
  const char *cause = NULL;
            char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = PF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  error = getaddrinfo("www.kame.net", "http", &hints, &res0);
  if (error) {
          errx(1, "%s", gai_strerror(error));
          /*NOTREACHED*/
  }
  s = -1;
  for (res = res0; res; res = res->ai_next) {
          s = socket(res->ai_family, res->ai_socktype,
              res->ai_protocol);
          if (s < 0) {
                  cause = "socket";
                  continue;
          }

            if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,  
sizeof(hbuf), sbuf,
                sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
                    errx(1, "could not get numeric hostname");
                    /*NOTREACHED*/
            }
            printf("host=%s, serv=%s\n", hbuf, sbuf);

          if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
                  cause = "connect";
                  close(s);
                  s = -1;
                  continue;
          }

          break;  /* okay we got one */
  }
  if (s < 0) {
          err(1, "%s", cause);
          /*NOTREACHED*/
  }
  freeaddrinfo(res0);
}

---

From: Jeroen Massar <[email-masked]>
Date: Mon, 28 Jan 2008 15:46:05 +0100

Iljitsch van Beijnum wrote:
> Jeroen, I'm not quoting your message, because it doesn't make any sense 
> to me.

Then read it again and quote what is not understood.

> manpages on my Mac with some minimal changes.

Which is in my message:

8<-----------------------------------------------------------------------
Please read:
http://www.kame.net/newsletter/19980604/
http://gsyc.escet.urjc.es/~eva/IPv6-web/ipv6.html

Note that the first document is nearly TEN (that is 10) years old 
already. The second one by Eva definitely should be able to let any 
programmer understand how easy it is to write a perfectly fine socket 
program.
----------------------------------------------------------------------->8

As I mentioned also, *clients*, thus code that uses connect(), are 
really easy to code. Servers though, thus code that uses listen(), are 
not so, as one will need to use multiple sockets.

Greets,
  Jeroen

---

From: Rémi Després <[email-masked]>
Date: Mon, 28 Jan 2008 16:44:47 +0100

Jeroen Massar wrote :
> internally in an application is probably a good move.
Yes. IMHO a nice and clean design.
> But using it on 
Why ???

Consider in particular a dual stack site with a private IPv4 space.
Its CPE, which has a NATv4-v4, may also have a NATv6-v4.
If it has one, and if it uses it for outgoing packets that have 0::/64 
destinations, IPv6-only hosts on the LAN can establish connections with 
  IPv6 *AND* IPv4 remote hosts.
IMHO this is nice and clean.

On the other hand, reasons for such a definite statement as "never a 
mapped address on any wire" have to be presented.

The reference I know on the subject is
file:///Users/Pro/Documents/_%20TECHNIQUE%20/IPv6-IPv4/MSG%20Itojun%20Hagino%20-%20Mapped%20addresses%20Considered%20Harmful00301.html
Is there a more recent one which would not be obsoleted ?

Objections of this one as far as I know don't apply to the above example.

Rémi

---

From: Jeroen Massar <[email-masked]>
Date: Mon, 28 Jan 2008 17:15:27 +0100

Rémi Després wrote:
>> But using it on the wire or when presenting it to users is definitely 
>> not.
> Why ???

Because ::x.x.x.x and ::ffff:x.x.x.x are IPv4, it is not IPv6.

> If it has one, and if it uses it for outgoing packets that have 0::/64 

::/96 you mean I guess ;)

>  IPv6 *AND* IPv4 remote hosts.

Why are you trying to translate IPv4 -> IPv6 to IPv4 and introduce state 
at the two translators, not even thinking of the mess it has to create 
for NATting these packets? You can simply do IPv4 -> IPv4.

> IMHO this is nice and clean.

That is very dirty in my opinion.

> mapped address on any wire" have to be presented.

How do you write your firewall? The user has IPv4 enabled, they have a 
working IPv4 firewall. IPv6 gets enabled, and suddenly the IPv4 firewall 
is completely moot as it can be bypassed by sending those packets as 
IPv6 in the ::/96 range. Ouch.

> file:///Users/Pro/Documents/_%20TECHNIQUE%20/IPv6-IPv4/MSG%20Itojun%20Hagino%20-%20Mapped%20addresses%20Considered%20Harmful00301.html 

I am pretty sure I can't reach that location.

Greets,
  Jeroen

---

From: Kevin Day <[email-masked]>
Date: Mon, 28 Jan 2008 10:55:57 -0600

On Jan 28, 2008, at 9:44 AM, Rémi Després wrote:

> Jeroen Massar wrote :
>> But using it on the wire or when presenting it to users is  
>> definitely not.
> Why ???
>

The problem with presenting v4 mapped/compatibility addresses on the  
wire is that the behavior of such packets has been left undefined so  
far.

* How these packets should be routed is completely undefined. Should  
routers handle them as though they were normal v6 unicast addresses?  
Or should they look at the v4 address and route them the same way as  
though it were v4? What about "special" v4 addresses (127.0.0.1,  
multicast, etc)? From my very limited testing, it looks like Juniper  
routers drop them, even if you add specific routes within the /96s for  
them. Our very old Cisco sends back an ICMP unreachable,

* There seems to be no behavior for 6to4, Teredo or tunnel brokers to  
do that results in anything working when receiving packets destined to/ 
sourced from these addresses.

* There are profound security implications of allowing v4 mapped/ 
compatibility addresses into your network. I'm not aware of any  
firewall or security device that will handle v4 mapped/compatibility  
addressed v6 packets, while still handling any of the behaviors  
considered for v4. One example brought up on one of the FreeBSD  
mailing lists long ago, before "net.inet6.ip6.v6only" got defaulted to  
"1" (essentially turning off v4 compatibility address use) was  
something like:

# Add a firewall rule keeping everyone out of my telnet server. All  
packets from anywhere to 1.2.3.4 to port 23 are dropped.
ipfw add drop tcp from any to 1.2.3.4 23

Now, even if this host has no v6 configured beyond an auto-configured  
link-local address, it was possible to "telnet ::FFFF:0102:0304" from  
somewhere else on the LAN and bypass the firewall. Since then changes  
were made to prevent this sort of thing in the simplest of cases (v4  
compatibility addresses off by default, not accepting them over the  
wire at any time, etc).

While that's a really simplistic example, it shows that allowing these  
packets on the wire adds an attack vector that wouldn't be considered  
by most. Its giving attackers three different ways of expressing the  
same address(v4 native, mapped, and compatibility) which doesn't take  
much imagination to see being exploited.

* There's no standard for how clients/servers should respond to these,  
leading to breakage already. If you send a Linux server a packet  
to ::FFFF:0102:0304 it responds back using its v4 stack with 1.2.3.4.  
Windows uses its v6 stack, even when it probably doesn't make sense to  
(through 6to4/Teredo tunnels). Mac OS X and the BSDs drop all packets  
in ::FFFF:0:0/96 and ::/96 going in/out.

The only time I could ever see them being acceptable is on a link- 
local scope, and only to/from your gateway for NAT-PT, and only in the  
case where you've got a v6-ONLY box that must talk to a v4 device.  
Even then though, it feels wrong. :)

---

From: Rémi Després <[email-masked]>
Date: Mon, 28 Jan 2008 18:23:59 +0100

> Because ::x.x.x.x and ::ffff:x.x.x.x are IPv4, it is not IPv6.

IMO too general to be sufficient

> ::/96 you mean I guess ;)
No.
Routing is in general performed on 64 bits (the remainder is IID, IMU 
not candiadate to be part of a prefix).
But no objection to /96 where it is supported.
> 
>> destinations, IPv6-only hosts on the LAN can establish connections 
>> with  IPv6 *AND* IPv4 remote hosts.
> 

I don't!
If you read carefully, you will see that IPv6 host reach IPv4 hosts via 
only one NAT (v6-v4).
> That is very dirty in my opinion.
Matter of taste then.
But at least this lets a real *IPv6-only* hostto reach an IPv4-only 
server, e.g. in HTTP.

> I am pretty sure I can't reach that location.
I copied this URL, pasted it in Mozilla thunderbird, and reached the 
(obsolete) document.
Either you were wrong in being "pretty sure" (once more ??) or your 
browser, or your OS, has a problem.

Regards

Rémi

---

From: Christian Huitema <[email-masked]>
Date: Mon, 28 Jan 2008 09:39:52 -0800

> in ::FFFF:0:0/96 and ::/96 going in/out.

What about KISS? The current specification of ::FFFF:0:0/96 is essentially that of a "magic value". According to some, whenever that magic value is encountered, something extraordinary shall happen, such as switching to a different network level protocol. This is a recipe for trouble, because it breaks the "keep it simple" rule.

What we have for every other address prefix is simple. V6 packets are sent using V6, and the outgoing interfaces are chosen according to V6 routing rules. In a host, the header of incoming V6 packet is checked, and unicast packets are rejected if the particular destination address is not recognized as a valid address for the receiving interface. In a router, packets are routed according to routing tables, and if no route is configured packets are dropped. Some routers may also perform ingress filtering. Anything more complex than is guaranteed to cause problems.

I think that Itojun was right, and we should simply deprecate the ::FFFF:0:0/96 prefix.

-- Christian Huitema

---

From: Jeroen Massar <[email-masked]>
Date: Mon, 28 Jan 2008 18:53:46 +0100

> IMO too general to be sufficient

It very generally is a very bad general idea ;)

It *WAS* a great idea in the beginning, to get IPv6 going and to get 
some form of communication between IPv4 and IPv6, but if you have 
written a couple of programs (not clients) and bumped into it a couple 
of times you will realize that it is not a good idea.

I am fully with our samurai on this one.

> But no objection to /96 where it is supported.

Please see RFC4291 section 2.5.5.1 and 2.5.5.2. These special prefixes 
are longer and are excluded from that space, they are special after all.

[..]
> But at least this lets a real *IPv6-only* hostto reach an IPv4-only 

Please use application proxies for this, and not routing tricks and by 
introducing NAT into IPv6. NAT-PT was deprecated for a reason.

[..]
> I copied this URL, pasted it in Mozilla thunderbird, and reached the 

Unless you give all of the IETF access to your local disk some way, and 
include a hostname in that URL, then we might be able to see the 
document that you are linking to ;)

> browser, or your OS, has a problem.

I am still pretty sure about this. I guess you should take a good deep 
look at the url :)

*hint*, it starts with file:// and then has /Users/Pro/Documents/.....

/me passes out fresh caffeine shots ;)

Indeed it works for you locally, as it is on your local disk, that is 
the trick with the file: protocol handler.

Please provide a link to the document that resides on the public 
internet. (Starting with 'http(s)://' is a good thing).

Greets,
  Jeroen

---

From: Rémi Després <[email-masked]>
Date: Mon, 28 Jan 2008 19:20:56 +0100

Thanks for the detailed answer.
My comments are in line.

Kevin Day a écrit :
> wire is that the behavior of such packets has been left undefined so far.

> * How these packets should be routed is completely undefined.

I agree that there is some blank here.
However If a route is configured, with the 0::/64 prefix, to reach 
NATv6-v4 boxes, the longest prefix match will do what is expected.
Any other assumption would require some extra code.

> Should 
> routers handle them as though they were normal v6 unicast addresses? Or 
> should they look at the v4 address and route them the same way as though 
> it were v4?
NO.
> What about "special" v4 addresses (127.0.0.1, multicast, 
> etc)? From my very limited testing, it looks like Juniper routers drop 
> them, even if you add specific routes within the /96s for them. Our very 
IPv4 multicast destinations will have, and must have, the same fate in 
NATv4-v4s.

> * There seems to be no behavior for 6to4, Teredo or tunnel brokers to do 
> that results in anything working when receiving packets destined 
> to/sourced from these addresses.
Hosts considered here are assumed to be pure IPv6, and to be in sites 
where NATv6-v4 is available.

Boxes that do the NATv6-v4 may also have other means to tunnel IPv6 in 
IPv4.
There is no conflict because these other means act when destinations are 
IPv6, not IPv4-only.

> * There are profound security implications of allowing v4 
> mapped/compatibility addresses into your network. I'm not aware of any 
> considered for v4. One example brought up on one of the FreeBSD mailing 
> lists long ago, before "net.inet6.ip6.v6only" got defaulted to "1" 
> (essentially turning off v4 compatibility address use) was something like:
> 
> somewhere else on the LAN and bypass the firewall.
I am not sure I see the configuration.
But the NATv6-v4 I discuss being only for outgoing connections, it seems 
guaranteed that it cannot not create a new hole for incoming connections.

> Since then changes 
> compatibility addresses off by default, not accepting them over the wire 
> at any time, etc).
> 
> packets on the wire adds an attack vector that wouldn't be considered by 
> most. Its giving attackers three different ways of expressing the same 
> address(v4 native, mapped, and compatibility) which doesn't take much 
> imagination to see being exploited.
The mapped address is only to express the public address of IPv4-only 
hosts where native such addresses cannot be used (in IPv6-only 
applications and at IPv6 link interfaces of IPv6-only hosts).
It is not one more way to do something already done.

> leading to breakage already. If you send a Linux server a packet to 
> ::FFFF:0102:0304 it responds back using its v4 stack with 1.2.3.4. 
> (through 6to4/Teredo tunnels). Mac OS X and the BSDs drop all packets in 
> ::FFFF:0:0/96 and ::/96 going in/out.
The case at hand is for an IPv6-only host reaching IPv4-only servers.
These servers will not see any mapped address.

> The only time I could ever see them being acceptable is on a link-local 
> scope, and only to/from your gateway for NAT-PT,
It would work as well in multi-subnet sites provided both IPv6 and IPv4 
are routed (and that the 0::/64 prefix is not artificially forbidden in 
intra-site routers).

> and only in the case 
> where you've got a v6-ONLY box that must talk to a v4 device.
This "only" case is IMHO worth dealing with.
It could very well become soon a practical case, when boxes that support 
NATv4-v4 also support NATv6-v4, a rather simple an extension (longer 
address support in NAT tables).
> though, it feels wrong. :)
I do hope you will soon feel differently, and even enthousiastic as I am 
about this simple solution to a real problem.

Thanks again for the discussion.

Rémi

---

From: Rémi Després <[email-masked]>
Date: Mon, 28 Jan 2008 19:31:17 +0100

> document that you are linking to ;)

You got me.
Apologies :-).

> internet. (Starting with 'http(s)://' is a good thing).
Could you try this one:
http://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-00

Rémi

---

From: Brian E Carpenter <[email-masked]>
Date: Tue, 29 Jan 2008 10:09:45 +1300

> socket calls. Worse, it's not possible to create IP version agnostic

I agree. That's why I've just come to realise the disastrous effect of
overloading IPv4-mapped addresses for both RFC 2553 and NAT-PT/SIIT usage.
We blew it.

Unfortunately, the above "may" isn't even a normative MAY, let alone
a SHOULD or MUST.

   Brian

---

From: Antonio Querubin <[email-masked]>
Date: Mon, 28 Jan 2008 15:32:42 -1000 (HST)

On Mon, 28 Jan 2008, Jeroen Massar wrote:

> Yes, IPv4-mapped/compat was a good idea, and using it correctly internally in 
> an application is probably a good move. But using it on the wire or when 
> presenting it to users is definitely not.

If you use one socket per AF, you really wouldn't need mapped addresses 
would you?  And yet you agree that using mapped addresses correctly 
internally is a good thing.  The main motivator for using mapped 
internally is if you program to a single unified socket for both AF.  Or 
am I misunderstanding you?

I agree that mapped/compat on the wire is a bad thing but hasn't that dead 
horse been beaten enough already?

In a v6-only world none of this would matter, but we have a transition we 
need to get through and the way things are looking it's gonna be a very 
long transition.  I think for the majority of apps and their developers, a 
significant paradigm change to two socket programming adds unnecessary 
complexity and is counter-productive to transition efforts.  The benefits 
of unified socket simplicity outweigh the risks to the relatively small 
percentage of apps that actually need to care what type of IP address is 
used.

Antonio Querubin
whois:  AQ7-ARIN

---

From: Rémi Després <[email-masked]>
Date: Tue, 29 Jan 2008 10:02:44 +0100

Christian Huitema wrote :
> What about KISS? The current specification of ::FFFF:0:0/96 is
> essentially that of a "magic value".
In a different view, which IMHO is right, what RFC 2535 says makes 
sense, is indeed simple, and is not magic.
<<<
    The API also provides a different type of compatibility: the ability
    for IPv6 applications to interoperate with IPv4 applications.  This
    feature uses the IPv4-mapped IPv6 address format defined in the IPv6
    addressing architecture specification [2].  This address format
    allows the IPv4 address of an IPv4 node to be represented as an IPv6
    address.  The IPv4 address is encoded into the low-order 32 bits of
    the IPv6 address, and the high-order 96 bits hold the fixed prefix
    0:0:0:0:0:FFFF.  IPv4- mapped addresses are written as follows:

       ::FFFF:<IPv4-address>

    These addresses can be generated automatically by the
    getipnodebyname() function when the specified host has only IPv4
    addresses (as described in Section 6.1).

    Applications may use PF_INET6 sockets to open TCP connections to IPv4
    nodes, or send UDP packets to IPv4 nodes, by simply encoding the
    destination's IPv4 address as an IPv4-mapped IPv6 address, and
    passing that address, within a sockaddr_in6 structure, in the
    connect() or sendto() call.  When applications use PF_INET6 sockets
    to accept TCP connections from IPv4 nodes, or receive UDP packets
    from IPv4 nodes, the system returns the peer's address to the
    application in the accept(), recvfrom(), or getpeername() call using
    a sockaddr_in6 structure encoded this way.>>>

Since applications *MAY* use PF_INET6 to send packets to IPv4 nodes 
(IPv4 meaning here "IPv4-only"), dual stacks *SHOULD* better send these 
packets in IPv4 when IPv4 link interfaces are available: if sent in 
IPv6, they are likely to find no paths to their destinations; in IPv4 
they would normally reach their destinations.

> According to some, whenever that magic value is encountered,
> something extraordinary shall happen, such  > as switching to a different network level protocol. This is a recipe
> for trouble, because it breaks the "keep it simple" rule.
In the different view, letting applications to have only one socket 
interface is *simpler* than obliging them to know whether the IP layer 
works in IPv4 or IPv6.

> What we have for every other address prefix is simple. V6 packets are
> sent using V6, and the outgoing interfaces are chosen according to V6
> routing rules. In a host, the header of incoming V6 packet is
> checked, and unicast packets are rejected if the particular
> destination address is not recognized as a valid address for the
> receiving interface. In a router, packets are routed according to
> routing tables, and if no route is configured packets are dropped.
> Some routers may also perform ingress filtering. Anything more
> complex than is guaranteed to cause problems.
In my understanding all of this is right.
It would need however to be completed by something about v4-v6 coexistence.
What about something like: <<<
Packets the source or destination of which is IPv4 only must be: (1) in 
IPv4  on links that are IPv4-only or IPv4 and IPv6; (2) in IPv6 on 
IPv6-only links, with IPv4 addresses in mapped format.>>>

Note that, to route IPv6 packets the destination of which is mapped 
IPv4, the 0::/64 routing prefix should not be artificially considered as 
invalid by routers.

The typical case where this is useful is within multi-subnet sites where 
there are IPv6 only hosts, and where access to the IPv4 Internet is via 
  CPEs that support NATv6-v4. >>>

> I think that Itojun was right, and we should simply deprecate the
Have you a reference where he suggests to go that far?

In Itojun's document I know,
http://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-00,
the proposal, in 2003, was to avoid mapped addressses "on the wire"(not 
at socket interfaces).
As far as I know, this document became obsolete without Itojun himself 
insisting on the subject.

While it identifies some threats in some configurations, it doesn't 
conflict, in my undersatnding, with mapped addresses on the wire in some 
other useful ones.
One of these other configurations happens to be very pertinent (and IMHO 
completely Kiss :-) ) for IPv6-only client hosts to be able to reach 
IPv4-only servers.

Rémi

---

From: Christian Huitema <[email-masked]>
Date: Tue, 29 Jan 2008 06:48:35 -0800

> interface is *simpler* than obliging them to know whether the IP layer

We can debate whether that is in fact simpler. Most "simple programming" is achieved using high level constructs such as RPC or Web interfaces. The fraction of programs written on the "socket" API tend to be written by sophisticated developers who like "bare to the metal" constructs. But even if a single listening was a goal, it can be achieved without messing with address format, simply by avoiding early binding of the socket to a specific address type, and then using specific addresses in their native formats whenever necessary.

-- Christian Huitema

---

From: Rémi Després <[email-masked]>
Date: Tue, 29 Jan 2008 19:04:24 +0100

Christian Huitema wrote :

>>  interface is *simpler* than obliging them to know whether the IP 
>> layer works in IPv4 or IPv6.
> 
> We can debate whether that is in fact simpler.
Right.
In this instance, that sems useful.

> Most "simple programming" is achieved using high level constructs
> such as RPC or Web interfaces. The fraction of programs written on
> the "socket" API tend to be written by sophisticated developers who
> like "bare to the metal" constructs.
In my view, that's legitimate.
But IMO conformance to RFC 2353 sec 3.7 doesn't make dual stacks less
"bare to the metal"

> But even if a single listening was a goal,
In my reading of RFC 2335-3.7, this *was* a goal, and a good one.

> it can be achieved without messing with address format,
Listening for an address without being concerned with the remote host
being IPv6 or IPv4 only, as RFC 2353-3.7 permits, was IMO not "messing
with address formats".
Permitting to express a 32 bit address in a 128 bit format was IMO a
good and natural decision.

> simply by avoiding early binding of the socket to a specific address
> type, and then using specific addresses in their native formats
> whenever necessary.
Yes it can work.
And applications that have this behavior can keep it, even if dual
stacks do conform to RFC 2353-3.7.
But they can hardly be considered as *IPv6-only*.
IPv6-only applications *do need* RFC 2353-3.7 dual stack conformance.

Deprecating mapped addresses would be a bad step backward, while
correcting RFC2535-3.7 conformance in dual stacks that don't conform
would be a good step forward.
I would have no adverse effect that I know on any existing application.

The bottom line would be that always:
- Server applications that have IPv4 sockets, or that have unspecified
address family sockets, will receive IPv4 addresses on them.
- Server applications that only have IPv6 sockets will receive IPv4
addresses on them, in mapped format.
- Client applications that have IPv6 sockets, and present on them remote 
host addresses that are IPv4 mapped addresses will, without having to 
tell more, activate their IPv4 stacks.
This seems to me the nice and simple logic we need.

Rémi

---

From: Brian E Carpenter <[email-masked]>
Date: Wed, 30 Jan 2008 16:34:04 +1300

On 2008-01-29 22:02, Rémi Després wrote:
...
> insisting on the subject.

I don't think he changed his mind, though. And this thread started
with operational difficulties caused by such addresses in the wild.

> completely Kiss :-) ) for IPv6-only client hosts to be able to reach

There's no fundamental need for a magic prefix. Iljitsch and I will have
a combined draft out soon that will discuss this. Being able to use a
regular unicast or anycast prefix to reach the translator is more KISS
than a magic prefix, IMHO.

    Brian

---

From: Rémi Després <[email-masked]>
Date: Wed, 30 Jan 2008 09:12:59 +0100

> than a magic prefix, IMHO.

I agree that other prefixes than mapped address prefix (0::/64) can be 
proposed to go across a v6 cloud to the v4 world.
But I see them as an indirect solution to a need that can be satisfied 
with a direct one.

This "unicast OR anycast prefix" needs being invented, and specified, 
while the mapped address prefix exists already, and to my knowledge 
works nicely.

With the mapped address prefix, IPv6-only hosts that send packets to 
IPv4-only hosts have, without any address translation, the right routing 
prefix in their destination address. They are *real IPv6-only*.

It seems to me that the combined draft you work on would be 
significantly simplified (and therefore improved) if it would replace 
the "unicast OR anycast prefix" by the existing mapped address /64 prefix.
(I believe, like you and Iljitsch do, that scalable NATs between v6 and 
v4 are a useful approach for the v4-v6 coexistence period, and that for 
this they may have to be split. But I also believe that some 
improvements are still possible in this approach. Accepting and using 
the mapped address prefix would IMHO be one of them.)

Maybe I miss something, but the question is "what is it exactly?".

Rémi

---

From: Rémi Després <[email-masked]>
Date: Thu, 31 Jan 2008 15:48:37 +0100

>> layer works in IPv4 or IPv6.
Right. Let's continue to clarify the issue.

> like "bare to the metal" constructs.
In my view, that's indeed appropriate.

But IMO conformance of dual stacks to RFC 2553 sec 3.7 doesn't make them
less "bare to the metal" (it just says that a v4 destination has to be 
handled by the v4 stack if there is one operational, even if this v4 
destination is presented in 128 bit format.)

> But even if a single listening was a goal,
In my reading of RFC 2553-3.7, this *was* a goal, and a good one.

> it can be achieved without messing with address format,
For an IPv6-only application, listening for an address without being 
concerned whether the remote host is IPv4 only, as RFC 2553-3.7 permits, 
isn't IMO "messing with address formats".

On the opposite, obliging an IPv6-only application to handle in any way 
the v4 Address Family is IMU mixing levels.
Permitting to express a 32 bit address in a 128 bit format is after all 
a simple idea.

> type, and then using specific addresses in their native formats 
Yes it works but, again, these applications can hardly be considered as 
IPv6-only.(To be *really IPv6-only*, applications do need RFC 2553-3.7 
conformance of dual stacks.)
Note that applications that have this behavior, and with it work on dual 
stacks that don't conform to 2553-3.7, can keep this behavior when their 
stack is patched to conform.

In summary, dual stacks that don't conform to RFC2553-3.7 should be 
corrected :
  1. No adverse effect is predictible, on any existing application.

  2. Some weird phenomena as observed recently would no longer appear.

  3. The bottom line will be that:
- Server applications that have IPv4 sockets, or that have unspecified
address family sockets, will receive IPv4 addresses on them.
- Server applications that only have IPv6 sockets will receive IPv4
addresses in mapped format (without having to recognize them).
- Client applications that, on IPv6 sockets to dual stacks, use remote 
host addresses that happen to be IPv4 addresses automatically activate 
the IPv4 part of their dual stacks.

This seems to me the right logic to have.
Changing that would be a step backward.

Rémi

---

From: Rémi Després <[email-masked]>
Date: Thu, 31 Jan 2008 15:49:37 +0100

Rémi