Skip to content

Commit 98a54db

Browse files
committed
nat64: Handle IPv6 addresses using "Well-Known Prefix" 64:ff9b::/96
1 parent 2cee62e commit 98a54db

File tree

1 file changed

+95
-6
lines changed

1 file changed

+95
-6
lines changed

core/net/ip/ip64-addr.c

+95-6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,61 @@
3636

3737
#define printf(...)
3838
/*---------------------------------------------------------------------------*/
39+
static int
40+
ip64_addr_ipv4_is_private(const uip_ip4addr_t *ipv4addr)
41+
{
42+
uip_ipaddr_t ipaddr, mask;
43+
44+
/* 10.0.0.0/8 */
45+
uip_ipaddr(&ipaddr, 10, 0, 0, 0);
46+
uip_ipaddr(&mask, 255, 0, 0, 0);
47+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
48+
return 1;
49+
}
50+
51+
/* 172.16.0.0/12 */
52+
uip_ipaddr(&ipaddr, 172, 16, 0, 0);
53+
uip_ipaddr(&mask, 255, 240, 0, 0);
54+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
55+
return 1;
56+
}
57+
58+
/* 198.18.0.0/15 */
59+
uip_ipaddr(&ipaddr, 198, 18, 0, 0);
60+
uip_ipaddr(&mask, 255, 254, 0, 0);
61+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
62+
return 1;
63+
}
64+
65+
/* 192.168.0.0/16 */
66+
uip_ipaddr(&ipaddr, 192, 168, 0, 0);
67+
uip_ipaddr(&mask, 255, 255, 0, 0);
68+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
69+
return 1;
70+
}
71+
72+
/* 192.0.2.0/24 */
73+
uip_ipaddr(&ipaddr, 192, 0, 2, 0);
74+
uip_ipaddr(&mask, 255, 255, 255, 0);
75+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
76+
return 1;
77+
}
78+
79+
/* 198.51.100.0/24 */
80+
uip_ipaddr(&ipaddr, 198, 51, 100, 0);
81+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
82+
return 1;
83+
}
84+
85+
/* 203.0.113.0/24 */
86+
uip_ipaddr(&ipaddr, 203, 0, 113, 0);
87+
if(uip_ipaddr_maskcmp(ipv4addr, &ipaddr, &mask)) {
88+
return 1;
89+
}
90+
91+
return 0;
92+
}
93+
/*---------------------------------------------------------------------------*/
3994
void
4095
ip64_addr_copy4(uip_ip4addr_t *dest, const uip_ip4addr_t *src)
4196
{
@@ -50,7 +105,7 @@ ip64_addr_copy6(uip_ip6addr_t *dest, const uip_ip6addr_t *src)
50105
/*---------------------------------------------------------------------------*/
51106
int
52107
ip64_addr_4to6(const uip_ip4addr_t *ipv4addr,
53-
uip_ip6addr_t *ipv6addr)
108+
uip_ip6addr_t *ipv6addr)
54109
{
55110
/* This function converts an IPv4 addresses into an IPv6
56111
addresses. It returns 0 if it failed to convert the address and
@@ -75,16 +130,16 @@ ip64_addr_4to6(const uip_ip4addr_t *ipv4addr,
75130
ipv6addr->u8[14] = ipv4addr->u8[2];
76131
ipv6addr->u8[15] = ipv4addr->u8[3];
77132
printf("ip64_addr_4to6: IPv6-encoded IPv4 address %d.%d.%d.%d\n",
78-
ipv4addr->u8[0], ipv4addr->u8[1],
79-
ipv4addr->u8[2], ipv4addr->u8[3]);
133+
ipv4addr->u8[0], ipv4addr->u8[1],
134+
ipv4addr->u8[2], ipv4addr->u8[3]);
80135

81136
/* Conversion succeeded, we return non-zero. */
82137
return 1;
83138
}
84139
/*---------------------------------------------------------------------------*/
85140
int
86141
ip64_addr_6to4(const uip_ip6addr_t *ipv6addr,
87-
uip_ip4addr_t *ipv4addr)
142+
uip_ip4addr_t *ipv4addr)
88143
{
89144
/* This function converts IPv6 addresses to IPv4 addresses. It
90145
returns 0 if it failed to convert the address and non-zero if it
@@ -105,17 +160,51 @@ ip64_addr_6to4(const uip_ip6addr_t *ipv6addr,
105160
ipv6addr->u8[9] == 0 &&
106161
ipv6addr->u8[10] == 0xff &&
107162
ipv6addr->u8[11] == 0xff) {
163+
108164
ipv4addr->u8[0] = ipv6addr->u8[12];
109165
ipv4addr->u8[1] = ipv6addr->u8[13];
110166
ipv4addr->u8[2] = ipv6addr->u8[14];
111167
ipv4addr->u8[3] = ipv6addr->u8[15];
112168

113169
printf("ip64_addr_6to4: IPv6-encoded IPv4 address %d.%d.%d.%d\n",
114-
ipv4addr->u8[0], ipv4addr->u8[1],
115-
ipv4addr->u8[2], ipv4addr->u8[3]);
170+
ipv4addr->u8[0], ipv4addr->u8[1],
171+
ipv4addr->u8[2], ipv4addr->u8[3]);
116172

117173
/* Conversion succeeded, we return non-zero. */
118174
return 1;
175+
} else if(ipv6addr->u8[0] == 00 &&
176+
ipv6addr->u8[1] == 0x64 &&
177+
ipv6addr->u8[2] == 0xff &&
178+
ipv6addr->u8[3] == 0x9b &&
179+
ipv6addr->u8[4] == 0 &&
180+
ipv6addr->u8[5] == 0 &&
181+
ipv6addr->u8[6] == 0 &&
182+
ipv6addr->u8[7] == 0 &&
183+
ipv6addr->u8[8] == 0 &&
184+
ipv6addr->u8[9] == 0 &&
185+
ipv6addr->u8[10] == 0 &&
186+
ipv6addr->u8[11] == 0) {
187+
188+
/*
189+
* Handle IPv6 addresses using the "Well-Know Prefix" 64:ff9b::/96.
190+
* Not allowed for private (RFC1918) IPv4 addresses as per RFC 6052.
191+
*/
192+
193+
ipv4addr->u8[0] = ipv6addr->u8[12];
194+
ipv4addr->u8[1] = ipv6addr->u8[13];
195+
ipv4addr->u8[2] = ipv6addr->u8[14];
196+
ipv4addr->u8[3] = ipv6addr->u8[15];
197+
198+
if(!ip64_addr_ipv4_is_private(ipv4addr)) {
199+
printf("ip64_addr_6to4: IPv6-encoded IPv4 address %d.%d.%d.%d\n",
200+
ipv4addr->u8[0], ipv4addr->u8[1],
201+
ipv4addr->u8[2], ipv4addr->u8[3]);
202+
/* Conversion succeeded, we return non-zero. */
203+
return 1;
204+
} else {
205+
/* WKP not allowed for private IPv4 addresses. Drop the packet */
206+
printf("ip64_addr_6to4: WKP not allowed for private IPv4 address\n");
207+
}
119208
}
120209
/* We could not convert the IPv6 address, so we return 0. */
121210
return 0;

0 commit comments

Comments
 (0)