From 1e3c114d655f65dfc3528b1d8884a026ba8bad6b Mon Sep 17 00:00:00 2001
From: Gert Doering <gert@greenie.muc.de>
Date: Sat, 28 May 2011 22:50:40 +0200
Subject: [PATCH] Replace 32-bit-based add_in6_addr() implementation by an 8-bit based one
- windows has no 32-bit accessor to the union inside "struct in6_addr",
and the 8-bit accessor is the only common denominator across BSD, Solaris,
Linux and Windows...
Signed-off-by: Gert Doering <gert@greenie.muc.de>
---
socket.c | 34 ++++++++++++++++------------------
1 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/socket.c b/socket.c
index 6b855c0..7903c26 100644
a
|
b
|
print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc) |
2619 | 2619 | return BSTR (&out); |
2620 | 2620 | } |
2621 | 2621 | |
| 2622 | #ifndef UINT8_MAX |
| 2623 | # define UINT8_MAX 0xff |
| 2624 | #endif |
| 2625 | |
2622 | 2626 | /* add some offset to an ipv6 address |
2623 | | * (add in steps of 32 bits, taking overflow into next round) |
| 2627 | * (add in steps of 8 bits, taking overflow into next round) |
2624 | 2628 | */ |
2625 | | #ifndef s6_addr32 |
2626 | | # ifdef TARGET_SOLARIS |
2627 | | # define s6_addr32 _S6_un._S6_u32 |
2628 | | # else |
2629 | | # define s6_addr32 __u6_addr.__u6_addr32 |
2630 | | # endif |
2631 | | #endif |
2632 | | #ifndef UINT32_MAX |
2633 | | # define UINT32_MAX (4294967295U) |
2634 | | #endif |
2635 | 2629 | struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add ) |
2636 | 2630 | { |
2637 | 2631 | int i; |
2638 | | uint32_t h; |
2639 | 2632 | |
2640 | | for( i=3; i>=0 && add > 0 ; i-- ) |
| 2633 | for( i=15; i>=0 && add > 0 ; i-- ) |
2641 | 2634 | { |
2642 | | h = ntohl( base.s6_addr32[i] ); |
2643 | | base.s6_addr32[i] = htonl( (h+add) & UINT32_MAX ); |
2644 | | /* 32-bit overrun? |
2645 | | * caveat: can't do "h+add > UINT32_MAX" with 32bit math! |
| 2635 | register int carry; |
| 2636 | register uint32_t h; |
| 2637 | |
| 2638 | h = (unsigned char) base.s6_addr[i]; |
| 2639 | base.s6_addr[i] = (h+add) & UINT8_MAX; |
| 2640 | |
| 2641 | /* using explicit carry for the 8-bit additions will catch |
| 2642 | * 8-bit and(!) 32-bit overruns nicely |
2646 | 2643 | */ |
2647 | | add = ( h > UINT32_MAX - add )? 1: 0; |
| 2644 | carry = ((h & 0xff) + (add & 0xff)) >> 8; |
| 2645 | add = (add>>8) + carry; |
2648 | 2646 | } |
2649 | 2647 | return base; |
2650 | 2648 | } |