source: lib/protocols_ospf.c @ 21c0d70

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 21c0d70 was d8b05b7, checked in by Shane Alcock <salcock@…>, 6 years ago

Make sure our copyright covers recent years

Consistency across all of our source files is also nice.

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