various arm fixes (mostly nowarn_align)
[olsrd.git] / lib / bmf / src / Packet.c
1 /*
2  * OLSR Basic Multicast Forwarding (BMF) plugin.
3  * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
4  * Written by Erik Tromp.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without 
8  * modification, are permitted provided that the following conditions 
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright 
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright 
14  *   notice, this list of conditions and the following disclaimer in 
15  *   the documentation and/or other materials provided with the 
16  *   distribution.
17  * * Neither the name of Thales, BMF nor the names of its 
18  *   contributors may be used to endorse or promote products derived 
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
24  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
28  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /* -------------------------------------------------------------------------
34  * File       : Packet.c
35  * Description: IP packet and Ethernet frame processing functions
36  * Created    : 29 Jun 2006
37  *
38  * ------------------------------------------------------------------------- */
39
40 #include "olsr.h"
41 #include "Packet.h"
42
43 /* System includes */
44 #include <stddef.h> /* NULL */
45 #include <assert.h> /* assert() */
46 #include <string.h> /* memcpy() */
47 #include <sys/types.h> /* u_int8_t, u_int16_t, u_int32_t */
48 #include <netinet/in.h> /* ntohs(), htons() */
49 #include <netinet/ip.h> /* struct iphdr */
50
51 /* -------------------------------------------------------------------------
52  * Function   : IsIpFragment
53  * Description: Check if an IP packet is an IP fragment
54  * Input      : ipPacket - the IP packet
55  * Output     : none
56  * Return     : true (1) or false (0)
57  * Data Used  : none
58  * ------------------------------------------------------------------------- */
59 int IsIpFragment(unsigned char* ipPacket)
60 {
61   struct ip* iph;
62
63   assert(ipPacket != NULL);
64
65   iph = (struct ip*) ARM_NOWARN_ALIGN(ipPacket);
66   if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
67   {
68     return 1;
69   }
70   return 0;
71 } /* IsIpFragment */
72
73 /* -------------------------------------------------------------------------
74  * Function   : GetIpTotalLength
75  * Description: Retrieve the total length of the IP packet (in bytes) of
76  *              an IP packet
77  * Input      : ipPacket - the IP packet
78  * Output     : none
79  * Return     : IP packet length
80  * Data Used  : none
81  * ------------------------------------------------------------------------- */
82 u_int16_t GetIpTotalLength(unsigned char* ipPacket)
83 {
84   struct iphdr* iph;
85
86   assert(ipPacket != NULL);
87
88   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
89   return ntohs(iph->tot_len);
90 } /* GetIpTotalLength */
91
92 /* -------------------------------------------------------------------------
93  * Function   : GetIpHeaderLength
94  * Description: Retrieve the IP header length (in bytes) of an IP packet
95  * Input      : ipPacket - the IP packet
96  * Output     : none
97  * Return     : IP header length
98  * Data Used  : none
99  * ------------------------------------------------------------------------- */
100 unsigned int GetIpHeaderLength(unsigned char* ipPacket)
101 {
102   struct iphdr* iph;
103
104   assert(ipPacket != NULL);
105
106   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
107   return iph->ihl << 2;
108 } /* GetIpHeaderLength */
109
110 /* -------------------------------------------------------------------------
111  * Function   : GetTtl
112  * Description: Retrieve the TTL (Time To Live) value from the IP header of
113  *              an IP packet
114  * Input      : ipPacket - the IP packet
115  * Output     : none
116  * Return     : TTL value
117  * Data Used  : none
118  * ------------------------------------------------------------------------- */
119 u_int8_t GetTtl(unsigned char* ipPacket)
120 {
121   struct iphdr* iph;
122
123   assert(ipPacket != NULL);
124
125   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
126   return iph->ttl;
127 } /* GetTtl */
128
129 /* -------------------------------------------------------------------------
130  * Function   : SaveTtlAndChecksum
131  * Description: Save the TTL (Time To Live) value and IP checksum as found in
132  *              the IP header of an IP packet
133  * Input      : ipPacket - the IP packet
134  * Output     : sttl - the TTL and checksum values
135  * Return     : none
136  * Data Used  : none
137  * ------------------------------------------------------------------------- */
138 void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
139 {
140   struct iphdr* iph;
141
142   assert(ipPacket != NULL && sttl != NULL);
143
144   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
145   sttl->ttl = iph->ttl;
146   sttl->check = ntohs(iph->check);
147 } /* SaveTtlAndChecksum */
148
149 /* -------------------------------------------------------------------------
150  * Function   : RestoreTtlAndChecksum
151  * Description: Restore the TTL (Time To Live) value and IP checksum in
152  *              the IP header of an IP packet
153  * Input      : ipPacket - the IP packet
154  *              sttl - the TTL and checksum values
155  * Output     : none
156  * Return     : none
157  * Data Used  : none
158  * ------------------------------------------------------------------------- */
159 void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
160 {
161   struct iphdr* iph;
162
163   assert(ipPacket != NULL && sttl != NULL);
164
165   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
166   iph->ttl = sttl->ttl;
167   iph->check = htons(sttl->check);
168 } /* RestoreTtlAndChecksum */
169
170 /* -------------------------------------------------------------------------
171  * Function   : DecreaseTtlAndUpdateHeaderChecksum
172  * Description: For an IP packet, decrement the TTL value and update the IP header
173  *              checksum accordingly.
174  * Input      : ipPacket - the IP packet
175  * Output     : none
176  * Return     : none
177  * Data Used  : none
178  * Notes      : See also RFC1141
179  * ------------------------------------------------------------------------- */
180 void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
181 {
182   struct iphdr* iph;
183   u_int32_t sum;
184
185   assert(ipPacket != NULL);
186
187   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
188
189   iph->ttl--; /* decrement ttl */
190   sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
191   iph->check = htons(sum + (sum>>16)); /* add carry */
192 } /* DecreaseTtlAndUpdateHeaderChecksum */
193
194 /* -------------------------------------------------------------------------
195  * Function   : GetIpHeader
196  * Description: Retrieve the IP header from BMF encapsulation UDP data
197  * Input      : encapsulationUdpData - the encapsulation UDP data
198  * Output     : none
199  * Return     : IP header
200  * Data Used  : none
201  * ------------------------------------------------------------------------- */
202 struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
203 {
204   return (struct ip*) ARM_NOWARN_ALIGN((encapsulationUdpData + ENCAP_HDR_LEN));
205 } /* GetIpHeader */
206
207 /* -------------------------------------------------------------------------
208  * Function   : GetIpPacket
209  * Description: Retrieve the IP packet from BMF encapsulation UDP data
210  * Input      : encapsulationUdpData - the encapsulation UDP data
211  * Output     : none
212  * Return     : The IP packet
213  * Data Used  : none
214  * ------------------------------------------------------------------------- */
215 unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
216 {
217   return encapsulationUdpData + ENCAP_HDR_LEN;
218 } /* GetIpPacket */
219
220 /* -------------------------------------------------------------------------
221  * Function   : GetEncapsulationUdpDataLength
222  * Description: Return the length of BMF encapsulation UDP data
223  * Input      : encapsulationUdpData - the encapsulation UDP data
224  * Output     : none
225  * Return     : The encapsulation data length
226  * Data Used  : none
227  * ------------------------------------------------------------------------- */
228 u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData)
229 {
230   return GetIpTotalLength(GetIpPacket(encapsulationUdpData)) + ENCAP_HDR_LEN;
231 } /* GetEncapsulationUdpDataLength */
232