]>
Commit | Line | Data |
---|---|---|
2d33f157 | 1 | /* |
2 | * API message handling module for OSPF daemon and client. | |
3 | * Copyright (C) 2001, 2002 Ralph Keller | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published | |
9 | * by the Free Software Foundation; either version 2, or (at your | |
10 | * option) any later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the | |
19 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | * Boston, MA 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #ifdef SUPPORT_OSPF_API | |
2d33f157 | 26 | |
27 | #include "linklist.h" | |
28 | #include "prefix.h" | |
29 | #include "if.h" | |
30 | #include "table.h" | |
31 | #include "memory.h" | |
32 | #include "command.h" | |
33 | #include "vty.h" | |
34 | #include "stream.h" | |
35 | #include "log.h" | |
36 | #include "thread.h" | |
37 | #include "hash.h" | |
38 | #include "sockunion.h" /* for inet_aton() */ | |
39 | #include "buffer.h" | |
40 | #include "network.h" | |
41 | ||
42 | #include "ospfd/ospfd.h" | |
43 | #include "ospfd/ospf_interface.h" | |
44 | #include "ospfd/ospf_ism.h" | |
45 | #include "ospfd/ospf_asbr.h" | |
46 | #include "ospfd/ospf_lsa.h" | |
47 | #include "ospfd/ospf_lsdb.h" | |
48 | #include "ospfd/ospf_neighbor.h" | |
49 | #include "ospfd/ospf_nsm.h" | |
50 | #include "ospfd/ospf_flood.h" | |
51 | #include "ospfd/ospf_packet.h" | |
52 | #include "ospfd/ospf_spf.h" | |
53 | #include "ospfd/ospf_dump.h" | |
54 | #include "ospfd/ospf_route.h" | |
55 | #include "ospfd/ospf_ase.h" | |
56 | #include "ospfd/ospf_zebra.h" | |
57 | ||
58 | #include "ospfd/ospf_api.h" | |
59 | ||
60 | ||
61 | /* For debugging only, will be removed */ | |
62 | void | |
63 | api_opaque_lsa_print (struct lsa_header *data) | |
64 | { | |
65 | struct opaque_lsa | |
66 | { | |
67 | struct lsa_header header; | |
00c290e0 | 68 | u_char mydata[]; |
2d33f157 | 69 | }; |
70 | ||
71 | struct opaque_lsa *olsa; | |
72 | int opaquelen; | |
73 | int i; | |
74 | ||
75 | ospf_lsa_header_dump (data); | |
76 | ||
77 | olsa = (struct opaque_lsa *) data; | |
78 | ||
79 | opaquelen = ntohs (data->length) - OSPF_LSA_HEADER_SIZE; | |
e84cc647 | 80 | zlog_debug ("apiserver_lsa_print: opaquelen=%d\n", opaquelen); |
2d33f157 | 81 | |
82 | for (i = 0; i < opaquelen; i++) | |
83 | { | |
e84cc647 | 84 | zlog_debug ("0x%x ", olsa->mydata[i]); |
2d33f157 | 85 | } |
e84cc647 | 86 | zlog_debug ("\n"); |
2d33f157 | 87 | } |
88 | ||
89 | /* ----------------------------------------------------------- | |
90 | * Generic messages | |
91 | * ----------------------------------------------------------- | |
92 | */ | |
93 | ||
94 | struct msg * | |
95 | msg_new (u_char msgtype, void *msgbody, u_int32_t seqnum, u_int16_t msglen) | |
96 | { | |
97 | struct msg *new; | |
98 | ||
393deb9b | 99 | new = XCALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg)); |
2d33f157 | 100 | |
101 | new->hdr.version = OSPF_API_VERSION; | |
102 | new->hdr.msgtype = msgtype; | |
103 | new->hdr.msglen = htons (msglen); | |
104 | new->hdr.msgseq = htonl (seqnum); | |
105 | ||
106 | new->s = stream_new (msglen); | |
107 | assert (new->s); | |
108 | stream_put (new->s, msgbody, msglen); | |
109 | ||
110 | return new; | |
111 | } | |
112 | ||
113 | ||
114 | /* Duplicate a message by copying content. */ | |
115 | struct msg * | |
116 | msg_dup (struct msg *msg) | |
117 | { | |
118 | struct msg *new; | |
119 | ||
120 | assert (msg); | |
121 | ||
122 | new = msg_new (msg->hdr.msgtype, STREAM_DATA (msg->s), | |
123 | ntohl (msg->hdr.msgseq), ntohs (msg->hdr.msglen)); | |
124 | return new; | |
125 | } | |
126 | ||
127 | ||
128 | /* XXX only for testing, will be removed */ | |
129 | ||
130 | struct nametab { | |
131 | int value; | |
132 | const char *name; | |
133 | }; | |
134 | ||
135 | const char * | |
136 | ospf_api_typename (int msgtype) | |
137 | { | |
138 | struct nametab NameTab[] = { | |
139 | { MSG_REGISTER_OPAQUETYPE, "Register opaque-type", }, | |
140 | { MSG_UNREGISTER_OPAQUETYPE, "Unregister opaque-type", }, | |
141 | { MSG_REGISTER_EVENT, "Register event", }, | |
142 | { MSG_SYNC_LSDB, "Sync LSDB", }, | |
143 | { MSG_ORIGINATE_REQUEST, "Originate request", }, | |
144 | { MSG_DELETE_REQUEST, "Delete request", }, | |
145 | { MSG_REPLY, "Reply", }, | |
146 | { MSG_READY_NOTIFY, "Ready notify", }, | |
147 | { MSG_LSA_UPDATE_NOTIFY, "LSA update notify", }, | |
148 | { MSG_LSA_DELETE_NOTIFY, "LSA delete notify", }, | |
149 | { MSG_NEW_IF, "New interface", }, | |
150 | { MSG_DEL_IF, "Del interface", }, | |
151 | { MSG_ISM_CHANGE, "ISM change", }, | |
152 | { MSG_NSM_CHANGE, "NSM change", }, | |
153 | }; | |
154 | ||
837d16cc | 155 | int i, n = array_size(NameTab); |
2d33f157 | 156 | const char *name = NULL; |
157 | ||
158 | for (i = 0; i < n; i++) | |
159 | { | |
160 | if (NameTab[i].value == msgtype) | |
161 | { | |
162 | name = NameTab[i].name; | |
163 | break; | |
164 | } | |
165 | } | |
166 | ||
167 | return name ? name : "?"; | |
168 | } | |
169 | ||
170 | const char * | |
171 | ospf_api_errname (int errcode) | |
172 | { | |
173 | struct nametab NameTab[] = { | |
174 | { OSPF_API_OK, "OK", }, | |
175 | { OSPF_API_NOSUCHINTERFACE, "No such interface", }, | |
176 | { OSPF_API_NOSUCHAREA, "No such area", }, | |
177 | { OSPF_API_NOSUCHLSA, "No such LSA", }, | |
178 | { OSPF_API_ILLEGALLSATYPE, "Illegal LSA type", }, | |
179 | { OSPF_API_OPAQUETYPEINUSE, "Opaque type in use", }, | |
180 | { OSPF_API_OPAQUETYPENOTREGISTERED, "Opaque type not registered", }, | |
181 | { OSPF_API_NOTREADY, "Not ready", }, | |
182 | { OSPF_API_NOMEMORY, "No memory", }, | |
183 | { OSPF_API_ERROR, "Other error", }, | |
184 | { OSPF_API_UNDEF, "Undefined", }, | |
185 | }; | |
186 | ||
837d16cc | 187 | int i, n = array_size(NameTab); |
2d33f157 | 188 | const char *name = NULL; |
189 | ||
190 | for (i = 0; i < n; i++) | |
191 | { | |
192 | if (NameTab[i].value == errcode) | |
193 | { | |
194 | name = NameTab[i].name; | |
195 | break; | |
196 | } | |
197 | } | |
198 | ||
199 | return name ? name : "?"; | |
200 | } | |
201 | ||
202 | void | |
203 | msg_print (struct msg *msg) | |
204 | { | |
205 | if (!msg) | |
206 | { | |
e84cc647 | 207 | zlog_debug ("msg_print msg=NULL!\n"); |
2d33f157 | 208 | return; |
209 | } | |
210 | ||
211 | #ifdef ORIGINAL_CODING | |
e84cc647 | 212 | zlog_debug |
2d33f157 | 213 | ("msg=%p msgtype=%d msglen=%d msgseq=%d streamdata=%p streamsize=%lu\n", |
214 | msg, msg->hdr.msgtype, ntohs (msg->hdr.msglen), ntohl (msg->hdr.msgseq), | |
215 | STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); | |
216 | #else /* ORIGINAL_CODING */ | |
217 | /* API message common header part. */ | |
e84cc647 | 218 | zlog_debug |
072990e2 | 219 | ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)", |
2d33f157 | 220 | ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype, |
221 | ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq), | |
222 | STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); | |
223 | ||
224 | /* API message body part. */ | |
225 | #ifdef ndef | |
226 | /* Generic Hex/Ascii dump */ | |
227 | DumpBuf (STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); /* Sorry, deleted! */ | |
228 | #else /* ndef */ | |
229 | /* Message-type dependent dump function. */ | |
230 | #endif /* ndef */ | |
231 | ||
232 | return; | |
233 | #endif /* ORIGINAL_CODING */ | |
234 | } | |
235 | ||
236 | void | |
237 | msg_free (struct msg *msg) | |
238 | { | |
239 | if (msg->s) | |
240 | stream_free (msg->s); | |
241 | ||
242 | XFREE (MTYPE_OSPF_API_MSG, msg); | |
243 | } | |
244 | ||
245 | ||
246 | /* Set sequence number of message */ | |
247 | void | |
248 | msg_set_seq (struct msg *msg, u_int32_t seqnr) | |
249 | { | |
250 | assert (msg); | |
251 | msg->hdr.msgseq = htonl (seqnr); | |
252 | } | |
253 | ||
254 | /* Get sequence number of message */ | |
255 | u_int32_t | |
256 | msg_get_seq (struct msg *msg) | |
257 | { | |
258 | assert (msg); | |
259 | return ntohl (msg->hdr.msgseq); | |
260 | } | |
261 | ||
262 | /* ----------------------------------------------------------- | |
263 | * Message fifo queues | |
264 | * ----------------------------------------------------------- | |
265 | */ | |
266 | ||
267 | struct msg_fifo * | |
268 | msg_fifo_new () | |
269 | { | |
393deb9b | 270 | return XCALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo)); |
2d33f157 | 271 | } |
272 | ||
273 | /* Add new message to fifo. */ | |
274 | void | |
275 | msg_fifo_push (struct msg_fifo *fifo, struct msg *msg) | |
276 | { | |
277 | if (fifo->tail) | |
278 | fifo->tail->next = msg; | |
279 | else | |
280 | fifo->head = msg; | |
281 | ||
282 | fifo->tail = msg; | |
283 | fifo->count++; | |
284 | } | |
285 | ||
286 | ||
287 | /* Remove first message from fifo. */ | |
288 | struct msg * | |
289 | msg_fifo_pop (struct msg_fifo *fifo) | |
290 | { | |
291 | struct msg *msg; | |
292 | ||
293 | msg = fifo->head; | |
294 | if (msg) | |
295 | { | |
296 | fifo->head = msg->next; | |
297 | ||
298 | if (fifo->head == NULL) | |
299 | fifo->tail = NULL; | |
300 | ||
301 | fifo->count--; | |
302 | } | |
303 | return msg; | |
304 | } | |
305 | ||
306 | /* Return first fifo entry but do not remove it. */ | |
307 | struct msg * | |
308 | msg_fifo_head (struct msg_fifo *fifo) | |
309 | { | |
310 | return fifo->head; | |
311 | } | |
312 | ||
313 | /* Flush message fifo. */ | |
314 | void | |
315 | msg_fifo_flush (struct msg_fifo *fifo) | |
316 | { | |
317 | struct msg *op; | |
318 | struct msg *next; | |
319 | ||
320 | for (op = fifo->head; op; op = next) | |
321 | { | |
322 | next = op->next; | |
323 | msg_free (op); | |
324 | } | |
325 | ||
326 | fifo->head = fifo->tail = NULL; | |
327 | fifo->count = 0; | |
328 | } | |
329 | ||
330 | /* Free API message fifo. */ | |
331 | void | |
332 | msg_fifo_free (struct msg_fifo *fifo) | |
333 | { | |
334 | msg_fifo_flush (fifo); | |
335 | ||
336 | XFREE (MTYPE_OSPF_API_FIFO, fifo); | |
337 | } | |
338 | ||
339 | struct msg * | |
340 | msg_read (int fd) | |
341 | { | |
342 | struct msg *msg; | |
343 | struct apimsghdr hdr; | |
3623814a | 344 | u_char buf[OSPF_API_MAX_MSG_SIZE]; |
2d33f157 | 345 | int bodylen; |
346 | int rlen; | |
347 | ||
348 | /* Read message header */ | |
3623814a | 349 | rlen = readn (fd, (u_char *) &hdr, sizeof (struct apimsghdr)); |
2d33f157 | 350 | |
351 | if (rlen < 0) | |
352 | { | |
6099b3b5 | 353 | zlog_warn ("msg_read: readn %s", safe_strerror (errno)); |
2d33f157 | 354 | return NULL; |
355 | } | |
356 | else if (rlen == 0) | |
357 | { | |
358 | zlog_warn ("msg_read: Connection closed by peer"); | |
359 | return NULL; | |
360 | } | |
361 | else if (rlen != sizeof (struct apimsghdr)) | |
362 | { | |
363 | zlog_warn ("msg_read: Cannot read message header!"); | |
364 | return NULL; | |
365 | } | |
366 | ||
367 | /* Check version of API protocol */ | |
368 | if (hdr.version != OSPF_API_VERSION) | |
369 | { | |
370 | zlog_warn ("msg_read: OSPF API protocol version mismatch"); | |
371 | return NULL; | |
372 | } | |
373 | ||
374 | /* Determine body length. */ | |
375 | bodylen = ntohs (hdr.msglen); | |
376 | if (bodylen > 0) | |
377 | { | |
378 | ||
379 | /* Read message body */ | |
380 | rlen = readn (fd, buf, bodylen); | |
381 | if (rlen < 0) | |
382 | { | |
6099b3b5 | 383 | zlog_warn ("msg_read: readn %s", safe_strerror (errno)); |
2d33f157 | 384 | return NULL; |
385 | } | |
386 | else if (rlen == 0) | |
387 | { | |
388 | zlog_warn ("msg_read: Connection closed by peer"); | |
389 | return NULL; | |
390 | } | |
391 | else if (rlen != bodylen) | |
392 | { | |
393 | zlog_warn ("msg_read: Cannot read message body!"); | |
394 | return NULL; | |
395 | } | |
396 | } | |
397 | ||
398 | /* Allocate new message */ | |
399 | msg = msg_new (hdr.msgtype, buf, ntohl (hdr.msgseq), ntohs (hdr.msglen)); | |
400 | ||
401 | return msg; | |
402 | } | |
403 | ||
404 | int | |
405 | msg_write (int fd, struct msg *msg) | |
406 | { | |
407 | u_char buf[OSPF_API_MAX_MSG_SIZE]; | |
408 | int l; | |
409 | int wlen; | |
410 | ||
411 | assert (msg); | |
412 | assert (msg->s); | |
413 | ||
414 | /* Length of message including header */ | |
415 | l = sizeof (struct apimsghdr) + ntohs (msg->hdr.msglen); | |
416 | ||
417 | /* Make contiguous memory buffer for message */ | |
418 | memcpy (buf, &msg->hdr, sizeof (struct apimsghdr)); | |
419 | memcpy (buf + sizeof (struct apimsghdr), STREAM_DATA (msg->s), | |
420 | ntohs (msg->hdr.msglen)); | |
421 | ||
422 | wlen = writen (fd, buf, l); | |
423 | if (wlen < 0) | |
424 | { | |
6099b3b5 | 425 | zlog_warn ("msg_write: writen %s", safe_strerror (errno)); |
2d33f157 | 426 | return -1; |
427 | } | |
428 | else if (wlen == 0) | |
429 | { | |
430 | zlog_warn ("msg_write: Connection closed by peer"); | |
431 | return -1; | |
432 | } | |
433 | else if (wlen != l) | |
434 | { | |
435 | zlog_warn ("msg_write: Cannot write API message"); | |
436 | return -1; | |
437 | } | |
438 | return 0; | |
439 | } | |
440 | ||
441 | /* ----------------------------------------------------------- | |
442 | * Specific messages | |
443 | * ----------------------------------------------------------- | |
444 | */ | |
445 | ||
446 | struct msg * | |
447 | new_msg_register_opaque_type (u_int32_t seqnum, u_char ltype, u_char otype) | |
448 | { | |
449 | struct msg_register_opaque_type rmsg; | |
450 | ||
451 | rmsg.lsatype = ltype; | |
452 | rmsg.opaquetype = otype; | |
453 | memset (&rmsg.pad, 0, sizeof (rmsg.pad)); | |
454 | ||
455 | return msg_new (MSG_REGISTER_OPAQUETYPE, &rmsg, seqnum, | |
456 | sizeof (struct msg_register_opaque_type)); | |
457 | } | |
458 | ||
459 | struct msg * | |
460 | new_msg_register_event (u_int32_t seqnum, struct lsa_filter_type *filter) | |
461 | { | |
462 | u_char buf[OSPF_API_MAX_MSG_SIZE]; | |
463 | struct msg_register_event *emsg; | |
ed2eb093 | 464 | unsigned int len; |
2d33f157 | 465 | |
466 | emsg = (struct msg_register_event *) buf; | |
467 | len = sizeof (struct msg_register_event) + | |
468 | filter->num_areas * sizeof (struct in_addr); | |
469 | emsg->filter.typemask = htons (filter->typemask); | |
470 | emsg->filter.origin = filter->origin; | |
471 | emsg->filter.num_areas = filter->num_areas; | |
c51443f4 DL |
472 | if (len > sizeof (buf)) |
473 | len = sizeof(buf); | |
474 | /* API broken - missing memcpy to fill data */ | |
2d33f157 | 475 | return msg_new (MSG_REGISTER_EVENT, emsg, seqnum, len); |
476 | } | |
477 | ||
478 | struct msg * | |
479 | new_msg_sync_lsdb (u_int32_t seqnum, struct lsa_filter_type *filter) | |
480 | { | |
481 | u_char buf[OSPF_API_MAX_MSG_SIZE]; | |
482 | struct msg_sync_lsdb *smsg; | |
ed2eb093 | 483 | unsigned int len; |
2d33f157 | 484 | |
485 | smsg = (struct msg_sync_lsdb *) buf; | |
486 | len = sizeof (struct msg_sync_lsdb) + | |
487 | filter->num_areas * sizeof (struct in_addr); | |
488 | smsg->filter.typemask = htons (filter->typemask); | |
489 | smsg->filter.origin = filter->origin; | |
490 | smsg->filter.num_areas = filter->num_areas; | |
c51443f4 DL |
491 | if (len > sizeof (buf)) |
492 | len = sizeof(buf); | |
493 | /* API broken - missing memcpy to fill data */ | |
2d33f157 | 494 | return msg_new (MSG_SYNC_LSDB, smsg, seqnum, len); |
495 | } | |
496 | ||
497 | ||
498 | struct msg * | |
499 | new_msg_originate_request (u_int32_t seqnum, | |
500 | struct in_addr ifaddr, | |
501 | struct in_addr area_id, struct lsa_header *data) | |
502 | { | |
503 | struct msg_originate_request *omsg; | |
ed2eb093 | 504 | unsigned int omsglen; |
2d33f157 | 505 | char buf[OSPF_API_MAX_MSG_SIZE]; |
506 | ||
2d33f157 | 507 | omsg = (struct msg_originate_request *) buf; |
508 | omsg->ifaddr = ifaddr; | |
509 | omsg->area_id = area_id; | |
c51443f4 DL |
510 | |
511 | omsglen = ntohs (data->length); | |
512 | if (omsglen > sizeof (buf) - offsetof (struct msg_originate_request, data)) | |
513 | omsglen = sizeof (buf) - offsetof (struct msg_originate_request, data); | |
514 | memcpy (&omsg->data, data, omsglen); | |
515 | omsglen += sizeof (struct msg_originate_request) - sizeof (struct lsa_header); | |
2d33f157 | 516 | |
517 | return msg_new (MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen); | |
518 | } | |
519 | ||
520 | struct msg * | |
521 | new_msg_delete_request (u_int32_t seqnum, | |
522 | struct in_addr area_id, u_char lsa_type, | |
523 | u_char opaque_type, u_int32_t opaque_id) | |
524 | { | |
525 | struct msg_delete_request dmsg; | |
526 | dmsg.area_id = area_id; | |
527 | dmsg.lsa_type = lsa_type; | |
528 | dmsg.opaque_type = opaque_type; | |
529 | dmsg.opaque_id = htonl (opaque_id); | |
530 | memset (&dmsg.pad, 0, sizeof (dmsg.pad)); | |
531 | ||
532 | return msg_new (MSG_DELETE_REQUEST, &dmsg, seqnum, | |
533 | sizeof (struct msg_delete_request)); | |
534 | } | |
535 | ||
536 | ||
537 | struct msg * | |
538 | new_msg_reply (u_int32_t seqnr, u_char rc) | |
539 | { | |
540 | struct msg *msg; | |
541 | struct msg_reply rmsg; | |
542 | ||
543 | /* Set return code */ | |
544 | rmsg.errcode = rc; | |
545 | memset (&rmsg.pad, 0, sizeof (rmsg.pad)); | |
546 | ||
547 | msg = msg_new (MSG_REPLY, &rmsg, seqnr, sizeof (struct msg_reply)); | |
548 | ||
549 | return msg; | |
550 | } | |
551 | ||
552 | struct msg * | |
553 | new_msg_ready_notify (u_int32_t seqnr, u_char lsa_type, | |
554 | u_char opaque_type, struct in_addr addr) | |
555 | { | |
556 | struct msg_ready_notify rmsg; | |
557 | ||
558 | rmsg.lsa_type = lsa_type; | |
559 | rmsg.opaque_type = opaque_type; | |
560 | memset (&rmsg.pad, 0, sizeof (rmsg.pad)); | |
561 | rmsg.addr = addr; | |
562 | ||
563 | return msg_new (MSG_READY_NOTIFY, &rmsg, seqnr, | |
564 | sizeof (struct msg_ready_notify)); | |
565 | } | |
566 | ||
567 | struct msg * | |
568 | new_msg_new_if (u_int32_t seqnr, | |
569 | struct in_addr ifaddr, struct in_addr area_id) | |
570 | { | |
571 | struct msg_new_if nmsg; | |
572 | ||
573 | nmsg.ifaddr = ifaddr; | |
574 | nmsg.area_id = area_id; | |
575 | ||
576 | return msg_new (MSG_NEW_IF, &nmsg, seqnr, sizeof (struct msg_new_if)); | |
577 | } | |
578 | ||
579 | struct msg * | |
580 | new_msg_del_if (u_int32_t seqnr, struct in_addr ifaddr) | |
581 | { | |
582 | struct msg_del_if dmsg; | |
583 | ||
584 | dmsg.ifaddr = ifaddr; | |
585 | ||
586 | return msg_new (MSG_DEL_IF, &dmsg, seqnr, sizeof (struct msg_del_if)); | |
587 | } | |
588 | ||
589 | struct msg * | |
590 | new_msg_ism_change (u_int32_t seqnr, struct in_addr ifaddr, | |
591 | struct in_addr area_id, u_char status) | |
592 | { | |
593 | struct msg_ism_change imsg; | |
594 | ||
595 | imsg.ifaddr = ifaddr; | |
596 | imsg.area_id = area_id; | |
597 | imsg.status = status; | |
598 | memset (&imsg.pad, 0, sizeof (imsg.pad)); | |
599 | ||
600 | return msg_new (MSG_ISM_CHANGE, &imsg, seqnr, | |
601 | sizeof (struct msg_ism_change)); | |
602 | } | |
603 | ||
604 | struct msg * | |
605 | new_msg_nsm_change (u_int32_t seqnr, struct in_addr ifaddr, | |
606 | struct in_addr nbraddr, | |
607 | struct in_addr router_id, u_char status) | |
608 | { | |
609 | struct msg_nsm_change nmsg; | |
610 | ||
611 | nmsg.ifaddr = ifaddr; | |
612 | nmsg.nbraddr = nbraddr; | |
613 | nmsg.router_id = router_id; | |
614 | nmsg.status = status; | |
615 | memset (&nmsg.pad, 0, sizeof (nmsg.pad)); | |
616 | ||
617 | return msg_new (MSG_NSM_CHANGE, &nmsg, seqnr, | |
618 | sizeof (struct msg_nsm_change)); | |
619 | } | |
620 | ||
621 | struct msg * | |
622 | new_msg_lsa_change_notify (u_char msgtype, | |
623 | u_int32_t seqnum, | |
624 | struct in_addr ifaddr, | |
625 | struct in_addr area_id, | |
626 | u_char is_self_originated, struct lsa_header *data) | |
627 | { | |
628 | u_char buf[OSPF_API_MAX_MSG_SIZE]; | |
629 | struct msg_lsa_change_notify *nmsg; | |
ed2eb093 | 630 | unsigned int len; |
2d33f157 | 631 | |
632 | assert (data); | |
633 | ||
634 | nmsg = (struct msg_lsa_change_notify *) buf; | |
2d33f157 | 635 | nmsg->ifaddr = ifaddr; |
636 | nmsg->area_id = area_id; | |
637 | nmsg->is_self_originated = is_self_originated; | |
638 | memset (&nmsg->pad, 0, sizeof (nmsg->pad)); | |
c51443f4 DL |
639 | |
640 | len = ntohs (data->length); | |
641 | if (len > sizeof (buf) - offsetof (struct msg_lsa_change_notify, data)) | |
642 | len = sizeof (buf) - offsetof (struct msg_lsa_change_notify, data); | |
643 | memcpy (&nmsg->data, data, len); | |
644 | len += sizeof (struct msg_lsa_change_notify) - sizeof (struct lsa_header); | |
2d33f157 | 645 | |
646 | return msg_new (msgtype, nmsg, seqnum, len); | |
647 | } | |
648 | ||
649 | #endif /* SUPPORT_OSPF_API */ |