fix chillispot endianness bugs (thx, SeG), fixes #2404
authorFelix Fietkau <nbd@openwrt.org>
Wed, 26 Sep 2007 21:34:16 +0000 (21:34 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 26 Sep 2007 21:34:16 +0000 (21:34 +0000)
SVN-Revision: 9041

net/chillispot/patches/001-endian_fix.patch [new file with mode: 0644]

diff --git a/net/chillispot/patches/001-endian_fix.patch b/net/chillispot/patches/001-endian_fix.patch
new file mode 100644 (file)
index 0000000..7bc100e
--- /dev/null
@@ -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 <endian.h>
++
+ /* 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;