ROHC compression/decompression library
crc.h
Go to the documentation of this file.
1 /*
2  * Copyright 2007,2008 CNES
3  * Copyright 2011,2012,2013 Didier Barvaux
4  * Copyright 2007,2008 Thales Alenia Space
5  * Copyright 2009,2010 Thales Communications
6  * Copyright 2007,2009,2010,2012,2013 Viveris Technologies
7  * Copyright 2012 WBX
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file crc.h
26  * @brief ROHC CRC routines
27  * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com>
28  * @author Didier Barvaux <didier@barvaux.org>
29  * @author FWX <rohc_team@dialine.fr>
30  */
31 
32 #ifndef ROHC_COMMON_CRC_H
33 #define ROHC_COMMON_CRC_H
34 
35 #include "ip.h"
36 #include "protocols/udp.h"
37 #include "protocols/rtp.h"
38 #include "protocols/esp.h"
39 #include "protocols/tcp.h"
40 
41 #include <stdbool.h>
42 
43 /// The CRC-3 initial value
44 #define CRC_INIT_3 0x7
45 /// The CRC-7 initial value
46 #define CRC_INIT_7 0x7f
47 /// The CRC-8 initial value
48 #define CRC_INIT_8 0xff
49 
50 /** The FCS-32 initial value */
51 #define CRC_INIT_FCS32 0xffffffff
52 /** The length (in bytes) of the FCS-32 CRC */
53 #define CRC_FCS32_LEN 4U
54 
55 /** The different types of CRC used to protect ROHC headers */
56 typedef enum
57 {
58  ROHC_CRC_TYPE_NONE = 0, /**< No CRC selected */
59  ROHC_CRC_TYPE_3 = 3, /**< The CRC-3 type */
60  ROHC_CRC_TYPE_7 = 7, /**< The CRC-7 type */
61  ROHC_CRC_TYPE_8 = 8, /**< The CRC-8 type */
63 
64 
65 /*
66  * Function prototypes.
67  */
68 
69 void rohc_crc_init_table(uint8_t *const table,
70  const rohc_crc_type_t crc_type)
71  __attribute__((nonnull(1)));
72 
73 uint8_t crc_calculate(const rohc_crc_type_t crc_type,
74  const uint8_t *const data,
75  const size_t length,
76  const uint8_t init_val,
77  const uint8_t *const crc_table)
78  __attribute__((nonnull(2, 5), warn_unused_result));
79 
80 uint32_t crc_calc_fcs32(const uint8_t *const data,
81  const size_t length,
82  const uint32_t init_val)
83  __attribute__((nonnull(1), warn_unused_result, pure));
84 
85 uint8_t compute_crc_static(const uint8_t *const outer_ip,
86  const uint8_t *const inner_ip,
87  const uint8_t *const next_header,
88  const rohc_crc_type_t crc_type,
89  const uint8_t init_val,
90  const uint8_t *const crc_table)
91  __attribute__((nonnull(1, 6), warn_unused_result));
92 uint8_t compute_crc_dynamic(const uint8_t *const outer_ip,
93  const uint8_t *const inner_ip,
94  const uint8_t *const next_header,
95  const rohc_crc_type_t crc_type,
96  const uint8_t init_val,
97  const uint8_t *const crc_table)
98  __attribute__((nonnull(1, 6), warn_unused_result));
99 
100 static inline
101 uint8_t udp_compute_crc_static(const uint8_t *const outer_ip,
102  const uint8_t *const inner_ip,
103  const uint8_t *const next_header,
104  const rohc_crc_type_t crc_type,
105  const uint8_t init_val,
106  const uint8_t *const crc_table)
107  __attribute__((nonnull(1, 3, 6), warn_unused_result));
108 static inline
109 uint8_t udp_compute_crc_dynamic(const uint8_t *const outer_ip,
110  const uint8_t *const inner_ip,
111  const uint8_t *const next_header,
112  const rohc_crc_type_t crc_type,
113  const uint8_t init_val,
114  const uint8_t *const crc_table)
115  __attribute__((nonnull(1, 3, 6), warn_unused_result));
116 
117 static inline
118 uint8_t esp_compute_crc_static(const uint8_t *const outer_ip,
119  const uint8_t *const inner_ip,
120  const uint8_t *const next_header,
121  const rohc_crc_type_t crc_type,
122  const uint8_t init_val,
123  const uint8_t *const crc_table)
124  __attribute__((nonnull(1, 3, 6), warn_unused_result));
125 static inline
126 uint8_t esp_compute_crc_dynamic(const uint8_t *const outer_ip,
127  const uint8_t *const inner_ip,
128  const uint8_t *const next_header,
129  const rohc_crc_type_t crc_type,
130  const uint8_t init_val,
131  const uint8_t *const crc_table)
132  __attribute__((nonnull(1, 3, 6), warn_unused_result));
133 
134 static inline
135 uint8_t rtp_compute_crc_static(const uint8_t *const outer_ip,
136  const uint8_t *const inner_ip,
137  const uint8_t *const next_header,
138  const rohc_crc_type_t crc_type,
139  const uint8_t init_val,
140  const uint8_t *const crc_table)
141  __attribute__((nonnull(1, 3, 6), warn_unused_result));
142 static inline
143 uint8_t rtp_compute_crc_dynamic(const uint8_t *const outer_ip,
144  const uint8_t *const inner_ip,
145  const uint8_t *const next_header,
146  const rohc_crc_type_t crc_type,
147  const uint8_t init_val,
148  const uint8_t *const crc_table)
149  __attribute__((nonnull(1, 3, 6), warn_unused_result));
150 
151 /**
152  * @brief Compute the CRC-STATIC part of an UDP or UDP-Lite header
153  *
154  * Concerned fields are:
155  * all fields expect those for CRC-DYNAMIC
156  * - bytes 1-4 in original UDP header
157  *
158  * @param outer_ip The outer IP packet
159  * @param inner_ip The inner IP packet if there is 2 IP headers, NULL otherwise
160  * @param next_header The next header located after the IP header(s)
161  * @param crc_type The type of CRC
162  * @param init_val The initial CRC value
163  * @param crc_table The pre-computed table for fast CRC computation
164  * @return The checksum
165  */
166 static inline
167 uint8_t udp_compute_crc_static(const uint8_t *const outer_ip,
168  const uint8_t *const inner_ip,
169  const uint8_t *const next_header,
170  const rohc_crc_type_t crc_type,
171  const uint8_t init_val,
172  const uint8_t *const crc_table)
173 {
174  uint8_t crc = init_val;
175  const struct udphdr *udp;
176 
177  /* compute the CRC-STATIC value for IP and IP2 headers */
178  crc = compute_crc_static(outer_ip, inner_ip, next_header,
179  crc_type, crc, crc_table);
180 
181  /* get the start of UDP header */
182  udp = (struct udphdr *) next_header;
183 
184  /* bytes 1-4 (Source Port, Destination Port) */
185  crc = crc_calculate(crc_type, (uint8_t *)(&udp->source), 4,
186  crc, crc_table);
187 
188  return crc;
189 }
190 
191 
192 /**
193  * @brief Compute the CRC-DYNAMIC part of an UDP or UDP-Lite header
194  *
195  * Concerned fields are:
196  * - bytes 5-6, 7-8 in original UDP header
197  *
198  * @param outer_ip The outer IP packet
199  * @param inner_ip The inner IP packet if there is 2 IP headers, NULL otherwise
200  * @param next_header The next header located after the IP header(s)
201  * @param crc_type The type of CRC
202  * @param init_val The initial CRC value
203  * @param crc_table The pre-computed table for fast CRC computation
204  * @return The checksum
205  */
206 static inline
207 uint8_t udp_compute_crc_dynamic(const uint8_t *const outer_ip,
208  const uint8_t *const inner_ip,
209  const uint8_t *const next_header,
210  const rohc_crc_type_t crc_type,
211  const uint8_t init_val,
212  const uint8_t *const crc_table)
213 {
214  uint8_t crc = init_val;
215  const struct udphdr *udp;
216 
217  /* compute the CRC-DYNAMIC value for IP and IP2 headers */
218  crc = compute_crc_dynamic(outer_ip, inner_ip, next_header,
219  crc_type, crc, crc_table);
220 
221  /* get the start of UDP header */
222  udp = (struct udphdr *) next_header;
223 
224  /* bytes 5-8 (Length, Checksum) */
225  crc = crc_calculate(crc_type, (uint8_t *)(&udp->len), 4,
226  crc, crc_table);
227 
228  return crc;
229 }
230 
231 
232 /**
233  * @brief Compute the CRC-STATIC part of an ESP header
234  *
235  * Concerned fields are:
236  * all fields expect those for CRC-DYNAMIC
237  * - bytes 1-4 in original ESP header
238  *
239  * @param outer_ip The outer IP packet
240  * @param inner_ip The inner IP packet if there is 2 IP headers, NULL otherwise
241  * @param next_header The next header located after the IP header(s)
242  * @param crc_type The type of CRC
243  * @param init_val The initial CRC value
244  * @param crc_table The pre-computed table for fast CRC computation
245  * @return The checksum
246  */
247 static inline
248 uint8_t esp_compute_crc_static(const uint8_t *const outer_ip,
249  const uint8_t *const inner_ip,
250  const uint8_t *const next_header,
251  const rohc_crc_type_t crc_type,
252  const uint8_t init_val,
253  const uint8_t *const crc_table)
254 {
255  uint8_t crc = init_val;
256  const struct esphdr *esp;
257 
258  /* compute the CRC-STATIC value for IP and IP2 headers */
259  crc = compute_crc_static(outer_ip, inner_ip, next_header,
260  crc_type, crc, crc_table);
261 
262  /* get the start of ESP header */
263  esp = (struct esphdr *) next_header;
264 
265  /* bytes 1-4 (Security parameters index) */
266  crc = crc_calculate(crc_type, (uint8_t *)(&esp->spi), 4,
267  crc, crc_table);
268 
269  return crc;
270 }
271 
272 
273 /**
274  * @brief Compute the CRC-DYNAMIC part of an ESP header
275  *
276  * Concerned fields are:
277  * - bytes 5-8 in original ESP header
278  *
279  * @param outer_ip The outer IP packet
280  * @param inner_ip The inner IP packet if there is 2 IP headers, NULL otherwise
281  * @param next_header The next header located after the IP header(s)
282  * @param crc_type The type of CRC
283  * @param init_val The initial CRC value
284  * @param crc_table The pre-computed table for fast CRC computation
285  * @return The checksum
286  */
287 static inline
288 uint8_t esp_compute_crc_dynamic(const uint8_t *const outer_ip,
289  const uint8_t *const inner_ip,
290  const uint8_t *const next_header,
291  const rohc_crc_type_t crc_type,
292  const uint8_t init_val,
293  const uint8_t *const crc_table)
294 {
295  uint8_t crc = init_val;
296  const struct esphdr *esp;
297 
298  /* compute the CRC-DYNAMIC value for IP and IP2 headers */
299  crc = compute_crc_dynamic(outer_ip, inner_ip, next_header,
300  crc_type, crc, crc_table);
301 
302  /* get the start of ESP header */
303  esp = (struct esphdr *) next_header;
304 
305  /* bytes 5-8 (Sequence number) */
306  crc = crc_calculate(crc_type, (uint8_t *)(&esp->sn), 4,
307  crc, crc_table);
308 
309  return crc;
310 }
311 
312 
313 /**
314  * @brief Compute the CRC-STATIC part of a RTP header
315  *
316  * Concerned fields are:
317  * all fields expect those for CRC-DYNAMIC
318  * - bytes 1, 9-12 (and CSRC list) in original RTP header
319  *
320  * @param outer_ip The outer IP packet
321  * @param inner_ip The inner IP packet if there is 2 IP headers, NULL otherwise
322  * @param next_header The next header located after the IP header(s)
323  * @param crc_type The type of CRC
324  * @param init_val The initial CRC value
325  * @param crc_table The pre-computed table for fast CRC computation
326  * @return The checksum
327  */
328 static inline
329 uint8_t rtp_compute_crc_static(const uint8_t *const outer_ip,
330  const uint8_t *const inner_ip,
331  const uint8_t *const next_header,
332  const rohc_crc_type_t crc_type,
333  const uint8_t init_val,
334  const uint8_t *const crc_table)
335 {
336  uint8_t crc = init_val;
337  const struct rtphdr *rtp;
338 
339  /* compute the CRC-STATIC value for IP, IP2 and UDP headers */
340  crc = udp_compute_crc_static(outer_ip, inner_ip, next_header,
341  crc_type, crc, crc_table);
342 
343  /* get the start of RTP header */
344  rtp = (struct rtphdr *) (next_header + sizeof(struct udphdr));
345 
346  /* byte 1 (Version, P, X, CC) */
347  crc = crc_calculate(crc_type, (uint8_t *)rtp, 1, crc, crc_table);
348 
349  /* bytes 9-12 (SSRC identifier) */
350  crc = crc_calculate(crc_type, (uint8_t *)(&rtp->ssrc), 4,
351  crc, crc_table);
352 
353  /* TODO: CSRC identifiers */
354 
355  return crc;
356 }
357 
358 
359 /**
360  * @brief Compute the CRC-DYNAMIC part of a RTP header
361  *
362  * Concerned fields are:
363  * - bytes 2, 3-4, 5-8 in original RTP header
364  *
365  * @param outer_ip The outer IP packet
366  * @param inner_ip The inner IP packet if there is 2 IP headers, NULL otherwise
367  * @param next_header The next header located after the IP header(s)
368  * @param crc_type The type of CRC
369  * @param init_val The initial CRC value
370  * @param crc_table The pre-computed table for fast CRC computation
371  * @return The checksum
372  */
373 static inline
374 uint8_t rtp_compute_crc_dynamic(const uint8_t *const outer_ip,
375  const uint8_t *const inner_ip,
376  const uint8_t *const next_header,
377  const rohc_crc_type_t crc_type,
378  const uint8_t init_val,
379  const uint8_t *const crc_table)
380 {
381  uint8_t crc = init_val;
382  const struct rtphdr *rtp;
383 
384  /* compute the CRC-DYNAMIC value for IP, IP2 and UDP headers */
385  crc = udp_compute_crc_dynamic(outer_ip, inner_ip, next_header,
386  crc_type, crc, crc_table);
387 
388  /* get the start of RTP header */
389  rtp = (struct rtphdr *) (next_header + sizeof(struct udphdr));
390 
391  /* bytes 2-8 (Marker, Payload Type, Sequence Number, Timestamp) */
392  crc = crc_calculate(crc_type, ((uint8_t *) rtp) + 1, 7,
393  crc, crc_table);
394 
395  return crc;
396 }
397 
398 
399 
400 #endif
401 
uint16_t len
Definition: udp.h:42
IP-agnostic packet.
uint8_t crc_calculate(const rohc_crc_type_t crc_type, const uint8_t *const data, const size_t length, const uint8_t init_val, const uint8_t *const crc_table)
Calculate the checksum for the given data.
Definition: crc.c:223
ESP header description.
uint32_t sn
Definition: esp.h:43
Definition: udp.h:38
uint32_t spi
Definition: esp.h:42
uint8_t compute_crc_static(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-STATIC part of an IP header.
Definition: crc.c:298
The RTP header.
Definition: rtp.h:48
static uint8_t esp_compute_crc_dynamic(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-DYNAMIC part of an ESP header.
Definition: crc.h:288
static uint8_t udp_compute_crc_static(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-STATIC part of an UDP or UDP-Lite header.
Definition: crc.h:167
Definition: crc.h:60
rohc_crc_type_t
Definition: crc.h:56
uint8_t compute_crc_dynamic(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-DYNAMIC part of an IP header.
Definition: crc.c:391
Definition: crc.h:59
static uint8_t rtp_compute_crc_dynamic(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-DYNAMIC part of a RTP header.
Definition: crc.h:374
static uint8_t udp_compute_crc_dynamic(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-DYNAMIC part of an UDP or UDP-Lite header.
Definition: crc.h:207
RTP header.
Definition: esp.h:40
Definition: crc.h:58
void rohc_crc_init_table(uint8_t *const table, const rohc_crc_type_t crc_type)
Initialize a CRC table given a 256-byte table and the CRC type to use.
Definition: crc.c:176
static uint8_t esp_compute_crc_static(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-STATIC part of an ESP header.
Definition: crc.h:248
Definition: crc.h:61
RTP header.
static uint8_t rtp_compute_crc_static(const uint8_t *const outer_ip, const uint8_t *const inner_ip, const uint8_t *const next_header, const rohc_crc_type_t crc_type, const uint8_t init_val, const uint8_t *const crc_table)
Compute the CRC-STATIC part of a RTP header.
Definition: crc.h:329
uint16_t source
Definition: udp.h:40
TCP header description.
Defines the UDP header.
uint32_t crc_calc_fcs32(const uint8_t *const data, const size_t length, const uint32_t init_val)
Optimized CRC FCS-32 calculation using a table.
Definition: crc.c:263