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