Annotation of embedaddon/quagga/ospfclient/ospfclient.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* This file is part of Quagga.
! 2: *
! 3: * Quagga is free software; you can redistribute it and/or modify it
! 4: * under the terms of the GNU General Public License as published by the
! 5: * Free Software Foundation; either version 2, or (at your option) any
! 6: * later version.
! 7: *
! 8: * Quagga is distributed in the hope that it will be useful, but
! 9: * WITHOUT ANY WARRANTY; without even the implied warranty of
! 10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 11: * General Public License for more details.
! 12: *
! 13: * You should have received a copy of the GNU General Public License
! 14: * along with Quagga; see the file COPYING. If not, write to the Free
! 15: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
! 16: * 02111-1307, USA.
! 17: */
! 18:
1.1 misho 19: /*
20: * Simple program to demonstrate how OSPF API can be used. This
21: * application retrieves the LSDB from the OSPF daemon and then
22: * originates, updates and finally deletes an application-specific
23: * opaque LSA. You can use this application as a template when writing
24: * your own application.
25: */
26:
27: /* The following includes are needed in all OSPF API client
28: applications. */
29:
30: #include <zebra.h>
31: #include "prefix.h" /* needed by ospf_asbr.h */
32: #include "privs.h"
33: #include "log.h"
34:
35: #include "ospfd/ospfd.h"
36: #include "ospfd/ospf_asbr.h"
37: #include "ospfd/ospf_lsa.h"
38: #include "ospfd/ospf_opaque.h"
39: #include "ospfd/ospf_api.h"
40: #include "ospf_apiclient.h"
41:
42: /* privileges struct.
43: * set cap_num_* and uid/gid to nothing to use NULL privs
44: * as ospfapiclient links in libospf.a which uses privs.
45: */
46: struct zebra_privs_t ospfd_privs =
47: {
48: .user = NULL,
49: .group = NULL,
50: .cap_num_p = 0,
51: .cap_num_i = 0
52: };
53:
54: /* The following includes are specific to this application. For
55: example it uses threads from libzebra, however your application is
56: free to use any thread library (like pthreads). */
57:
58: #include "ospfd/ospf_dump.h" /* for ospf_lsa_header_dump */
59: #include "thread.h"
60: #include "log.h"
61:
62: /* Local portnumber for async channel. Note that OSPF API library will also
63: allocate a sync channel at ASYNCPORT+1. */
64: #define ASYNCPORT 4000
65:
66: /* Master thread */
67: struct thread_master *master;
68:
69: /* Global variables */
70: struct ospf_apiclient *oclient;
71: char **args;
72:
73: /* Our opaque LSAs have the following format. */
74: struct my_opaque_lsa
75: {
76: struct lsa_header hdr; /* include common LSA header */
77: u_char data[4]; /* our own data format then follows here */
78: };
79:
80:
81: /* ---------------------------------------------------------
82: * Threads for asynchronous messages and LSA update/delete
83: * ---------------------------------------------------------
84: */
85:
86: static int
87: lsa_delete (struct thread *t)
88: {
89: struct ospf_apiclient *oclient;
90: struct in_addr area_id;
91: int rc;
92:
93: oclient = THREAD_ARG (t);
94:
95: inet_aton (args[6], &area_id);
96:
97: printf ("Deleting LSA... ");
98: rc = ospf_apiclient_lsa_delete (oclient,
99: area_id,
100: atoi (args[2]), /* lsa type */
101: atoi (args[3]), /* opaque type */
102: atoi (args[4])); /* opaque ID */
103: printf ("done, return code is = %d\n", rc);
104: return rc;
105: }
106:
107: static int
108: lsa_inject (struct thread *t)
109: {
110: struct ospf_apiclient *cl;
111: struct in_addr ifaddr;
112: struct in_addr area_id;
113: u_char lsa_type;
114: u_char opaque_type;
115: u_int32_t opaque_id;
116: void *opaquedata;
117: int opaquelen;
118:
119: static u_int32_t counter = 1; /* Incremented each time invoked */
120: int rc;
121:
122: cl = THREAD_ARG (t);
123:
124: inet_aton (args[5], &ifaddr);
125: inet_aton (args[6], &area_id);
126: lsa_type = atoi (args[2]);
127: opaque_type = atoi (args[3]);
128: opaque_id = atoi (args[4]);
129: opaquedata = &counter;
130: opaquelen = sizeof (u_int32_t);
131:
132: printf ("Originating/updating LSA with counter=%d... ", counter);
133: rc = ospf_apiclient_lsa_originate(cl, ifaddr, area_id,
134: lsa_type,
135: opaque_type, opaque_id,
136: opaquedata, opaquelen);
137:
138: printf ("done, return code is %d\n", rc);
139:
140: counter++;
141:
142: return 0;
143: }
144:
145:
146: /* This thread handles asynchronous messages coming in from the OSPF
147: API server */
148: static int
149: lsa_read (struct thread *thread)
150: {
151: struct ospf_apiclient *oclient;
152: int fd;
153: int ret;
154:
155: printf ("lsa_read called\n");
156:
157: oclient = THREAD_ARG (thread);
158: fd = THREAD_FD (thread);
159:
160: /* Handle asynchronous message */
161: ret = ospf_apiclient_handle_async (oclient);
162: if (ret < 0) {
163: printf ("Connection closed, exiting...");
164: exit(0);
165: }
166:
167: /* Reschedule read thread */
168: thread_add_read (master, lsa_read, oclient, fd);
169:
170: return 0;
171: }
172:
173: /* ---------------------------------------------------------
174: * Callback functions for asynchronous events
175: * ---------------------------------------------------------
176: */
177:
178: static void
179: lsa_update_callback (struct in_addr ifaddr, struct in_addr area_id,
180: u_char is_self_originated,
181: struct lsa_header *lsa)
182: {
183: printf ("lsa_update_callback: ");
184: printf ("ifaddr: %s ", inet_ntoa (ifaddr));
185: printf ("area: %s\n", inet_ntoa (area_id));
186: printf ("is_self_origin: %u\n", is_self_originated);
187:
188: /* It is important to note that lsa_header does indeed include the
189: header and the LSA payload. To access the payload, first check
190: the LSA type and then typecast lsa into the corresponding type,
191: e.g.:
192:
193: if (lsa->type == OSPF_ROUTER_LSA) {
194: struct router_lsa *rl = (struct router_lsa) lsa;
195: ...
196: u_int16_t links = rl->links;
197: ...
198: }
199: */
200:
201: ospf_lsa_header_dump (lsa);
202: }
203:
204: static void
205: lsa_delete_callback (struct in_addr ifaddr, struct in_addr area_id,
206: u_char is_self_originated,
207: struct lsa_header *lsa)
208: {
209: printf ("lsa_delete_callback: ");
210: printf ("ifaddr: %s ", inet_ntoa (ifaddr));
211: printf ("area: %s\n", inet_ntoa (area_id));
212: printf ("is_self_origin: %u\n", is_self_originated);
213:
214: ospf_lsa_header_dump (lsa);
215: }
216:
217: static void
218: ready_callback (u_char lsa_type, u_char opaque_type, struct in_addr addr)
219: {
220: printf ("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
221: lsa_type, opaque_type, inet_ntoa (addr));
222:
223: /* Schedule opaque LSA originate in 5 secs */
224: thread_add_timer (master, lsa_inject, oclient, 5);
225:
226: /* Schedule opaque LSA update with new value */
227: thread_add_timer (master, lsa_inject, oclient, 10);
228:
229: /* Schedule delete */
230: thread_add_timer (master, lsa_delete, oclient, 30);
231: }
232:
233: static void
234: new_if_callback (struct in_addr ifaddr, struct in_addr area_id)
235: {
236: printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr));
237: printf ("area_id: %s\n", inet_ntoa (area_id));
238: }
239:
240: static void
241: del_if_callback (struct in_addr ifaddr)
242: {
243: printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr));
244: }
245:
246: static void
247: ism_change_callback (struct in_addr ifaddr, struct in_addr area_id,
248: u_char state)
249: {
250: printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr));
251: printf ("area_id: %s\n", inet_ntoa (area_id));
252: printf ("state: %d [%s]\n", state, LOOKUP (ospf_ism_state_msg, state));
253: }
254:
255: static void
256: nsm_change_callback (struct in_addr ifaddr, struct in_addr nbraddr,
257: struct in_addr router_id, u_char state)
258: {
259: printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr));
260: printf ("nbraddr: %s\n", inet_ntoa (nbraddr));
261: printf ("router_id: %s\n", inet_ntoa (router_id));
262: printf ("state: %d [%s]\n", state, LOOKUP (ospf_nsm_state_msg, state));
263: }
264:
265:
266: /* ---------------------------------------------------------
267: * Main program
268: * ---------------------------------------------------------
269: */
270:
271: static int usage()
272: {
273: printf("Usage: ospfclient <ospfd> <lsatype> <opaquetype> <opaqueid> <ifaddr> <areaid>\n");
274: printf("where ospfd : router where API-enabled OSPF daemon is running\n");
275: printf(" lsatype : either 9, 10, or 11 depending on flooding scope\n");
276: printf(" opaquetype: 0-255 (e.g., experimental applications use > 128)\n");
277: printf(" opaqueid : arbitrary application instance (24 bits)\n");
278: printf(" ifaddr : interface IP address (for type 9) otherwise ignored\n");
279: printf(" areaid : area in IP address format (for type 10) otherwise ignored\n");
280:
281: exit(1);
282: }
283:
284: int
285: main (int argc, char *argv[])
286: {
287: struct thread thread;
288:
289: args = argv;
290:
291: /* ospfclient should be started with the following arguments:
292: *
293: * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr
294: * (6) area_id
295: *
296: * host: name or IP of host where ospfd is running
297: * lsa_type: 9, 10, or 11
298: * opaque_type: 0-255 (e.g., experimental applications use > 128)
299: * opaque_id: arbitrary application instance (24 bits)
300: * if_addr: interface IP address (for type 9) otherwise ignored
301: * area_id: area in IP address format (for type 10) otherwise ignored
302: */
303:
304: if (argc != 7)
305: {
306: usage();
307: }
308:
309: /* Initialization */
310: zprivs_init (&ospfd_privs);
311: master = thread_master_create ();
312:
313: /* Open connection to OSPF daemon */
314: oclient = ospf_apiclient_connect (args[1], ASYNCPORT);
315: if (!oclient)
316: {
317: printf ("Connecting to OSPF daemon on %s failed!\n",
318: args[1]);
319: exit (1);
320: }
321:
322: /* Register callback functions. */
323: ospf_apiclient_register_callback (oclient,
324: ready_callback,
325: new_if_callback,
326: del_if_callback,
327: ism_change_callback,
328: nsm_change_callback,
329: lsa_update_callback,
330: lsa_delete_callback);
331:
332: /* Register LSA type and opaque type. */
333: ospf_apiclient_register_opaque_type (oclient, atoi (args[2]),
334: atoi (args[3]));
335:
336: /* Synchronize database with OSPF daemon. */
337: ospf_apiclient_sync_lsdb (oclient);
338:
339: /* Schedule thread that handles asynchronous messages */
340: thread_add_read (master, lsa_read, oclient, oclient->fd_async);
341:
342: /* Now connection is established, run loop */
343: while (1)
344: {
345: thread_fetch (master, &thread);
346: thread_call (&thread);
347: }
348:
349: /* Never reached */
350: return 0;
351: }
352:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>