Annotation of embedaddon/quagga/ospfd/ospf_api.c, revision 1.1.1.3
1.1 misho 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
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;
68: u_char mydata[];
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;
80: zlog_debug ("apiserver_lsa_print: opaquelen=%d\n", opaquelen);
81:
82: for (i = 0; i < opaquelen; i++)
83: {
84: zlog_debug ("0x%x ", olsa->mydata[i]);
85: }
86: zlog_debug ("\n");
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:
99: new = XCALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg));
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:
1.1.1.2 misho 155: int i, n = array_size(NameTab);
1.1 misho 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:
1.1.1.2 misho 187: int i, n = array_size(NameTab);
1.1 misho 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: {
207: zlog_debug ("msg_print msg=NULL!\n");
208: return;
209: }
210:
211: #ifdef ORIGINAL_CODING
212: zlog_debug
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. */
218: zlog_debug
219: ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",
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: {
270: return XCALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo));
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;
344: u_char buf[OSPF_API_MAX_MSG_SIZE];
345: int bodylen;
346: int rlen;
347:
348: /* Read message header */
349: rlen = readn (fd, (u_char *) &hdr, sizeof (struct apimsghdr));
350:
351: if (rlen < 0)
352: {
353: zlog_warn ("msg_read: readn %s", safe_strerror (errno));
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: {
383: zlog_warn ("msg_read: readn %s", safe_strerror (errno));
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: {
425: zlog_warn ("msg_write: writen %s", safe_strerror (errno));
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;
1.1.1.3 ! misho 464: size_t len;
1.1 misho 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;
1.1.1.3 ! misho 472: if (len > sizeof (buf))
! 473: len = sizeof(buf);
! 474: /* API broken - missing memcpy to fill data */
1.1 misho 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;
1.1.1.3 ! misho 483: size_t len;
1.1 misho 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;
1.1.1.3 ! misho 491: if (len > sizeof (buf))
! 492: len = sizeof(buf);
! 493: /* API broken - missing memcpy to fill data */
1.1 misho 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;
1.1.1.3 ! misho 504: size_t omsglen;
1.1 misho 505: char buf[OSPF_API_MAX_MSG_SIZE];
506:
507: omsg = (struct msg_originate_request *) buf;
508: omsg->ifaddr = ifaddr;
509: omsg->area_id = area_id;
1.1.1.3 ! misho 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);
1.1 misho 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;
1.1.1.3 ! misho 630: size_t len;
1.1 misho 631:
632: assert (data);
633:
634: nmsg = (struct msg_lsa_change_notify *) buf;
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));
1.1.1.3 ! misho 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);
1.1 misho 645:
646: return msg_new (msgtype, nmsg, seqnum, len);
647: }
648:
649: #endif /* SUPPORT_OSPF_API */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>