various arm fixes (mostly nowarn_align)
[olsrd.git] / lib / p2pd / src / Packet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include "olsr.h"
42 #include "Packet.h"
43
44 /* System includes */
45 #include <stddef.h>             /* NULL */
46 #include <assert.h>             /* assert() */
47 #include <string.h>             /* memcpy() */
48 #include <sys/types.h>          /* u_int8_t, u_int16_t, u_int32_t */
49 #include <netinet/in.h>         /* ntohs(), htons() */
50 #include <netinet/ip.h>         /* struct iphdr */
51
52 /* -------------------------------------------------------------------------
53  * Function   : IsIpFragment
54  * Description: Check if an IP packet is an IP fragment
55  * Input      : ipPacket - the IP packet
56  * Output     : none
57  * Return     : true (1) or false (0)
58  * Data Used  : none
59  * ------------------------------------------------------------------------- */
60 int IsIpFragment(unsigned char* ipPacket)
61 {
62   struct ip* iph;
63
64   assert(ipPacket != NULL);
65
66   iph = (struct ip*) ARM_NOWARN_ALIGN(ipPacket);
67   if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
68   {
69     return 1;
70   }
71   return 0;
72 } /* IsIpFragment */
73
74 /* -------------------------------------------------------------------------
75  * Function   : GetIpTotalLength
76  * Description: Retrieve the total length of the IP packet (in bytes) of
77  *              an IP packet
78  * Input      : ipPacket - the IP packet
79  * Output     : none
80  * Return     : IP packet length
81  * Data Used  : none
82  * ------------------------------------------------------------------------- */
83 u_int16_t GetIpTotalLength(unsigned char* ipPacket)
84 {
85   struct iphdr* iph;
86
87   assert(ipPacket != NULL);
88
89   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
90   return ntohs(iph->tot_len);
91 } /* GetIpTotalLength */
92
93 /* -------------------------------------------------------------------------
94  * Function   : IsIpv4Fragment
95  * Description: Check if an IP packet is an IP fragment
96  * Input      : ipPacket - the IP packet
97  * Output     : none
98  * Return     : true (1) or false (0)
99  * Data Used  : none
100  * ------------------------------------------------------------------------- */
101 int IsIpv4Fragment(struct ip* hdr)
102 {
103   assert(hdr != NULL);
104
105   if ((ntohs(hdr->ip_off) & IP_OFFMASK) != 0)
106   {
107     return 1;
108   }
109   return 0;
110 } /* IsIpv4Fragment */
111
112 int IsMulticastv4(struct ip* hdr)
113 {
114   uint32_t addr;
115
116   assert(hdr != NULL);
117
118   memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));
119   if ((addr & 0xE0000000) == 0xE0000000)
120     return 1;
121   
122   return 0;
123 }
124
125 int IsBroadcast(struct ip* hdr)
126 {
127   uint32_t addr;
128
129   assert(hdr != NULL);
130
131   memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));
132   if (addr == 0xFFFFFFFF)
133     return 1;
134     
135   return 0;
136 }
137
138 /* -------------------------------------------------------------------------
139  * Function   : IsIpv6Fragment
140  * Description: Check if an IP packet is an IP fragment
141  * Input      : ipPacket - the IP packet
142  * Output     : none
143  * Return     : true (1) or false (0)
144  * Data Used  : none
145  * ------------------------------------------------------------------------- */
146 int IsIpv6Fragment(struct ip6_hdr* hdr __attribute__ ((unused)))
147 {
148   assert(hdr != NULL);
149   
150 //#error Implementation required
151   if (0)
152     return 1;
153     
154   return 0;
155 }
156
157 int IsMulticastv6(struct ip6_hdr* hdr __attribute__ ((unused)))
158 {
159   assert(hdr != NULL);
160
161
162   return 0;
163 }
164
165 /* -------------------------------------------------------------------------
166  * Function   : GetIpHeaderLength
167  * Description: Retrieve the IP header length (in bytes) of an IP packet
168  * Input      : ipPacket - the IP packet
169  * Output     : none
170  * Return     : IP header length
171  * Data Used  : none
172  * ------------------------------------------------------------------------- */
173 unsigned int
174 GetIpHeaderLength(unsigned char *ipPacket)
175 {
176   struct iphdr *iph;
177
178   assert(ipPacket != NULL);
179
180   iph = (struct iphdr *) ARM_NOWARN_ALIGN(ipPacket);
181   return iph->ihl << 2;
182 }                               /* GetIpHeaderLength */
183
184 /* -------------------------------------------------------------------------
185  * Function   : GetIpPacket
186  * Description: Retrieve the IP packet from BMF encapsulation UDP data
187  * Input      : encapsulationUdpData - the encapsulation UDP data
188  * Output     : none
189  * Return     : The IP packet
190  * Data Used  : none
191  * ------------------------------------------------------------------------- */
192 unsigned char *
193 GetIpPacket(unsigned char *encapsulationUdpData)
194 {
195   return encapsulationUdpData + ENCAP_HDR_LEN;
196 }                               /* GetIpPacket */
197
198 /* -------------------------------------------------------------------------
199  * Function   : GetTtl
200  * Description: Retrieve the TTL (Time To Live) value from the IP header of
201  *              an IP packet
202  * Input      : ipPacket - the IP packet
203  * Output     : none
204  * Return     : TTL value
205  * Data Used  : none
206  * ------------------------------------------------------------------------- */
207 u_int8_t GetTtl(unsigned char* ipPacket)
208 {
209   struct iphdr* iph;
210
211   assert(ipPacket != NULL);
212
213   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
214   return iph->ttl;
215 } /* GetTtl */
216
217 /* -------------------------------------------------------------------------
218  * Function   : SaveTtlAndChecksum
219  * Description: Save the TTL (Time To Live) value and IP checksum as found in
220  *              the IP header of an IP packet
221  * Input      : ipPacket - the IP packet
222  * Output     : sttl - the TTL and checksum values
223  * Return     : none
224  * Data Used  : none
225  * ------------------------------------------------------------------------- */
226 void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
227 {
228   struct iphdr* iph;
229
230   assert(ipPacket != NULL && sttl != NULL);
231
232   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
233   sttl->ttl = iph->ttl;
234   sttl->check = ntohs(iph->check);
235 } /* SaveTtlAndChecksum */
236
237 /* -------------------------------------------------------------------------
238  * Function   : RestoreTtlAndChecksum
239  * Description: Restore the TTL (Time To Live) value and IP checksum in
240  *              the IP header of an IP packet
241  * Input      : ipPacket - the IP packet
242  *              sttl - the TTL and checksum values
243  * Output     : none
244  * Return     : none
245  * Data Used  : none
246  * ------------------------------------------------------------------------- */
247 void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
248 {
249   struct iphdr* iph;
250
251   assert(ipPacket != NULL && sttl != NULL);
252
253   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
254   iph->ttl = sttl->ttl;
255   iph->check = htons(sttl->check);
256 } /* RestoreTtlAndChecksum */
257
258 /* -------------------------------------------------------------------------
259  * Function   : DecreaseTtlAndUpdateHeaderChecksum
260  * Description: For an IP packet, decrement the TTL value and update the IP header
261  *              checksum accordingly.
262  * Input      : ipPacket - the IP packet
263  * Output     : none
264  * Return     : none
265  * Data Used  : none
266  * Notes      : See also RFC1141
267  * ------------------------------------------------------------------------- */
268 void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
269 {
270   struct iphdr* iph;
271   u_int32_t sum;
272
273   assert(ipPacket != NULL);
274
275   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
276
277   iph->ttl--; /* decrement ttl */
278   sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
279   iph->check = htons(sum + (sum>>16)); /* add carry */
280 } /* DecreaseTtlAndUpdateHeaderChecksum */
281
282
283
284
285 /*
286  * Local Variables:
287  * c-basic-offset: 2
288  * indent-tabs-mode: nil
289  * End:
290  */