From 029eb64be975ef0b3a16888b6e19c899f0d96735 Mon Sep 17 00:00:00 2001 From: nbd Date: Wed, 26 Sep 2007 21:34:16 +0000 Subject: [PATCH] fix chillispot endianness bugs (thx, SeG), fixes #2404 git-svn-id: svn://svn.openwrt.org/openwrt/packages@9041 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- net/chillispot/patches/001-endian_fix.patch | 135 ++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 net/chillispot/patches/001-endian_fix.patch diff --git a/net/chillispot/patches/001-endian_fix.patch b/net/chillispot/patches/001-endian_fix.patch new file mode 100644 index 000000000..7bc100e6f --- /dev/null +++ b/net/chillispot/patches/001-endian_fix.patch @@ -0,0 +1,135 @@ +Index: chillispot-1.1.0/src/dhcp.c +=================================================================== +--- chillispot-1.1.0.orig/src/dhcp.c 2006-09-24 19:48:25.000000000 +0200 ++++ chillispot-1.1.0/src/dhcp.c 2007-09-25 15:35:12.521055038 +0200 +@@ -116,6 +116,24 @@ + #endif + + ++/* ++ * BrainSlayer: ++ * wrapper for fixing the big endian bugs within dhcp server code.its surelly not the best. ++ * all dhcp packet fields must be handled in little endian ++ */ ++ ++static uint16_t swap16(uint16_t word) { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned char low = word>>8; ++ unsigned char high = word&0xff; ++ return ((uint16_t)(high<<8))|low; ++#elif __BYTE_ORDER == __LITTLE_ENDIAN ++ return word; ++#else ++#error "Could not determine the system's endianness" ++#endif ++} ++ + /** + * dhcp_ip_check() + * Generates an IPv4 header checksum. +@@ -125,11 +143,11 @@ + uint32_t sum = 0; + pack->iph.check = 0; + for (i=0; i<(pack->iph.ihl * 2); i++) { +- sum += ((uint16_t*) &pack->iph)[i]; ++ sum += swap16(((uint16_t*) &pack->iph)[i]); /* brainslayer */ + } + while (sum>>16) + sum = (sum & 0xFFFF)+(sum >> 16); +- pack->iph.check = ~sum; ++ pack->iph.check = swap16(~sum); /* brainslayer */ + return 0; + } + +@@ -152,27 +170,28 @@ + } + + /* Sum UDP header and payload */ ++ + for (i=0; i<(udp_len/2); i++) { +- sum += ((uint16_t*) &pack->udph)[i]; ++ sum += swap16(((uint16_t*) &pack->udph)[i]); /* brainslayer */ + } + +- /* Sum any uneven payload octet */ ++ + if (udp_len & 0x01) { + sum += ((uint8_t*) &pack->udph)[udp_len-1]; + } + + /* Sum both source and destination address */ + for (i=0; i<4; i++) { +- sum += ((uint16_t*) &pack->iph.saddr)[i]; ++ sum += swap16(((uint16_t*) &pack->iph.saddr)[i]); /* brainslayer */ + } + + /* Sum both protocol and udp_len (again) */ +- sum = sum + pack->udph.len + ((pack->iph.protocol<<8)&0xFF00); ++ sum = sum + swap16(pack->udph.len) + ((pack->iph.protocol<<8)&0xFF00); /* brainslayer */ + + while (sum>>16) + sum = (sum & 0xFFFF)+(sum >> 16); + +- pack->udph.check = ~sum; ++ pack->udph.check = swap16(~sum); /* brainslayer */ + + return 0; + } +@@ -201,7 +220,7 @@ + + /* Sum TCP header and payload */ + for (i=0; i<(tcp_len/2); i++) { +- sum += ((uint16_t*) pack->payload)[i]; ++ sum += swap16(((uint16_t*) pack->payload)[i]); /* brainslayer */ + } + + /* Sum any uneven payload octet */ +@@ -211,16 +230,16 @@ + + /* Sum both source and destination address */ + for (i=0; i<4; i++) { +- sum += ((uint16_t*) &pack->iph.saddr)[i]; ++ sum += swap16(((uint16_t*) &pack->iph.saddr)[i]); /* brainslayer */ + } + + /* Sum both protocol and tcp_len */ +- sum = sum + htons(tcp_len) + ((pack->iph.protocol<<8)&0xFF00); ++ sum = sum + swap16(htons(tcp_len)) + ((pack->iph.protocol<<8)&0xFF00); /* brainslayer */ + + while (sum>>16) + sum = (sum & 0xFFFF)+(sum >> 16); + +- tcph->check = ~sum; ++ tcph->check = swap16(~sum); /* brainslayer */ + + return 0; + } +Index: chillispot-1.1.0/src/dhcp.h +=================================================================== +--- chillispot-1.1.0.orig/src/dhcp.h 2006-09-24 19:48:25.000000000 +0200 ++++ chillispot-1.1.0/src/dhcp.h 2007-09-25 15:35:12.533055724 +0200 +@@ -119,6 +119,8 @@ + uint16_t prot; + }; + ++#include ++ + /* Constants for IP packet */ + #define DHCP_IP_ALEN 4 + #define DHCP_IP_HLEN 20 +@@ -127,8 +129,15 @@ + #define DHCP_IP_UDP 17 /* UDP Protocol number */ + + struct dhcp_iphdr_t { ++#if __BYTE_ORDER == __LITTLE_ENDIAN /* nbd fix for swapped version and length field */ + uint8_t ihl:4; + uint8_t version:4; ++#elif __BYTE_ORDER == __BIG_ENDIAN ++ uint8_t version:4; ++ uint8_t ihl:4; ++#else ++#error "Could not determine the system's endianness" ++#endif + uint8_t tos; + uint16_t tot_len; + uint16_t id;