source: lib/protocols_ospf.c @ ee6e802

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ee6e802 was ee6e802, checked in by Shane Alcock <salcock@…>, 4 years ago

Updated copyright blurb on all source files

In some cases, this meant adding copyright blurbs to files that
had never had them before.

  • Property mode set to 100644
File size: 9.1 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        assert(version != NULL && "version may not be NULL when calling trace_get_ospf_header!");
44
45        ospf = trace_get_transport(packet, &proto, remaining);
46
47        if (!ospf || proto != TRACE_IPPROTO_OSPF || *remaining == 0)
48                return NULL;
49
50        *version = *((uint8_t *)ospf);
51
52        if (*version == 2 && *remaining < sizeof(libtrace_ospf_v2_t))
53                return NULL;
54
55        return ospf;
56}
57
58DLLEXPORT void *trace_get_ospf_contents_v2(libtrace_ospf_v2_t *header,
59                uint8_t *ospf_type, uint32_t *remaining) {
60
61        uint8_t dummy_type;
62        char *ptr;
63
64        assert(remaining != NULL && "remaining may not be NULL when calling trace_get_ospf_contents!");
65
66        if (!ospf_type)
67                ospf_type = &dummy_type;
68
69        if (!header || *remaining < sizeof(libtrace_ospf_v2_t)) {
70                *ospf_type = 0;
71                *remaining = 0;
72                return NULL;
73        }
74
75        *ospf_type = header->type;
76
77        ptr = ((char *)header) + sizeof(libtrace_ospf_v2_t);
78        *remaining -= sizeof(libtrace_ospf_v2_t);
79
80        return (void *)ptr;
81
82}
83
84DLLEXPORT unsigned char *trace_get_first_ospf_link_from_router_lsa_v2(
85                libtrace_ospf_router_lsa_v2_t *lsa,
86                uint32_t *remaining) {
87
88        unsigned char *link_ptr = NULL;
89        assert(remaining != NULL && "remaining may not be NULL when calling trace_get_first_link_from_router_lsa_v2!");
90
91        if (!lsa || *remaining < sizeof(libtrace_ospf_router_lsa_v2_t)) {
92                *remaining = 0;
93                return NULL;
94        }
95
96        link_ptr = ((unsigned char *)lsa) + sizeof(libtrace_ospf_router_lsa_v2_t);
97        *remaining -= sizeof(libtrace_ospf_router_lsa_v2_t);
98        return link_ptr;
99
100}
101
102DLLEXPORT unsigned char *trace_get_first_ospf_lsa_from_db_desc_v2(
103                libtrace_ospf_db_desc_v2_t *db_desc,
104                uint32_t *remaining) {
105
106        unsigned char *lsa_ptr = NULL;
107
108        assert(remaining != NULL && "remaining may not be NULL when calling trace_get_first_ospf_v2_lsa!");
109
110        if (!db_desc || *remaining < sizeof(libtrace_ospf_db_desc_v2_t)) {
111                *remaining = 0;
112                return NULL;
113        }
114
115        lsa_ptr = ((unsigned char *)db_desc) + sizeof(libtrace_ospf_db_desc_v2_t);
116        *remaining -= sizeof(libtrace_ospf_db_desc_v2_t);
117
118        return lsa_ptr;
119}
120
121DLLEXPORT unsigned char *trace_get_first_ospf_lsa_from_update_v2(
122                libtrace_ospf_ls_update_t *ls_update,
123                uint32_t *remaining) {
124
125        unsigned char *lsa_ptr = NULL;
126
127        assert(remaining != NULL && "remaining may not be NULL when calling trace_get_first_ospf_v2_lsa!");
128
129        if (!ls_update || *remaining < sizeof(libtrace_ospf_ls_update_t)) {
130                *remaining = 0;
131                return NULL;
132        }
133
134        lsa_ptr = ((unsigned char *)ls_update) + sizeof(libtrace_ospf_ls_update_t);
135        *remaining -= sizeof(libtrace_ospf_ls_update_t);
136
137        return lsa_ptr;
138}
139
140DLLEXPORT uint32_t trace_get_ospf_metric_from_as_external_lsa_v2(
141                libtrace_ospf_as_external_lsa_v2_t *as_lsa) {
142
143        uint32_t metric = 0;
144
145        assert(as_lsa);
146
147        metric = as_lsa->metric_a << 16;
148        metric |= (as_lsa->metric_b << 8);
149        metric |= as_lsa->metric_c;
150
151        return metric;
152}
153
154DLLEXPORT uint32_t trace_get_ospf_metric_from_summary_lsa_v2(
155                libtrace_ospf_summary_lsa_v2_t *sum_lsa) {
156
157        uint32_t metric = 0;
158
159        assert(sum_lsa);
160
161        metric = sum_lsa->metric_a << 16;
162        metric |= (sum_lsa->metric_b << 8);
163        metric |= sum_lsa->metric_c;
164
165        return metric;
166}
167
168DLLEXPORT int trace_get_next_ospf_link_v2(unsigned char **current,
169                libtrace_ospf_link_v2_t **link,
170                uint32_t *remaining,
171                uint32_t *link_len) {
172
173        if (*current == NULL || *remaining < sizeof(libtrace_ospf_link_v2_t)) {
174                *remaining = 0;
175                *link = NULL;
176                return 0;
177        }
178
179        *link = (libtrace_ospf_link_v2_t *)*current;
180
181        /* XXX The spec allows for multiple metrics for a single link. This
182         * approach won't support this, so we may need to be more intelligent
183         * about this in future */
184        *remaining -= sizeof(libtrace_ospf_link_v2_t);
185        *link_len = sizeof(libtrace_ospf_link_v2_t);
186        *current += sizeof(libtrace_ospf_link_v2_t);
187
188        return 1;
189
190}
191
192DLLEXPORT int trace_get_next_ospf_lsa_header_v2(unsigned char **current,
193                libtrace_ospf_lsa_v2_t **lsa_hdr,
194                uint32_t *remaining,
195                uint8_t *lsa_type,
196                uint16_t *lsa_length) {
197
198        int valid_lsa = 0;
199
200        if (*current == NULL || *remaining < sizeof(libtrace_ospf_lsa_v2_t)) {
201                *lsa_hdr = NULL;
202                *remaining = 0;
203                return 0;
204
205        }
206
207        *lsa_hdr = (libtrace_ospf_lsa_v2_t *)(*current);
208
209        /* Check that the LSA type is valid */
210        switch ((*lsa_hdr)->lsa_type) {
211                case TRACE_OSPF_LS_ROUTER:
212                case TRACE_OSPF_LS_NETWORK:
213                case TRACE_OSPF_LS_SUMMARY:
214                case TRACE_OSPF_LS_ASBR_SUMMARY:
215                case TRACE_OSPF_LS_EXTERNAL:
216                        valid_lsa = 1;
217                        break;
218        }
219
220        /* This function is for reading LSA headers only, e.g. those in DB desc
221         * or LS Ack packets. As such, I'm going to set the type and length to
222         * values that should prevent anyone from trying to treat subsequent
223         * payload as an LSA body */
224        *lsa_type = 0;
225        *lsa_length = sizeof(libtrace_ospf_lsa_v2_t);
226
227        if (!valid_lsa) {
228                *remaining = 0;
229                return -1;
230        }
231
232        *remaining -= *lsa_length;
233        *current += *lsa_length;
234
235        if (remaining == 0) {
236                /* No more LSAs */
237                return 0;
238        }
239        return 1;
240}
241
242DLLEXPORT int trace_get_next_ospf_lsa_v2(unsigned char **current,
243                libtrace_ospf_lsa_v2_t **lsa_hdr,
244                unsigned char **lsa_body,
245                uint32_t *remaining,
246                uint8_t *lsa_type,
247                uint16_t *lsa_length) {
248
249        int valid_lsa = 0;
250
251        if (*current == NULL || *remaining < sizeof(libtrace_ospf_lsa_v2_t)) {
252                *lsa_hdr = NULL;
253                *lsa_body = NULL;
254                *remaining = 0;
255
256                return 0;
257
258        }
259
260        *lsa_hdr = (libtrace_ospf_lsa_v2_t *)(*current);
261        *lsa_type = (*lsa_hdr)->lsa_type;
262        *lsa_length = ntohs((*lsa_hdr)->length);
263
264        /* Check that the LSA type is valid */
265        switch (*lsa_type) {
266                case TRACE_OSPF_LS_ROUTER:
267                case TRACE_OSPF_LS_NETWORK:
268                case TRACE_OSPF_LS_SUMMARY:
269                case TRACE_OSPF_LS_ASBR_SUMMARY:
270                case TRACE_OSPF_LS_EXTERNAL:
271                        valid_lsa = 1;
272                        break;
273        }
274
275        if (*lsa_length > *remaining || !valid_lsa) {
276                /* LSA is incomplete or an invalid type.
277                 *
278                 * If this occurs, you've probably managed to read something
279                 * that is NOT a legit LSA */
280                *remaining = 0;
281                *lsa_body = NULL;
282                return -1;
283        }
284
285        /* Some OSPF packets, e.g. LS ACKs, only contain LSA headers. If this
286         * is the case, we'll set the body pointer to NULL so the caller
287         * can't read invalid data */
288        if (*lsa_length == sizeof(libtrace_ospf_lsa_v2_t))
289                *lsa_body = NULL;
290        else
291                *lsa_body = (*current + sizeof(libtrace_ospf_lsa_v2_t));
292
293        *remaining -= *lsa_length;
294        *current += *lsa_length;
295
296        if (remaining == 0) {
297                /* No more LSAs */
298                return 0;
299        }
300
301        return 1;
302
303}
304
305
Note: See TracBrowser for help on using the repository browser.