1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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;
|