summaryrefslogtreecommitdiffstats
path: root/ip6t_NPTV6_common.h
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2011-11-10 23:03:45 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2011-11-10 23:03:45 +0100
commit0d03a6f3467d93f1ae7b04e3fed6fc11a1a9f9e4 (patch)
tree1f9150119579ec4f981beaf7446fe29c9e539e5b /ip6t_NPTV6_common.h
parent8790aa53a3d0959ba318fea1ecb9de5a4de4cac5 (diff)
downloadNPTv6-0d03a6f3467d93f1ae7b04e3fed6fc11a1a9f9e4.tar
NPTv6-0d03a6f3467d93f1ae7b04e3fed6fc11a1a9f9e4.zip
Add ICMP errors for untranslatable addresses
Diffstat (limited to 'ip6t_NPTV6_common.h')
-rw-r--r--ip6t_NPTV6_common.h38
1 files changed, 21 insertions, 17 deletions
diff --git a/ip6t_NPTV6_common.h b/ip6t_NPTV6_common.h
index 86b297c..9b3aa6f 100644
--- a/ip6t_NPTV6_common.h
+++ b/ip6t_NPTV6_common.h
@@ -44,8 +44,26 @@ static inline u_int16_t add16(u_int16_t a, u_int16_t b)
static bool translate_address(struct in6_addr *addr, const struct in6_addr *prefix, u_int16_t plen) {
u_int16_t csum = 0;
int o = plen / 16, b = plen % 16;
+ int fix_word;
int i;
+ /* Fix checksum like specified in RFC 6296 */
+ if (plen <= 48) {
+ fix_word = 3;
+ }
+ else {
+ for (fix_word = (plen+15)/16; fix_word < 7; fix_word++) {
+ if (addr->s6_addr16[fix_word] != 0xffff)
+ break;
+ }
+ }
+
+ if (addr->s6_addr16[fix_word] == 0xffff) {
+ /* Fail before the address is translated so the ICMP error can be sent */
+ return false;
+ }
+
+
for (i = 0; i < o; i++) {
csum = add16(csum, addr->s6_addr16[i]);
csum = add16(csum, ~prefix->s6_addr16[i]);
@@ -62,24 +80,10 @@ static bool translate_address(struct in6_addr *addr, const struct in6_addr *pref
addr->s6_addr16[o] |= (prefix->s6_addr16[o] & bmask);
}
- /* Fix checksum like specified in RFC 6296 */
- if (plen <= 48) {
- i = 3;
- }
- else {
- for (i = (plen+15)/16; i < 7; i++) {
- if (addr->s6_addr16[i] != 0xffff)
- break;
- }
- }
-
- if (addr->s6_addr16[i] == 0xffff) {
- return false;
- }
- addr->s6_addr16[i] = add16(addr->s6_addr16[i], csum);
- if (addr->s6_addr16[i] == 0xffff) {
- addr->s6_addr16[i] = 0;
+ addr->s6_addr16[fix_word] = add16(addr->s6_addr16[fix_word], csum);
+ if (addr->s6_addr16[fix_word] == 0xffff) {
+ addr->s6_addr16[fix_word] = 0;
}
return true;