/[packages]/updates/1/quagga/current/SOURCES/quagga-fix_CVE-2012-0249-CVE-2012-0250.diff
ViewVC logotype

Contents of /updates/1/quagga/current/SOURCES/quagga-fix_CVE-2012-0249-CVE-2012-0250.diff

Parent Directory Parent Directory | Revision Log Revision Log


Revision 232974 - (show annotations) (download)
Mon Apr 23 15:19:42 2012 UTC (12 years, 1 month ago) by luigiwalser
File size: 36489 byte(s)
fix CVE-2012-0249, CVE-2012-0250, CVE-2012-0255 (from upstream)
1 diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
2 index e65b2e3..8ace095 100644
3 --- a/ospfd/ospf_dump.c
4 +++ b/ospfd/ospf_dump.c
5 @@ -661,7 +661,7 @@ ospf_header_dump (struct ospf_header *ospfh)
6 zlog_debug ("Header");
7 zlog_debug (" Version %d", ospfh->version);
8 zlog_debug (" Type %d (%s)", ospfh->type,
9 - ospf_packet_type_str[ospfh->type]);
10 + LOOKUP (ospf_packet_type_str, ospfh->type));
11 zlog_debug (" Packet Len %d", ntohs (ospfh->length));
12 zlog_debug (" Router ID %s", inet_ntoa (ospfh->router_id));
13 zlog_debug (" Area ID %s", inet_ntoa (ospfh->area_id));
14 @@ -1457,7 +1457,7 @@ DEFUN (show_debugging_ospf,
15 if (IS_DEBUG_OSPF_PACKET (i, SEND) && IS_DEBUG_OSPF_PACKET (i, RECV))
16 {
17 vty_out (vty, " OSPF packet %s%s debugging is on%s",
18 - ospf_packet_type_str[i + 1],
19 + LOOKUP (ospf_packet_type_str, i + 1),
20 IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "",
21 VTY_NEWLINE);
22 }
23 @@ -1465,12 +1465,12 @@ DEFUN (show_debugging_ospf,
24 {
25 if (IS_DEBUG_OSPF_PACKET (i, SEND))
26 vty_out (vty, " OSPF packet %s send%s debugging is on%s",
27 - ospf_packet_type_str[i + 1],
28 + LOOKUP (ospf_packet_type_str, i + 1),
29 IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "",
30 VTY_NEWLINE);
31 if (IS_DEBUG_OSPF_PACKET (i, RECV))
32 vty_out (vty, " OSPF packet %s receive%s debugging is on%s",
33 - ospf_packet_type_str[i + 1],
34 + LOOKUP (ospf_packet_type_str, i + 1),
35 IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "",
36 VTY_NEWLINE);
37 }
38 diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h
39 index fb81371..455214f 100644
40 --- a/ospfd/ospf_dump.h
41 +++ b/ospfd/ospf_dump.h
42 @@ -121,7 +121,6 @@ extern unsigned long term_debug_ospf_zebra;
43 extern unsigned long term_debug_ospf_nssa;
44
45 /* Message Strings. */
46 -extern const char *ospf_packet_type_str[];
47 extern char *ospf_lsa_type_str[];
48
49 /* Prototypes. */
50 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
51 index 0f338d3..03e6d2a 100644
52 --- a/ospfd/ospf_packet.c
53 +++ b/ospfd/ospf_packet.c
54 @@ -50,15 +50,16 @@
55 #include "ospfd/ospf_dump.h"
56
57 /* Packet Type String. */
58 -const char *ospf_packet_type_str[] =
59 -{
60 - "unknown",
61 - "Hello",
62 - "Database Description",
63 - "Link State Request",
64 - "Link State Update",
65 - "Link State Acknowledgment",
66 +const struct message ospf_packet_type_str[] =
67 +{
68 + { OSPF_MSG_HELLO, "Hello" },
69 + { OSPF_MSG_DB_DESC, "Database Description" },
70 + { OSPF_MSG_LS_REQ, "Link State Request" },
71 + { OSPF_MSG_LS_UPD, "Link State Update" },
72 + { OSPF_MSG_LS_ACK, "Link State Acknowledgment" },
73 };
74 +const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
75 + sizeof (ospf_packet_type_str[0]);
76
77 /* OSPF authentication checking function */
78 static int
79 @@ -201,7 +202,7 @@ ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
80 "destination %s) called with NULL obuf, ignoring "
81 "(please report this bug)!\n",
82 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
83 - ospf_packet_type_str[stream_getc_from(op->s, 1)],
84 + LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
85 inet_ntoa (op->dst));
86 return;
87 }
88 @@ -755,7 +756,7 @@ ospf_write (struct thread *thread)
89 }
90
91 zlog_debug ("%s sent to [%s] via [%s].",
92 - ospf_packet_type_str[type], inet_ntoa (op->dst),
93 + LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
94 IF_NAME (oi));
95
96 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
97 @@ -801,7 +802,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
98 {
99 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
100 "dropping.",
101 - ospf_packet_type_str[ospfh->type],
102 + LOOKUP (ospf_packet_type_str, ospfh->type),
103 inet_ntoa (iph->ip_src));
104 }
105 return;
106 @@ -2571,7 +2572,7 @@ ospf_read (struct thread *thread)
107 }
108
109 zlog_debug ("%s received from [%s] via [%s]",
110 - ospf_packet_type_str[ospfh->type],
111 + LOOKUP (ospf_packet_type_str, ospfh->type),
112 inet_ntoa (ospfh->router_id), IF_NAME (oi));
113 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
114 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
115 diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
116 index 9a47208..2115f11 100644
117 --- a/ospfd/ospf_packet.h
118 +++ b/ospfd/ospf_packet.h
119 @@ -163,4 +163,7 @@ extern int ospf_ls_ack_timer (struct thread *);
120 extern int ospf_poll_timer (struct thread *);
121 extern int ospf_hello_reply_timer (struct thread *);
122
123 +extern const struct message ospf_packet_type_str[];
124 +extern const size_t ospf_packet_type_str_max;
125 +
126 #endif /* _ZEBRA_OSPF_PACKET_H */
127 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
128 index 03e6d2a..500f245 100644
129 --- a/ospfd/ospf_packet.c
130 +++ b/ospfd/ospf_packet.c
131 @@ -223,7 +223,7 @@ ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
132 "destination %s) called with NULL obuf, ignoring "
133 "(please report this bug)!\n",
134 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
135 - ospf_packet_type_str[stream_getc_from(op->s, 1)],
136 + LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
137 inet_ntoa (op->dst));
138 return;
139 }
140 --- quagga-0.99.18/ospfd/ospf_packet.c~ 2012-04-23 11:01:11.969597352 -0400
141 +++ quagga-0.99.18/ospfd/ospf_packet.c 2012-04-23 11:01:18.409574962 -0400
142 @@ -61,6 +61,18 @@
143 const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
144 sizeof (ospf_packet_type_str[0]);
145
146 +/* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
147 + particular types, offset is the "type" field of a packet. */
148 +static const u_int16_t ospf_packet_minlen[] =
149 +{
150 + 0,
151 + OSPF_HELLO_MIN_SIZE,
152 + OSPF_DB_DESC_MIN_SIZE,
153 + OSPF_LS_REQ_MIN_SIZE,
154 + OSPF_LS_UPD_MIN_SIZE,
155 + OSPF_LS_ACK_MIN_SIZE,
156 +};
157 +
158 /* OSPF authentication checking function */
159 static int
160 ospf_auth_type (struct ospf_interface *oi)
161 @@ -2293,6 +2305,47 @@
162 return 1;
163 }
164
165 +/* Verify a complete OSPF packet for proper sizing/alignment. */
166 +static unsigned
167 +ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
168 +{
169 + u_int16_t bytesdeclared;
170 +
171 + /* Length, 1st approximation. */
172 + if (bytesonwire < OSPF_HEADER_SIZE)
173 + {
174 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
175 + zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
176 + return MSG_NG;
177 + }
178 + /* Now it is safe to access header fields. Performing length check, allow
179 + * for possible extra bytes of crypto auth/padding, which are not counted
180 + * in the OSPF header "length" field. */
181 + bytesdeclared = ntohs (oh->length);
182 + if (bytesdeclared > bytesonwire)
183 + {
184 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
185 + zlog_debug ("%s: packet length error (%u real, %u declared)",
186 + __func__, bytesonwire, bytesdeclared);
187 + return MSG_NG;
188 + }
189 + /* Length, 2nd approximation. The type-specific constraint is checked
190 + against declared length, not amount of bytes on wire. */
191 + if
192 + (
193 + oh->type >= OSPF_MSG_HELLO &&
194 + oh->type <= OSPF_MSG_LS_ACK &&
195 + bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
196 + )
197 + {
198 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
199 + zlog_debug ("%s: undersized (%u B) %s packet", __func__,
200 + bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
201 + return MSG_NG;
202 + }
203 + return MSG_OK;
204 +}
205 +
206 /* OSPF Header verification. */
207 static int
208 ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
209 @@ -2388,10 +2441,10 @@
210 /* prepare for next packet. */
211 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
212
213 - /* read OSPF packet. */
214 stream_reset(ospf->ibuf);
215 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
216 return -1;
217 + /* This raw packet is known to be at least as big as its IP header. */
218
219 /* Note that there should not be alignment problems with this assignment
220 because this is at the beginning of the stream data buffer. */
221 @@ -2436,6 +2489,8 @@
222
223 /* Now it is safe to access all fields of OSPF packet header. */
224 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
225 + if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
226 + return -1;
227
228 /* associate packet with ospf interface */
229 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
230 diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
231 index 2115f11..3cbe889 100644
232 --- a/ospfd/ospf_packet.h
233 +++ b/ospfd/ospf_packet.h
234 @@ -46,6 +46,10 @@
235
236 #define OSPF_HELLO_REPLY_DELAY 1
237
238 +/* Return values of functions involved in packet verification, see ospf6d. */
239 +#define MSG_OK 0
240 +#define MSG_NG 1
241 +
242 struct ospf_packet
243 {
244 struct ospf_packet *next;
245 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
246 index f425da8..a71cc99 100644
247 --- a/ospfd/ospf_packet.c
248 +++ b/ospfd/ospf_packet.c
249 @@ -2255,8 +2255,7 @@ ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
250 }
251
252 static int
253 -ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
254 - struct ospf_header *ospfh)
255 +ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
256 {
257 int ret = 0;
258 struct crypt_key *ck;
259 @@ -2282,7 +2281,7 @@ ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
260 /* This is very basic, the digest processing is elsewhere */
261 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
262 ospfh->u.crypt.key_id == ck->key_id &&
263 - ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
264 + ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE)
265 ret = 1;
266 else
267 ret = 0;
268 @@ -2406,7 +2405,7 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
269 return -1;
270 }
271
272 - if (! ospf_check_auth (oi, ibuf, ospfh))
273 + if (! ospf_check_auth (oi, ospfh))
274 {
275 zlog_warn ("interface %s: ospf_read authentication failed.",
276 IF_NAME (oi));
277 --- quagga-0.99.18/ospfd/ospf_packet.c~ 2011-03-21 07:09:13.000000000 -0400
278 +++ quagga-0.99.18/ospfd/ospf_packet.c 2012-04-23 10:08:17.570633842 -0400
279 @@ -291,24 +291,14 @@
280
281
282 static int
283 -ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
284 - u_int16_t length)
285 +ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
286 {
287 - unsigned char *ibuf;
288 MD5_CTX ctx;
289 unsigned char digest[OSPF_AUTH_MD5_SIZE];
290 - unsigned char *pdigest;
291 struct crypt_key *ck;
292 - struct ospf_header *ospfh;
293 struct ospf_neighbor *nbr;
294 + u_int16_t length = ntohs (ospfh->length);
295
296 -
297 - ibuf = STREAM_PNT (s);
298 - ospfh = (struct ospf_header *) ibuf;
299 -
300 - /* Get pointer to the end of the packet. */
301 - pdigest = ibuf + length;
302 -
303 /* Get secret key. */
304 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
305 ospfh->u.crypt.key_id);
306 @@ -334,12 +324,12 @@
307 /* Generate a digest for the ospf packet - their digest + our digest. */
308 memset(&ctx, 0, sizeof(ctx));
309 MD5Init(&ctx);
310 - MD5Update(&ctx, ibuf, length);
311 + MD5Update(&ctx, ospfh, length);
312 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
313 MD5Final(digest, &ctx);
314
315 /* compare the two */
316 - if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
317 + if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
318 {
319 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
320 IF_NAME (oi));
321 @@ -2350,7 +2340,7 @@
322 {
323 if (ospfh->checksum != 0)
324 return -1;
325 - if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
326 + if (ospf_check_md5_digest (oi, ospfh) == 0)
327 {
328 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
329 IF_NAME (oi));
330 diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
331 index bf3b083..ca0653c 100644
332 --- a/ospfd/ospf_lsa.h
333 +++ b/ospfd/ospf_lsa.h
334 @@ -153,6 +153,7 @@ struct router_lsa_link
335 };
336
337 /* OSPF Router-LSAs structure. */
338 +#define OSPF_ROUTER_LSA_MIN_SIZE 16U /* w/1 link descriptor */
339 struct router_lsa
340 {
341 struct lsa_header header;
342 @@ -170,6 +171,7 @@ struct router_lsa
343 };
344
345 /* OSPF Network-LSAs structure. */
346 +#define OSPF_NETWORK_LSA_MIN_SIZE 8U /* w/1 router-ID */
347 struct network_lsa
348 {
349 struct lsa_header header;
350 @@ -178,6 +180,7 @@ struct network_lsa
351 };
352
353 /* OSPF Summary-LSAs structure. */
354 +#define OSPF_SUMMARY_LSA_MIN_SIZE 8U /* w/1 TOS metric block */
355 struct summary_lsa
356 {
357 struct lsa_header header;
358 @@ -187,6 +190,7 @@ struct summary_lsa
359 };
360
361 /* OSPF AS-external-LSAs structure. */
362 +#define OSPF_AS_EXTERNAL_LSA_MIN_SIZE 16U /* w/1 TOS forwarding block */
363 struct as_external_lsa
364 {
365 struct lsa_header header;
366 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
367 index 5704f9d..3b82820 100644
368 --- a/ospfd/ospf_packet.c
369 +++ b/ospfd/ospf_packet.c
370 @@ -73,6 +73,24 @@ static const u_int16_t ospf_packet_minlen[] =
371 OSPF_LS_ACK_MIN_SIZE,
372 };
373
374 +/* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular
375 + types, offset is the "LSA type" field. */
376 +static const u_int16_t ospf_lsa_minlen[] =
377 +{
378 + 0,
379 + OSPF_ROUTER_LSA_MIN_SIZE,
380 + OSPF_NETWORK_LSA_MIN_SIZE,
381 + OSPF_SUMMARY_LSA_MIN_SIZE,
382 + OSPF_SUMMARY_LSA_MIN_SIZE,
383 + OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
384 + 0,
385 + OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
386 + 0,
387 + 0,
388 + 0,
389 + 0,
390 +};
391 +
392 /* OSPF authentication checking function */
393 static int
394 ospf_auth_type (struct ospf_interface *oi)
395 @@ -2310,11 +2328,199 @@ ospf_check_sum (struct ospf_header *ospfh)
396 return 1;
397 }
398
399 +/* Verify, that given link/TOS records are properly sized/aligned and match
400 + Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
401 +static unsigned
402 +ospf_router_lsa_links_examin
403 +(
404 + struct router_lsa_link * link,
405 + u_int16_t linkbytes,
406 + const u_int16_t num_links
407 +)
408 +{
409 + unsigned counted_links = 0, thislinklen;
410 +
411 + while (linkbytes)
412 + {
413 + thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
414 + if (thislinklen > linkbytes)
415 + {
416 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
417 + zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
418 + return MSG_NG;
419 + }
420 + link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
421 + linkbytes -= thislinklen;
422 + counted_links++;
423 + }
424 + if (counted_links != num_links)
425 + {
426 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
427 + zlog_debug ("%s: %u link blocks declared, %u present",
428 + __func__, num_links, counted_links);
429 + return MSG_NG;
430 + }
431 + return MSG_OK;
432 +}
433 +
434 +/* Verify, that the given LSA is properly sized/aligned (including type-specific
435 + minimum length constraint). */
436 +static unsigned
437 +ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
438 +{
439 + unsigned ret;
440 + struct router_lsa * rlsa;
441 + if
442 + (
443 + lsah->type < OSPF_MAX_LSA &&
444 + ospf_lsa_minlen[lsah->type] &&
445 + lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
446 + )
447 + {
448 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
449 + zlog_debug ("%s: undersized (%u B) %s",
450 + __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
451 + return MSG_NG;
452 + }
453 + switch (lsah->type)
454 + {
455 + case OSPF_ROUTER_LSA:
456 + /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
457 + if (headeronly)
458 + {
459 + ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
460 + break;
461 + }
462 + rlsa = (struct router_lsa *) lsah;
463 + ret = ospf_router_lsa_links_examin
464 + (
465 + (struct router_lsa_link *) rlsa->link,
466 + lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
467 + ntohs (rlsa->links) /* 16 bits */
468 + );
469 + break;
470 + case OSPF_AS_EXTERNAL_LSA:
471 + /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
472 + case OSPF_AS_NSSA_LSA:
473 + /* RFC3101 C, idem */
474 + ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
475 + break;
476 + /* Following LSA types are considered OK length-wise as soon as their minimum
477 + * length constraint is met and length of the whole LSA is a multiple of 4
478 + * (basic LSA header size is already a multiple of 4). */
479 + case OSPF_NETWORK_LSA:
480 + /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
481 + case OSPF_SUMMARY_LSA:
482 + case OSPF_ASBR_SUMMARY_LSA:
483 + /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
484 +#ifdef HAVE_OPAQUE_LSA
485 + case OSPF_OPAQUE_LINK_LSA:
486 + case OSPF_OPAQUE_AREA_LSA:
487 + case OSPF_OPAQUE_AS_LSA:
488 + /* RFC5250 A.2, "some number of octets (of application-specific
489 + * data) padded to 32-bit alignment." This is considered equivalent
490 + * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
491 + * file for the detailed analysis of this passage. */
492 +#endif
493 + ret = lsalen % 4 ? MSG_NG : MSG_OK;
494 + break;
495 + default:
496 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
497 + zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
498 + return MSG_NG;
499 + }
500 + if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
501 + zlog_debug ("%s: alignment error in %s",
502 + __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
503 + return ret;
504 +}
505 +
506 +/* Verify if the provided input buffer is a valid sequence of LSAs. This
507 + includes verification of LSA blocks length/alignment and dispatching
508 + of deeper-level checks. */
509 +static unsigned
510 +ospf_lsaseq_examin
511 +(
512 + struct lsa_header *lsah, /* start of buffered data */
513 + size_t length,
514 + const u_char headeronly,
515 + /* When declared_num_lsas is not 0, compare it to the real number of LSAs
516 + and treat the difference as an error. */
517 + const u_int32_t declared_num_lsas
518 +)
519 +{
520 + u_int32_t counted_lsas = 0;
521 +
522 + while (length)
523 + {
524 + u_int16_t lsalen;
525 + if (length < OSPF_LSA_HEADER_SIZE)
526 + {
527 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
528 + zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
529 + __func__, length, counted_lsas);
530 + return MSG_NG;
531 + }
532 + /* save on ntohs() calls here and in the LSA validator */
533 + lsalen = ntohs (lsah->length);
534 + if (lsalen < OSPF_LSA_HEADER_SIZE)
535 + {
536 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
537 + zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
538 + __func__, counted_lsas, lsalen);
539 + return MSG_NG;
540 + }
541 + if (headeronly)
542 + {
543 + /* less checks here and in ospf_lsa_examin() */
544 + if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
545 + {
546 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
547 + zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
548 + return MSG_NG;
549 + }
550 + lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
551 + length -= OSPF_LSA_HEADER_SIZE;
552 + }
553 + else
554 + {
555 + /* make sure the input buffer is deep enough before further checks */
556 + if (lsalen > length)
557 + {
558 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
559 + zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
560 + __func__, counted_lsas, lsalen, length);
561 + return MSG_NG;
562 + }
563 + if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
564 + {
565 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
566 + zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
567 + return MSG_NG;
568 + }
569 + lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
570 + length -= lsalen;
571 + }
572 + counted_lsas++;
573 + }
574 +
575 + if (declared_num_lsas && counted_lsas != declared_num_lsas)
576 + {
577 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
578 + zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
579 + __func__, declared_num_lsas, counted_lsas);
580 + return MSG_NG;
581 + }
582 + return MSG_OK;
583 +}
584 +
585 /* Verify a complete OSPF packet for proper sizing/alignment. */
586 static unsigned
587 ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
588 {
589 u_int16_t bytesdeclared;
590 + unsigned ret;
591 + struct ospf_ls_update * lsupd;
592
593 /* Length, 1st approximation. */
594 if (bytesonwire < OSPF_HEADER_SIZE)
595 @@ -2348,7 +2554,59 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
596 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
597 return MSG_NG;
598 }
599 - return MSG_OK;
600 + switch (oh->type)
601 + {
602 + case OSPF_MSG_HELLO:
603 + /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
604 + by N>=0 router-IDs. */
605 + ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
606 + break;
607 + case OSPF_MSG_DB_DESC:
608 + /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
609 + by N>=0 header-only LSAs. */
610 + ret = ospf_lsaseq_examin
611 + (
612 + (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
613 + bytesonwire - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
614 + 1, /* header-only LSAs */
615 + 0
616 + );
617 + break;
618 + case OSPF_MSG_LS_REQ:
619 + /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
620 + ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
621 + OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
622 + break;
623 + case OSPF_MSG_LS_UPD:
624 + /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
625 + by N>=0 full LSAs (with N declared beforehand). */
626 + lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
627 + ret = ospf_lsaseq_examin
628 + (
629 + (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
630 + bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
631 + 0, /* full LSAs */
632 + ntohl (lsupd->num_lsas) /* 32 bits */
633 + );
634 + break;
635 + case OSPF_MSG_LS_ACK:
636 + /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
637 + ret = ospf_lsaseq_examin
638 + (
639 + (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
640 + bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
641 + 1, /* header-only LSAs */
642 + 0
643 + );
644 + break;
645 + default:
646 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
647 + zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
648 + return MSG_NG;
649 + }
650 + if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
651 + zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
652 + return ret;
653 }
654
655 /* OSPF Header verification. */
656 diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
657 index 3cbe889..337686a 100644
658 --- a/ospfd/ospf_packet.h
659 +++ b/ospfd/ospf_packet.h
660 @@ -121,6 +121,10 @@ struct ospf_db_desc
661 u_int32_t dd_seqnum;
662 };
663
664 +struct ospf_ls_update
665 +{
666 + u_int32_t num_lsas;
667 +};
668
669 /* Macros. */
670 /* XXX Perhaps obsolete; function in ospf_packet.c */
671 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
672 index 3b82820..7b661a3 100644
673 --- a/ospfd/ospf_packet.c
674 +++ b/ospfd/ospf_packet.c
675 @@ -2559,7 +2559,7 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
676 case OSPF_MSG_HELLO:
677 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
678 by N>=0 router-IDs. */
679 - ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
680 + ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
681 break;
682 case OSPF_MSG_DB_DESC:
683 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
684 @@ -2567,14 +2567,14 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
685 ret = ospf_lsaseq_examin
686 (
687 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
688 - bytesonwire - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
689 + bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
690 1, /* header-only LSAs */
691 0
692 );
693 break;
694 case OSPF_MSG_LS_REQ:
695 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
696 - ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
697 + ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
698 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
699 break;
700 case OSPF_MSG_LS_UPD:
701 @@ -2584,7 +2584,7 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
702 ret = ospf_lsaseq_examin
703 (
704 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
705 - bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
706 + bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
707 0, /* full LSAs */
708 ntohl (lsupd->num_lsas) /* 32 bits */
709 );
710 @@ -2594,7 +2594,7 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
711 ret = ospf_lsaseq_examin
712 (
713 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
714 - bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
715 + bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
716 1, /* header-only LSAs */
717 0
718 );
719 diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
720 index 8ace095..7e11e25 100644
721 --- a/ospfd/ospf_dump.c
722 +++ b/ospfd/ospf_dump.c
723 @@ -115,6 +115,16 @@ const struct message ospf_network_type_msg[] =
724 };
725 const int ospf_network_type_msg_max = OSPF_IFTYPE_MAX;
726
727 +/* AuType */
728 +const struct message ospf_auth_type_str[] =
729 +{
730 + { OSPF_AUTH_NULL, "Null" },
731 + { OSPF_AUTH_SIMPLE, "Simple" },
732 + { OSPF_AUTH_CRYPTOGRAPHIC, "Cryptographic" },
733 +};
734 +const size_t ospf_auth_type_str_max = sizeof (ospf_auth_type_str) /
735 + sizeof (ospf_auth_type_str[0]);
736 +
737 /* Configuration debug option variables. */
738 unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
739 unsigned long conf_debug_ospf_event = 0;
740 @@ -657,6 +667,7 @@ static void
741 ospf_header_dump (struct ospf_header *ospfh)
742 {
743 char buf[9];
744 + u_int16_t auth_type = ntohs (ospfh->auth_type);
745
746 zlog_debug ("Header");
747 zlog_debug (" Version %d", ospfh->version);
748 @@ -666,9 +677,9 @@ ospf_header_dump (struct ospf_header *ospfh)
749 zlog_debug (" Router ID %s", inet_ntoa (ospfh->router_id));
750 zlog_debug (" Area ID %s", inet_ntoa (ospfh->area_id));
751 zlog_debug (" Checksum 0x%x", ntohs (ospfh->checksum));
752 - zlog_debug (" AuType %d", ntohs (ospfh->auth_type));
753 + zlog_debug (" AuType %s", LOOKUP (ospf_auth_type_str, auth_type));
754
755 - switch (ntohs (ospfh->auth_type))
756 + switch (auth_type)
757 {
758 case OSPF_AUTH_NULL:
759 break;
760 --- quagga-0.99.18/ospfd/ospf_dump.h~ 2012-04-23 10:38:14.074389366 -0400
761 +++ quagga-0.99.18/ospfd/ospf_dump.h 2012-04-23 10:41:16.213755215 -0400
762 @@ -122,6 +122,8 @@
763
764 /* Message Strings. */
765 extern char *ospf_lsa_type_str[];
766 +extern const struct message ospf_auth_type_str[];
767 +extern const size_t ospf_auth_type_str_max;
768
769 /* Prototypes. */
770 extern const char *ospf_area_name_string (struct ospf_area *);
771 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
772 index 7b661a3..05651d3 100644
773 --- a/ospfd/ospf_packet.c
774 +++ b/ospfd/ospf_packet.c
775 @@ -91,6 +91,9 @@ static const u_int16_t ospf_lsa_minlen[] =
776 0,
777 };
778
779 +/* for ospf_check_auth() */
780 +static int ospf_check_sum (struct ospf_header *);
781 +
782 /* OSPF authentication checking function */
783 static int
784 ospf_auth_type (struct ospf_interface *oi)
785 @@ -2262,44 +2265,91 @@ ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
786 return 0;
787 }
788
789 +/* Return 1, if the packet is properly authenticated and checksummed,
790 + 0 otherwise. In particular, check that AuType header field is valid and
791 + matches the locally configured AuType, and that D.5 requirements are met. */
792 static int
793 ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
794 {
795 - int ret = 0;
796 struct crypt_key *ck;
797 + u_int16_t iface_auth_type;
798 + u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
799
800 - switch (ntohs (ospfh->auth_type))
801 + switch (pkt_auth_type)
802 + {
803 + case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
804 + if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
805 {
806 - case OSPF_AUTH_NULL:
807 - ret = 1;
808 - break;
809 - case OSPF_AUTH_SIMPLE:
810 - if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
811 - ret = 1;
812 - else
813 - ret = 0;
814 - break;
815 - case OSPF_AUTH_CRYPTOGRAPHIC:
816 - if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
817 - {
818 - ret = 0;
819 - break;
820 - }
821 -
822 - /* This is very basic, the digest processing is elsewhere */
823 - if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
824 - ospfh->u.crypt.key_id == ck->key_id &&
825 - ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE)
826 - ret = 1;
827 - else
828 - ret = 0;
829 - break;
830 - default:
831 - ret = 0;
832 - break;
833 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
834 + zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
835 + IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
836 + return 0;
837 }
838 -
839 - return ret;
840 + if (! ospf_check_sum (ospfh))
841 + {
842 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
843 + zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
844 + IF_NAME (oi), inet_ntoa (ospfh->router_id));
845 + return 0;
846 + }
847 + return 1;
848 + case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
849 + if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
850 + {
851 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
852 + zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
853 + IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
854 + return 0;
855 + }
856 + if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
857 + {
858 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
859 + zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
860 + return 0;
861 + }
862 + if (! ospf_check_sum (ospfh))
863 + {
864 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
865 + zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
866 + IF_NAME (oi), inet_ntoa (ospfh->router_id));
867 + return 0;
868 + }
869 + return 1;
870 + case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
871 + if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
872 + {
873 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
874 + zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
875 + IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
876 + return 0;
877 + }
878 + if (ospfh->checksum)
879 + {
880 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
881 + zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
882 + return 0;
883 + }
884 + /* only MD5 crypto method can pass ospf_packet_examin() */
885 + if
886 + (
887 + NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
888 + ospfh->u.crypt.key_id != ck->key_id ||
889 + /* Condition above uses the last key ID on the list, which is
890 + different from what ospf_crypt_key_lookup() does. A bug? */
891 + ! ospf_check_md5_digest (oi, ospfh)
892 + )
893 + {
894 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
895 + zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
896 + return 0;
897 + }
898 + return 1;
899 + default:
900 + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
901 + zlog_warn ("interface %s: invalid packet auth-type (%02x)",
902 + IF_NAME (oi), pkt_auth_type);
903 + return 0;
904 + }
905 }
906
907 static int
908 @@ -2518,7 +2568,7 @@ ospf_lsaseq_examin
909 static unsigned
910 ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
911 {
912 - u_int16_t bytesdeclared;
913 + u_int16_t bytesdeclared, bytesauth;
914 unsigned ret;
915 struct ospf_ls_update * lsupd;
916
917 @@ -2533,11 +2583,24 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
918 * for possible extra bytes of crypto auth/padding, which are not counted
919 * in the OSPF header "length" field. */
920 bytesdeclared = ntohs (oh->length);
921 - if (bytesdeclared > bytesonwire)
922 + if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
923 + bytesauth = 0;
924 + else
925 + {
926 + if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
927 + {
928 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
929 + zlog_debug ("%s: unsupported crypto auth length (%u B)",
930 + __func__, oh->u.crypt.auth_data_len);
931 + return MSG_NG;
932 + }
933 + bytesauth = OSPF_AUTH_MD5_SIZE;
934 + }
935 + if (bytesdeclared + bytesauth > bytesonwire)
936 {
937 if (IS_DEBUG_OSPF_PACKET (0, RECV))
938 - zlog_debug ("%s: packet length error (%u real, %u declared)",
939 - __func__, bytesonwire, bytesdeclared);
940 + zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
941 + __func__, bytesonwire, bytesdeclared, bytesauth);
942 return MSG_NG;
943 }
944 /* Length, 2nd approximation. The type-specific constraint is checked
945 @@ -2645,42 +2708,9 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
946 return -1;
947 }
948
949 - /* Check authentication. */
950 - if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
951 - {
952 - zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
953 - IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
954 - return -1;
955 - }
956 -
957 + /* Check authentication. The function handles logging actions, where required. */
958 if (! ospf_check_auth (oi, ospfh))
959 - {
960 - zlog_warn ("interface %s: ospf_read authentication failed.",
961 - IF_NAME (oi));
962 - return -1;
963 - }
964 -
965 - /* if check sum is invalid, packet is discarded. */
966 - if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
967 - {
968 - if (! ospf_check_sum (ospfh))
969 - {
970 - zlog_warn ("interface %s: ospf_read packet checksum error %s",
971 - IF_NAME (oi), inet_ntoa (ospfh->router_id));
972 - return -1;
973 - }
974 - }
975 - else
976 - {
977 - if (ospfh->checksum != 0)
978 - return -1;
979 - if (ospf_check_md5_digest (oi, ospfh) == 0)
980 - {
981 - zlog_warn ("interface %s: ospf_read md5 authentication failed.",
982 - IF_NAME (oi));
983 - return -1;
984 - }
985 - }
986 + return -1;
987
988 return 0;
989 }
990 diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
991 index 05651d3..de14ccc 100644
992 --- a/ospfd/ospf_packet.c
993 +++ b/ospfd/ospf_packet.c
994 @@ -2582,6 +2582,12 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
995 /* Now it is safe to access header fields. Performing length check, allow
996 * for possible extra bytes of crypto auth/padding, which are not counted
997 * in the OSPF header "length" field. */
998 + if (oh->version != OSPF_VERSION)
999 + {
1000 + if (IS_DEBUG_OSPF_PACKET (0, RECV))
1001 + zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
1002 + return MSG_NG;
1003 + }
1004 bytesdeclared = ntohs (oh->length);
1005 if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
1006 bytesauth = 0;
1007 @@ -2677,21 +2683,6 @@ static int
1008 ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
1009 struct ip *iph, struct ospf_header *ospfh)
1010 {
1011 - /* check version. */
1012 - if (ospfh->version != OSPF_VERSION)
1013 - {
1014 - zlog_warn ("interface %s: ospf_read version number mismatch.",
1015 - IF_NAME (oi));
1016 - return -1;
1017 - }
1018 -
1019 - /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
1020 - if (ospfh->type < 1 || ospfh->type > 5)
1021 - {
1022 - zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
1023 - return -1;
1024 - }
1025 -
1026 /* Check Area ID. */
1027 if (!ospf_check_area_id (oi, ospfh))
1028 {
1029 --- a/ospfd/ospf_lsa.h
1030 +++ a/ospfd/ospf_lsa.h
1031 @@ -153,7 +153,14 @@ struct router_lsa_link
1032 };
1033
1034 /* OSPF Router-LSAs structure. */
1035 -#define OSPF_ROUTER_LSA_MIN_SIZE 16U /* w/1 link descriptor */
1036 +#define OSPF_ROUTER_LSA_MIN_SIZE 4U /* w/0 link descriptors */
1037 +/* There is an edge case, when number of links in a Router-LSA may be 0 without
1038 + breaking the specification. A router, which has no other links to backbone
1039 + area besides one virtual link, will not put any VL descriptor blocks into
1040 + the Router-LSA generated for area 0 until a full adjacency over the VL is
1041 + reached (RFC2328 12.4.1.3). In this case the Router-LSA initially received
1042 + by the other end of the VL will have 0 link descriptor blocks, but soon will
1043 + be replaced with the next revision having 1 descriptor block. */
1044 struct router_lsa
1045 {
1046 struct lsa_header header;

  ViewVC Help
Powered by ViewVC 1.1.30