source: lib/protocols_ospf.c @ f6f3ae5

develop
Last change on this file since f6f3ae5 was f6f3ae5, checked in by Jacob Van Walraven <jcv9@…>, 2 years ago

Assertion cleanup

  • Property mode set to 100644
File size: 11.2 KB
Line 
1/*
2 *
3 * Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
4 * All rights reserved.
5 *
6 * This file is part of libtrace.
7 *
8 * This code has been developed by the University of Waikato WAND
9 * research group. For further information please see http://www.wand.net.nz/
10 *
11 * libtrace is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * libtrace is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 *
24 *
25 */
26#include "libtrace_int.h"
27#include "libtrace.h"
28#include "protocols.h"
29#include <assert.h>
30#include <stdlib.h>
31#include <stdio.h> // fprintf
32
33DLLEXPORT void *trace_get_ospf_header(libtrace_packet_t *packet,
34                uint8_t *version, uint32_t *remaining) {
35        uint8_t proto;
36        void *ospf;
37        uint32_t dummy_rem = 0;
38
39
40        if (!remaining)
41                remaining = &dummy_rem;
42
43        if (!packet) {
44                fprintf(stderr, "NULL packet passed into trace_get_ospf_version()\n");
45                return NULL;
46        }
47        /*assert(version != NULL && "version may not be NULL when calling trace_get_ospf_header!");*/
48        if (!version) {
49                fprintf(stderr, "NULL version passed into trace_get_ospf_version()\n");
50                return NULL;
51        }
52
53        ospf = trace_get_transport(packet, &proto, remaining);
54
55        if (!ospf || proto != TRACE_IPPROTO_OSPF || *remaining == 0)
56                return NULL;
57
58        *version = *((uint8_t *)ospf);
59
60        if (*version == 2 && *remaining < sizeof(libtrace_ospf_v2_t))
61                return NULL;
62
63        return ospf;
64}
65
66DLLEXPORT void *trace_get_ospf_contents_v2(libtrace_ospf_v2_t *header,
67                uint8_t *ospf_type, uint32_t *remaining) {
68
69        uint8_t dummy_type;
70        char *ptr;
71
72        /*assert(remaining != NULL && "remaining may not be NULL when calling trace_get_ospf_contents!");*/
73        if (!remaining) {
74                fprintf(stderr, "Remaining may not be NULL when calling trace_get_ospf_contents()\n");
75                return NULL;
76        }
77        if (!header) {
78                fprintf(stderr, "Header may not be NULL when calling trace_get_ospf_contents()\n");
79                return NULL;
80        }
81
82        if (!ospf_type)
83                ospf_type = &dummy_type;
84
85        if (*remaining < sizeof(libtrace_ospf_v2_t)) {
86                *ospf_type = 0;
87                *remaining = 0;
88                fprintf(stderr, "Remaining may not be less than the size of libtrace_ospf_v2_t when calling trace_get_ospf_contents()\n");
89                return NULL;
90        }
91
92        *ospf_type = header->type;
93
94        ptr = ((char *)header) + sizeof(libtrace_ospf_v2_t);
95        *remaining -= sizeof(libtrace_ospf_v2_t);
96
97        return (void *)ptr;
98
99}
100
101DLLEXPORT unsigned char *trace_get_first_ospf_link_from_router_lsa_v2(
102                libtrace_ospf_router_lsa_v2_t *lsa,
103                uint32_t *remaining) {
104
105        unsigned char *link_ptr = NULL;
106        /*assert(remaining != NULL && "remaining may not be NULL when calling trace_get_first_link_from_router_lsa_v2!");*/
107        if (!remaining) {
108                fprintf(stderr, "Remaining may not be NULL when calling trace_get_first_link_from_router_lsa_v2()\n");
109                return NULL;
110        }
111        if (!lsa) {
112                fprintf(stderr, "NULL lsa passed into trace_get_first_link_from_router_lsa_v2()\n");
113                return NULL;
114        }
115
116        if (*remaining < sizeof(libtrace_ospf_router_lsa_v2_t)) {
117                *remaining = 0;
118                fprintf(stderr, "Remaining may not be less than the size of libtrace_ospf_router_lsa_v2_t when calling trace_get_first_ospf_link_from_router_lsa_v2()\n");
119                return NULL;
120        }
121
122        link_ptr = ((unsigned char *)lsa) + sizeof(libtrace_ospf_router_lsa_v2_t);
123        *remaining -= sizeof(libtrace_ospf_router_lsa_v2_t);
124        return link_ptr;
125
126}
127
128DLLEXPORT unsigned char *trace_get_first_ospf_lsa_from_db_desc_v2(
129                libtrace_ospf_db_desc_v2_t *db_desc,
130                uint32_t *remaining) {
131
132        unsigned char *lsa_ptr = NULL;
133
134        /*assert(remaining != NULL && "remaining may not be NULL when calling trace_get_first_ospf_v2_lsa!");*/
135        if (!remaining) {
136                fprintf(stderr, "Remaining may not be NULL when calling trace_get_first_ospf_v2_lsa()\n");
137                return NULL;
138        }
139        if (!db_desc) {
140                fprintf(stderr, "db_desc may not be NULL when calling trace_get_first_ospf_v2_lsa()\n");
141                return NULL;
142        }
143
144        if (*remaining < sizeof(libtrace_ospf_db_desc_v2_t)) {
145                *remaining = 0;
146                fprintf(stderr, "Remaining may not be less than the size of libtrace_ospf_db_desc_v2_t when calling trace_get_first_ospf_lsa_from_db_desc_v2()\n");
147                return NULL;
148        }
149
150        lsa_ptr = ((unsigned char *)db_desc) + sizeof(libtrace_ospf_db_desc_v2_t);
151        *remaining -= sizeof(libtrace_ospf_db_desc_v2_t);
152
153        return lsa_ptr;
154}
155
156DLLEXPORT unsigned char *trace_get_first_ospf_lsa_from_update_v2(
157                libtrace_ospf_ls_update_t *ls_update,
158                uint32_t *remaining) {
159
160        unsigned char *lsa_ptr = NULL;
161
162        /*assert(remaining != NULL && "remaining may not be NULL when calling trace_get_first_ospf_v2_lsa!");*/
163        if (!remaining) {
164                fprintf(stderr, "Remaining may not be NULL when calling trace_get_first_ospf_v2_lsa()\n");
165                return NULL;
166        }
167        if (!ls_update) {
168                fprintf(stderr, "ls_update may not be NULL when calling trace_get_first_ospf_v2_lsa()\n");
169                return NULL;
170        }
171
172        if (*remaining < sizeof(libtrace_ospf_ls_update_t)) {
173                *remaining = 0;
174                fprintf(stderr, "Remaining may not be less than the size of an ls_update when calling trace_get_first_ospf_v2_lsa()\n");
175                return NULL;
176        }
177
178        lsa_ptr = ((unsigned char *)ls_update) + sizeof(libtrace_ospf_ls_update_t);
179        *remaining -= sizeof(libtrace_ospf_ls_update_t);
180
181        return lsa_ptr;
182}
183
184DLLEXPORT uint32_t trace_get_ospf_metric_from_as_external_lsa_v2(
185                libtrace_ospf_as_external_lsa_v2_t *as_lsa) {
186
187        uint32_t metric = 0;
188
189        /*assert(as_lsa);*/
190        if (!as_lsa) {
191                fprintf(stderr, "NULL as_lsa passed into trace_get_ospf_metric_from_as_external_lsa_v2()\n");
192                /* Return metric of 0 on error? */
193                return metric;
194        }
195
196        metric = as_lsa->metric_a << 16;
197        metric |= (as_lsa->metric_b << 8);
198        metric |= as_lsa->metric_c;
199
200        return metric;
201}
202
203DLLEXPORT uint32_t trace_get_ospf_metric_from_summary_lsa_v2(
204                libtrace_ospf_summary_lsa_v2_t *sum_lsa) {
205
206        uint32_t metric = 0;
207
208        /*assert(sum_lsa);*/
209        if (!sum_lsa) {
210                fprintf(stderr, "NULL sum_lsa passed into trace_get_ospf_metric_from_summary_lsa_v2()\n");
211                /* Return metric of 0 on error? */
212                return metric;
213        }
214
215        metric = sum_lsa->metric_a << 16;
216        metric |= (sum_lsa->metric_b << 8);
217        metric |= sum_lsa->metric_c;
218
219        return metric;
220}
221
222DLLEXPORT int trace_get_next_ospf_link_v2(unsigned char **current,
223                libtrace_ospf_link_v2_t **link,
224                uint32_t *remaining,
225                uint32_t *link_len) {
226
227        if (*current == NULL || *remaining < sizeof(libtrace_ospf_link_v2_t)) {
228                *remaining = 0;
229                *link = NULL;
230                return 0;
231        }
232
233        *link = (libtrace_ospf_link_v2_t *)*current;
234
235        /* XXX The spec allows for multiple metrics for a single link. This
236         * approach won't support this, so we may need to be more intelligent
237         * about this in future */
238        *remaining -= sizeof(libtrace_ospf_link_v2_t);
239        *link_len = sizeof(libtrace_ospf_link_v2_t);
240        *current += sizeof(libtrace_ospf_link_v2_t);
241
242        return 1;
243
244}
245
246DLLEXPORT int trace_get_next_ospf_lsa_header_v2(unsigned char **current,
247                libtrace_ospf_lsa_v2_t **lsa_hdr,
248                uint32_t *remaining,
249                uint8_t *lsa_type,
250                uint16_t *lsa_length) {
251
252        int valid_lsa = 0;
253
254        if (*current == NULL || *remaining < sizeof(libtrace_ospf_lsa_v2_t)) {
255                *lsa_hdr = NULL;
256                *remaining = 0;
257                return 0;
258
259        }
260
261        *lsa_hdr = (libtrace_ospf_lsa_v2_t *)(*current);
262
263        /* Check that the LSA type is valid */
264        switch ((*lsa_hdr)->lsa_type) {
265                case TRACE_OSPF_LS_ROUTER:
266                case TRACE_OSPF_LS_NETWORK:
267                case TRACE_OSPF_LS_SUMMARY:
268                case TRACE_OSPF_LS_ASBR_SUMMARY:
269                case TRACE_OSPF_LS_EXTERNAL:
270                        valid_lsa = 1;
271                        break;
272        }
273
274        /* This function is for reading LSA headers only, e.g. those in DB desc
275         * or LS Ack packets. As such, I'm going to set the type and length to
276         * values that should prevent anyone from trying to treat subsequent
277         * payload as an LSA body */
278        *lsa_type = 0;
279        *lsa_length = sizeof(libtrace_ospf_lsa_v2_t);
280
281        if (!valid_lsa) {
282                *remaining = 0;
283                return -1;
284        }
285
286        *remaining -= *lsa_length;
287        *current += *lsa_length;
288
289        if (remaining == 0) {
290                /* No more LSAs */
291                return 0;
292        }
293        return 1;
294}
295
296DLLEXPORT int trace_get_next_ospf_lsa_v2(unsigned char **current,
297                libtrace_ospf_lsa_v2_t **lsa_hdr,
298                unsigned char **lsa_body,
299                uint32_t *remaining,
300                uint8_t *lsa_type,
301                uint16_t *lsa_length) {
302
303        int valid_lsa = 0;
304
305        if (*current == NULL || *remaining < sizeof(libtrace_ospf_lsa_v2_t)) {
306                *lsa_hdr = NULL;
307                *lsa_body = NULL;
308                *remaining = 0;
309
310                return 0;
311
312        }
313
314        *lsa_hdr = (libtrace_ospf_lsa_v2_t *)(*current);
315        *lsa_type = (*lsa_hdr)->lsa_type;
316        *lsa_length = ntohs((*lsa_hdr)->length);
317
318        /* Check that the LSA type is valid */
319        switch (*lsa_type) {
320                case TRACE_OSPF_LS_ROUTER:
321                case TRACE_OSPF_LS_NETWORK:
322                case TRACE_OSPF_LS_SUMMARY:
323                case TRACE_OSPF_LS_ASBR_SUMMARY:
324                case TRACE_OSPF_LS_EXTERNAL:
325                        valid_lsa = 1;
326                        break;
327        }
328
329        if (*lsa_length > *remaining || !valid_lsa) {
330                /* LSA is incomplete or an invalid type.
331                 *
332                 * If this occurs, you've probably managed to read something
333                 * that is NOT a legit LSA */
334                *remaining = 0;
335                *lsa_body = NULL;
336                return -1;
337        }
338
339        /* Some OSPF packets, e.g. LS ACKs, only contain LSA headers. If this
340         * is the case, we'll set the body pointer to NULL so the caller
341         * can't read invalid data */
342        if (*lsa_length == sizeof(libtrace_ospf_lsa_v2_t))
343                *lsa_body = NULL;
344        else
345                *lsa_body = (*current + sizeof(libtrace_ospf_lsa_v2_t));
346
347        *remaining -= *lsa_length;
348        *current += *lsa_length;
349
350        if (remaining == 0) {
351                /* No more LSAs */
352                return 0;
353        }
354
355        return 1;
356
357}
358
359
Note: See TracBrowser for help on using the repository browser.