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