Merge pull request #78 from ffontaine/master
[olsrd.git] / lib / p2pd / 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 #include "olsr.h"
47 #include "Packet.h"
48
49 /* System includes */
50 #include <stddef.h>             /* NULL */
51 #include <assert.h>             /* assert() */
52 #include <string.h>             /* memcpy() */
53 #include <sys/types.h>          /* u_int8_t, u_int16_t, u_int32_t */
54 #include <netinet/in.h>         /* ntohs(), htons() */
55 #include <netinet/ip.h>         /* struct iphdr */
56
57 /* -------------------------------------------------------------------------
58  * Function   : IsIpFragment
59  * Description: Check if an IP packet is an IP fragment
60  * Input      : ipPacket - the IP packet
61  * Output     : none
62  * Return     : true (1) or false (0)
63  * Data Used  : none
64  * ------------------------------------------------------------------------- */
65 int IsIpFragment(unsigned char* ipPacket)
66 {
67   struct ip* iph;
68
69   assert(ipPacket != NULL);
70
71   iph = (struct ip*) ARM_NOWARN_ALIGN(ipPacket);
72   if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
73   {
74     return 1;
75   }
76   return 0;
77 } /* IsIpFragment */
78
79 /* -------------------------------------------------------------------------
80  * Function   : GetIpTotalLength
81  * Description: Retrieve the total length of the IP packet (in bytes) of
82  *              an IP packet
83  * Input      : ipPacket - the IP packet
84  * Output     : none
85  * Return     : IP packet length
86  * Data Used  : none
87  * ------------------------------------------------------------------------- */
88 u_int16_t GetIpTotalLength(unsigned char* ipPacket)
89 {
90   struct iphdr* iph;
91
92   assert(ipPacket != NULL);
93
94   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
95   return ntohs(iph->tot_len);
96 } /* GetIpTotalLength */
97
98 /* -------------------------------------------------------------------------
99  * Function   : IsIpv4Fragment
100  * Description: Check if an IP packet is an IP fragment
101  * Input      : ipPacket - the IP packet
102  * Output     : none
103  * Return     : true (1) or false (0)
104  * Data Used  : none
105  * ------------------------------------------------------------------------- */
106 int IsIpv4Fragment(struct ip* hdr)
107 {
108   assert(hdr != NULL);
109
110   if ((ntohs(hdr->ip_off) & IP_OFFMASK) != 0)
111   {
112     return 1;
113   }
114   return 0;
115 } /* IsIpv4Fragment */
116
117 int IsMulticastv4(struct ip* hdr)
118 {
119   assert(hdr != NULL);
120
121   if (IN_MULTICAST(ntohl(hdr->ip_dst.s_addr)))
122           return 1;
123   
124   return 0;
125 }
126
127
128 /* -------------------------------------------------------------------------
129  * Function   : IsIpv6Fragment
130  * Description: Check if an IP packet is an IP fragment
131  * Input      : ipPacket - the IP packet
132  * Output     : none
133  * Return     : true (1) or false (0)
134  * Data Used  : none
135  * ------------------------------------------------------------------------- */
136 int IsIpv6Fragment(struct ip6_hdr* hdr __attribute__ ((unused)))
137 {
138   assert(hdr != NULL);
139   
140 //#error Implementation required
141   if (0)
142     return 1;
143     
144   return 0;
145 }
146
147 int IsMulticastv6(struct ip6_hdr* hdr __attribute__ ((unused)))
148 {
149   assert(hdr != NULL);
150
151
152   return 0;
153 }
154
155 /* -------------------------------------------------------------------------
156  * Function   : GetIpHeaderLength
157  * Description: Retrieve the IP header length (in bytes) of an IP packet
158  * Input      : ipPacket - the IP packet
159  * Output     : none
160  * Return     : IP header length
161  * Data Used  : none
162  * ------------------------------------------------------------------------- */
163 unsigned int
164 GetIpHeaderLength(unsigned char *ipPacket)
165 {
166   struct iphdr *iph;
167
168   assert(ipPacket != NULL);
169
170   iph = (struct iphdr *) ARM_NOWARN_ALIGN(ipPacket);
171   return iph->ihl << 2;
172 }                               /* GetIpHeaderLength */
173
174 /* -------------------------------------------------------------------------
175  * Function   : GetIpPacket
176  * Description: Retrieve the IP packet from BMF encapsulation UDP data
177  * Input      : encapsulationUdpData - the encapsulation UDP data
178  * Output     : none
179  * Return     : The IP packet
180  * Data Used  : none
181  * ------------------------------------------------------------------------- */
182 unsigned char *
183 GetIpPacket(unsigned char *encapsulationUdpData)
184 {
185   return encapsulationUdpData + ENCAP_HDR_LEN;
186 }                               /* GetIpPacket */
187
188 /* -------------------------------------------------------------------------
189  * Function   : GetTtl
190  * Description: Retrieve the TTL (Time To Live) value from the IP header of
191  *              an IP packet
192  * Input      : ipPacket - the IP packet
193  * Output     : none
194  * Return     : TTL value
195  * Data Used  : none
196  * ------------------------------------------------------------------------- */
197 u_int8_t GetTtl(unsigned char* ipPacket)
198 {
199   struct iphdr* iph;
200
201   assert(ipPacket != NULL);
202
203   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
204   return iph->ttl;
205 } /* GetTtl */
206
207 /* -------------------------------------------------------------------------
208  * Function   : SaveTtlAndChecksum
209  * Description: Save the TTL (Time To Live) value and IP checksum as found in
210  *              the IP header of an IP packet
211  * Input      : ipPacket - the IP packet
212  * Output     : sttl - the TTL and checksum values
213  * Return     : none
214  * Data Used  : none
215  * ------------------------------------------------------------------------- */
216 void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
217 {
218   struct iphdr* iph;
219
220   assert(ipPacket != NULL && sttl != NULL);
221
222   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
223   sttl->ttl = iph->ttl;
224   sttl->check = ntohs(iph->check);
225 } /* SaveTtlAndChecksum */
226
227 /* -------------------------------------------------------------------------
228  * Function   : RestoreTtlAndChecksum
229  * Description: Restore the TTL (Time To Live) value and IP checksum in
230  *              the IP header of an IP packet
231  * Input      : ipPacket - the IP packet
232  *              sttl - the TTL and checksum values
233  * Output     : none
234  * Return     : none
235  * Data Used  : none
236  * ------------------------------------------------------------------------- */
237 void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
238 {
239   struct iphdr* iph;
240
241   assert(ipPacket != NULL && sttl != NULL);
242
243   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
244   iph->ttl = sttl->ttl;
245   iph->check = htons(sttl->check);
246 } /* RestoreTtlAndChecksum */
247
248 /* -------------------------------------------------------------------------
249  * Function   : DecreaseTtlAndUpdateHeaderChecksum
250  * Description: For an IP packet, decrement the TTL value and update the IP header
251  *              checksum accordingly.
252  * Input      : ipPacket - the IP packet
253  * Output     : none
254  * Return     : none
255  * Data Used  : none
256  * Notes      : See also RFC1141
257  * ------------------------------------------------------------------------- */
258 void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
259 {
260   struct iphdr* iph;
261   u_int32_t sum;
262
263   assert(ipPacket != NULL);
264
265   iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
266
267   iph->ttl--; /* decrement ttl */
268   sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
269   iph->check = htons(sum + (sum>>16)); /* add carry */
270 } /* DecreaseTtlAndUpdateHeaderChecksum */
271
272
273
274
275 /*
276  * Local Variables:
277  * c-basic-offset: 2
278  * indent-tabs-mode: nil
279  * End:
280  */