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