source: lib/protocols_ospf.c @ fb1fd42

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