7612b61775459e2abe77ddce2ef2e006b8da1532
[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 "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*) 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*) ipPacket;
89   return ntohs(iph->tot_len);
90 } /* GetIpTotalLength */
91
92 /* -------------------------------------------------------------------------
93  * Function   : IsIpv4Fragment
94  * Description: Check if an IP packet is an IP fragment
95  * Input      : ipPacket - the IP packet
96  * Output     : none
97  * Return     : true (1) or false (0)
98  * Data Used  : none
99  * ------------------------------------------------------------------------- */
100 int IsIpv4Fragment(struct ip* hdr)
101 {
102   assert(hdr != NULL);
103
104   if ((ntohs(hdr->ip_off) & IP_OFFMASK) != 0)
105   {
106     return 1;
107   }
108   return 0;
109 } /* IsIpv4Fragment */
110
111 int IsMulticastv4(struct ip* hdr)
112 {
113   uint32_t addr;
114
115   assert(hdr != NULL);
116
117   memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));
118   if ((addr & 0xE0000000) == 0xE0000000)
119     return 1;
120   
121   return 0;
122 }
123
124 int IsBroadcast(struct ip* hdr)
125 {
126   uint32_t addr;
127
128   assert(hdr != NULL);
129
130   memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));
131   if (addr == 0xFFFFFFFF)
132     return 1;
133     
134   return 0;
135 }
136
137 /* -------------------------------------------------------------------------
138  * Function   : IsIpv6Fragment
139  * Description: Check if an IP packet is an IP fragment
140  * Input      : ipPacket - the IP packet
141  * Output     : none
142  * Return     : true (1) or false (0)
143  * Data Used  : none
144  * ------------------------------------------------------------------------- */
145 int IsIpv6Fragment(struct ip6_hdr* hdr __attribute__ ((unused)))
146 {
147   assert(hdr != NULL);
148   
149 //#error Implementation required
150   if (0)
151     return 1;
152     
153   return 0;
154 }
155
156 int IsMulticastv6(struct ip6_hdr* hdr __attribute__ ((unused)))
157 {
158   assert(hdr != NULL);
159
160
161   return 0;
162 }
163
164 /* -------------------------------------------------------------------------
165  * Function   : GetIpHeaderLength
166  * Description: Retrieve the IP header length (in bytes) of an IP packet
167  * Input      : ipPacket - the IP packet
168  * Output     : none
169  * Return     : IP header length
170  * Data Used  : none
171  * ------------------------------------------------------------------------- */
172 unsigned int
173 GetIpHeaderLength(unsigned char *ipPacket)
174 {
175   struct iphdr *iph;
176
177   assert(ipPacket != NULL);
178
179   iph = (struct iphdr *)ipPacket;
180   return iph->ihl << 2;
181 }                               /* GetIpHeaderLength */
182
183 /* -------------------------------------------------------------------------
184  * Function   : GetIpPacket
185  * Description: Retrieve the IP packet from BMF encapsulation UDP data
186  * Input      : encapsulationUdpData - the encapsulation UDP data
187  * Output     : none
188  * Return     : The IP packet
189  * Data Used  : none
190  * ------------------------------------------------------------------------- */
191 unsigned char *
192 GetIpPacket(unsigned char *encapsulationUdpData)
193 {
194   return encapsulationUdpData + ENCAP_HDR_LEN;
195 }                               /* GetIpPacket */
196
197 /* -------------------------------------------------------------------------
198  * Function   : GetTtl
199  * Description: Retrieve the TTL (Time To Live) value from the IP header of
200  *              an IP packet
201  * Input      : ipPacket - the IP packet
202  * Output     : none
203  * Return     : TTL value
204  * Data Used  : none
205  * ------------------------------------------------------------------------- */
206 u_int8_t GetTtl(unsigned char* ipPacket)
207 {
208   struct iphdr* iph;
209
210   assert(ipPacket != NULL);
211
212   iph = (struct iphdr*) ipPacket;
213   return iph->ttl;
214 } /* GetTtl */
215
216 /* -------------------------------------------------------------------------
217  * Function   : SaveTtlAndChecksum
218  * Description: Save the TTL (Time To Live) value and IP checksum as found in
219  *              the IP header of an IP packet
220  * Input      : ipPacket - the IP packet
221  * Output     : sttl - the TTL and checksum values
222  * Return     : none
223  * Data Used  : none
224  * ------------------------------------------------------------------------- */
225 void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
226 {
227   struct iphdr* iph;
228
229   assert(ipPacket != NULL && sttl != NULL);
230
231   iph = (struct iphdr*) ipPacket;
232   sttl->ttl = iph->ttl;
233   sttl->check = ntohs(iph->check);
234 } /* SaveTtlAndChecksum */
235
236 /* -------------------------------------------------------------------------
237  * Function   : RestoreTtlAndChecksum
238  * Description: Restore the TTL (Time To Live) value and IP checksum in
239  *              the IP header of an IP packet
240  * Input      : ipPacket - the IP packet
241  *              sttl - the TTL and checksum values
242  * Output     : none
243  * Return     : none
244  * Data Used  : none
245  * ------------------------------------------------------------------------- */
246 void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
247 {
248   struct iphdr* iph;
249
250   assert(ipPacket != NULL && sttl != NULL);
251
252   iph = (struct iphdr*) ipPacket;
253   iph->ttl = sttl->ttl;
254   iph->check = htons(sttl->check);
255 } /* RestoreTtlAndChecksum */
256
257 /* -------------------------------------------------------------------------
258  * Function   : DecreaseTtlAndUpdateHeaderChecksum
259  * Description: For an IP packet, decrement the TTL value and update the IP header
260  *              checksum accordingly.
261  * Input      : ipPacket - the IP packet
262  * Output     : none
263  * Return     : none
264  * Data Used  : none
265  * Notes      : See also RFC1141
266  * ------------------------------------------------------------------------- */
267 void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
268 {
269   struct iphdr* iph;
270   u_int32_t sum;
271
272   assert(ipPacket != NULL);
273
274   iph = (struct iphdr*) ipPacket;
275
276   iph->ttl--; /* decrement ttl */
277   sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
278   iph->check = htons(sum + (sum>>16)); /* add carry */
279 } /* DecreaseTtlAndUpdateHeaderChecksum */
280
281
282
283
284 /*
285  * Local Variables:
286  * c-basic-offset: 2
287  * indent-tabs-mode: nil
288  * End:
289  */