1 /*
2  */
3 
4 /*
5  * Graph.h
6  *
7  * Definitions used to represent a graph of a network
8  *
9  * History
10  *   2004/06/22 : pda/jean   : design
11  *   2006/05/26 : pda/jean   : collect points
12  *   2007/06/15 : pda/jean   : local vlan descriptions
13  *   2008/05/06 : pda        : equipement location
14  *   2008/07/29 : pda/boggia : ssid based metrology
15  */
16 
17 /******************************************************************************
18 Include files for items specific to this file
19 ******************************************************************************/
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <ctype.h>
26 #include <limits.h>
27 
28 /*
29  * For IP address manipulation functions
30  */
31 
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 
36 /******************************************************************************
37 Global definitions used everywhere
38 ******************************************************************************/
39 
40 /*
41  * Facility
42  */
43 
44 #define	NTAB(t)		(sizeof (t) / sizeof (t [0]))
45 
46 /*
47  * Link name (used in interface description) to identify links to outside
48  * of our network.
49  */
50 #define	EXTLINK	"X"
51 
52 /*
53  * Maximum line length (including "network" lines)
54  */
55 
56 #define	MAXLINE	100000
57 
58 /*
59  * Maximum number of Vlans
60  */
61 
62 #define	MAXVLAN	4096
63 
64 /******************************************************************************
65 Dynamic memory object
66 ******************************************************************************/
67 
68 enum mobj_mode
69 {
70     MOBJ_CONST,			/* cannot increase size after init */
71     MOBJ_MALLOC,		/* already allocated areas cannot change */
72     MOBJ_REALLOC,		/* already allocated areas may change address */
73 } ;
74 
75 
76 struct mobj
77 {
78     enum mobj_mode mode ;
79     int maxidx ;		/* used only for MOBJ_CONST or MOBJ_REALLOC */
80     int curidx ;
81     int objsiz ;
82     void *head ;		/* head of a list */
83     void *data ;		/* used only for MOBJ_CONST or MOBJ_REALLOC */
84 } ;
85 typedef struct mobj MOBJ ;
86 
87 MOBJ *mobj_init (int objsiz, enum mobj_mode mode) ;
88 void mobj_close (MOBJ *d) ;
89 void mobj_free (MOBJ *d, void *data) ;
90 void *mobj_alloc (MOBJ *d, int nelem) ;
91 void *mobj_data (MOBJ *d) ;
92 void *mobj_head (MOBJ *d) ;
93 void mobj_sethead (MOBJ *d, void *head) ;
94 void mobj_empty (MOBJ *d) ;
95 int mobj_size (MOBJ *d) ;
96 int mobj_count (MOBJ *d) ;
97 int mobj_read (FILE *fp, MOBJ *d, int nelem) ;
98 int mobj_write (FILE *fp, MOBJ *d) ;
99 
100 #define	MOBJ_ALLOC_INSERT(v,m)	(((v) = mobj_alloc ((m),1)), \
101 				 ((v)->next = mobj_head (m)), \
102 				 (mobj_sethead ((m), (v))) )
103 
104 
105 /*
106  * Global dynamic objects (saved in compiled files)
107  */
108 
109 #define	HASHMOBJIDX		0
110 #define	SYMMOBJIDX		1
111 #define	STRMOBJIDX		2
112 #define	NODEMOBJIDX		3
113 #define	LINKMOBJIDX		4
114 #define	LLISTMOBJIDX		5
115 #define	EQMOBJIDX		6
116 #define	VLANMOBJIDX		7
117 #define	LVLANMOBJIDX		8
118 #define	NETMOBJIDX		9
119 #define	NLISTMOBJIDX		10
120 #define	RNETMOBJIDX		11
121 #define	ROUTEMOBJIDX		12
122 #define SSIDMOBJIDX		13
123 #define SSIDPROBEMOBJIDX	14
124 #define	NB_MOBJ		(SSIDPROBEMOBJIDX+1)
125 
126 #define	hashmobj	(mobjlist [HASHMOBJIDX])
127 #define	symmobj		(mobjlist [SYMMOBJIDX])
128 #define	strmobj		(mobjlist [STRMOBJIDX])
129 #define	nodemobj	(mobjlist [NODEMOBJIDX])
130 #define	linkmobj	(mobjlist [LINKMOBJIDX])
131 #define	llistmobj	(mobjlist [LLISTMOBJIDX])
132 #define	eqmobj		(mobjlist [EQMOBJIDX])
133 #define	vlanmobj	(mobjlist [VLANMOBJIDX])
134 #define	lvlanmobj	(mobjlist [LVLANMOBJIDX])
135 #define	netmobj		(mobjlist [NETMOBJIDX])
136 #define	nlistmobj	(mobjlist [NLISTMOBJIDX])
137 #define	rnetmobj	(mobjlist [RNETMOBJIDX])
138 #define	routemobj	(mobjlist [ROUTEMOBJIDX])
139 #define	ssidmobj	(mobjlist [SSIDMOBJIDX])
140 #define	ssidprobemobj	(mobjlist [SSIDPROBEMOBJIDX])
141 
142 extern MOBJ *mobjlist [] ;
143 
144 void duplicate_graph (MOBJ *new [], MOBJ *old []) ;
145 
146 /******************************************************************************
147 Vlan type
148 ******************************************************************************/
149 
150 typedef int vlan_t ;			/* vlan id */
151 
152 struct vlanlist
153 {
154     vlan_t min, max ;			/* vlan range */
155     struct vlanlist *next ;		/* next in list */
156 } ;
157 
158 #define	NBYTESVLAN	(MAXVLAN/8)
159 
160 typedef unsigned char vlanset_t [NBYTESVLAN] ;
161 #define vlan_zero(tab)		do { int i ; for (i=0;i<NBYTESVLAN;i++) \
162 					tab[i]=0 ; } while (0)
163 #define vlan_fill(tab)		do { int i ; for (i=0;i<NBYTESVLAN;i++) \
164 					tab[i]=UCHAR_MAX ; } while (0)
165 #define	vlan_isset(tab,n)	(tab [n/8] & (1 << (n%8)))
166 #define	vlan_set(tab,n)		(tab [n/8] |= (1 << (n%8)))
167 #define	vlan_clear(tab,n)	(tab [n/8] &= ~(1 << (n%8)))
168 #define	vlan_nextset(tab,n)	do { for (;n<MAXVLAN;n++) \
169 					if (vlan_set(tab,n)) break ; } while (0)
170 
171 void traversed_vlans (vlanset_t vs) ;
172 void print_vlanlist (FILE *fp, vlanset_t vs, int desc) ;
173 
174 /******************************************************************************
175 Miscellaneous functions
176 ******************************************************************************/
177 
178 extern int errorstate ;
179 extern int lineno ;
180 
181 void error (int syserr, char *msg) ;
182 void inconsistency (char *fmt, ...) ;
183 void *my_malloc (size_t s) ;
184 char *append (char *old, char *a) ;
185 
186 /******************************************************************************
187 Symbol table functions
188 ******************************************************************************/
189 
190 struct symtab
191 {
192     char *name ;		/* name (in strmobj) */
193     struct node *node ;		/* node with this name (in nodemobj) */
194     struct link *link ;		/* physical link between eq (in linkmobj) */
195     struct symtab *next ;	/* next symtab (in symmobj) */
196 } ;
197 
198 void symtab_init (void) ;
199 struct symtab *symtab_lookup (char *name) ;
200 struct symtab *symtab_get (char *name) ;
201 
202 #define symtab_to_name(s)	((s)->name)
203 #define symtab_to_node(s)	((s)->node)
204 #define symtab_to_link(s)	((s)->link)
205 
206 
207 /******************************************************************************
208 IP address datatypes and functions
209 ******************************************************************************/
210 
211 #define INET4 1
212 #define INET6 2
213 
214 struct cidr46
215 {
216     int family ;			/* INET4 or INET6 */
217     union
218     {
219 	struct in_addr adr4 ;
220 	struct in6_addr adr6 ;
221     } u ;
222     int preflen ;
223 } ;
224 
225 typedef struct cidr46 ip_t ;
226 
227 #define	IPADDRLEN  sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")
228 typedef char iptext_t [IPADDRLEN+1] ;
229 
230 int ip_pton (char *text, ip_t *cidr) ;
231 int ip_ntop (ip_t *cidr, iptext_t text, int prefix) ;
232 int ip_equal (ip_t *adr1, ip_t *adr2) ;
233 int ip_match (ip_t *adr, ip_t *network, int prefix) ;
234 void ip_netof (ip_t *srcadr, ip_t *dstadr) ;
235 
236 /******************************************************************************
237 Node name management
238 ******************************************************************************/
239 
240 char *new_nodename (char *eqname) ;
241 
242 /******************************************************************************
243 Node management
244 ******************************************************************************/
245 
246 /*
247  * Warning : if a modification of these structures occur, don't
248  * forget to modify the following source files
249  *	absrel.c
250  *	relabs.c
251  *	dupgraph.c
252  *	textread.c
253  *	textwrite.c
254  */
255 
256 enum nodetype
257 {
258     NT_L1,
259     NT_L2,
260     NT_L3,
261     NT_BRIDGE,
262     NT_ROUTER,
263     NT_BRPAT,
264     NT_L2PAT,
265 } ;
266 
267 enum L1type
268 {
269     L1T_DISABLED,
270     L1T_TRUNK,
271     L1T_ETHER,
272 } ;
273 
274 #define	CHAN_DFS	-1
275 
276 struct radio
277 {
278     struct ssid *ssid ;			/* SSID list or NULL if no radio */
279     int channel ;			/* channel frequency ou CHAN_* */
280     int power ;				/* radio power */
281 } ;
282 
283 struct L1
284 {
285     char *ifname ;			/* physical interface name */
286     char *ifdesc ;			/* description */
287     char *link ;			/* physical link name */
288     char *stat ;			/* collect point */
289     struct radio radio ;		/* radio parameters */
290     enum L1type l1type ;
291 } ;
292 
293 struct L2
294 {
295     vlan_t vlan ;
296     int	native ;			/* true if native vlan */
297     char *stat ;			/* collect point */
298     char *ifname ;			/* logical interface name */
299 } ;
300 
301 struct L3
302 {
303     ip_t addr ;				/* IP (v4 or v6) address with mask */
304 } ;
305 
306 #ifdef NOTNEEDED
307 struct bridge
308 {
309     /* nothing */
310 } ;
311 #endif
312 
313 struct router
314 {
315     char *name ;			/* routing instance name */
316 } ;
317 
318 struct L2pat
319 {
320     struct vlanlist *allowed ;
321     vlan_t native ;			/* native vlan or -1 */
322 } ;
323 
324 struct node
325 {
326     char *name ;			/* name of node */
327     struct eq *eq ;			/* equipement */
328     enum nodetype nodetype ;
329     union
330     {
331 	struct L1 l1 ;
332 	struct L2 l2 ;
333 	struct L3 l3 ;
334 	/* nothing for bridge */
335 	struct router router ;
336 	struct L2pat l2pat ;
337 	/* nothing for brpat */
338     } u ;
339     struct linklist *linklist ;
340 
341     /* For graph traversal */
342     vlanset_t vlanset ;			/* vlans transported on this node */
343     int mark ;				/* used by various places. See below */
344 
345     struct node *enext ;		/* next entry in equipement node list */
346     struct node *eprev ;		/* previous entry in equipement node list */
347     struct node *next ;			/* next entry in node list */
348 } ;
349 
350 
351 #define	MK_L2TRANSPORT		(1<<0)	/* used by transport_vlan_on_L2 */
352 #define	MK_SELECTED		(1<<1)	/* used by select_xxx */
353 #define	MK_PORTMAC		(1<<2)	/* used by output_portmac */
354 #define	MK_LAST			MK_SELECTED
355 
356 #define	MK_SET(p,b)		((p)->mark |= (b))
357 #define	MK_CLEAR(p,b)		((p)->mark &= ~(b))
358 #define	MK_ISSET(p,b)		((p)->mark & (b))
359 
360 #define	MK_SELECT(p)		MK_SET ((p), MK_SELECTED)
361 #define	MK_DESELECT(p)		MK_CLEAR ((p), MK_SELECTED)
362 #define	MK_ISSELECTED(p)	MK_ISSET ((p), MK_SELECTED)
363 
364 struct node *create_node (char *name, struct eq *eq, enum nodetype nodetype) ;
365 
366 /******************************************************************************
367 Link management
368 ******************************************************************************/
369 
370 struct link
371 {
372     char *name ;			/* link name if physical link */
373     struct node *node [2] ;		/* interconnected nodes */
374 } ;
375 
376 /*
377  * List of links, generaly used to keep all links connected to a node,
378  * but used also to keep all physical links seen in the input file.
379  */
380 
381 struct linklist
382 {
383     struct link *link ;
384     struct linklist *next ;
385 } ;
386 
387 struct link *create_link (char *name, char *n1, char *n2) ;
388 
389 #define	getlinkpeer(l,n) (((l)->node[0]==(n)) ? (l)->node[1] : (l)->node[0])
390 
391 struct node *get_neighbour (struct node *n, enum nodetype type) ;
392 void check_links (void) ;
393 
394 /******************************************************************************
395 Propagation of vlans in the graph
396 ******************************************************************************/
397 
398 void transport_vlan_on_L2 (struct node *n, vlan_t v) ;
399 
400 /******************************************************************************
401 Equipment list
402 ******************************************************************************/
403 
404 struct eq
405 {
406     char *name ;
407     char *type ;
408     char *model ;
409     char *snmp ;
410     char *location ;
411     int manual ;			/* 1: manual config, 0: obtained from eq */
412 
413     int mark ;				/* used by drawl2 */
414 
415     /* Equipment-level sensor */
416     int ipmac ;
417     int portmac ;
418 
419     /* Equipment list of nodes */
420     struct node *enhead ;
421     struct node *entail ;
422 
423     struct eq *next ;
424 
425 } ;
426 
427 struct eq *eq_lookup (char *name) ;
428 struct eq *eq_get (char *name, int nameinsymtab) ;
429 
430 /******************************************************************************
431 Vlan and attached network list
432 ******************************************************************************/
433 
434 struct network
435 {
436     ip_t addr ;				/* IP (v4 or v6) address with mask */
437     int mark ;
438     struct network *next ;
439 } ;
440 
441 struct netlist
442 {
443     struct network *net ;
444     struct netlist *next ;
445 } ;
446 
447 struct vlan
448 {
449     char *name ;
450     int voice ;				/* 1 if voice vlan */
451     int mark ;
452     struct netlist *netlist ;
453     struct lvlan *lvlan ;		/* local vlan descriptions */
454 } ;
455 
456 /* local vlan descriptions */
457 struct lvlan
458 {
459     vlan_t vlanid ;
460     struct eq *eq ;
461     char *name ;
462     int mark ;
463     struct lvlan *next ;
464 } ;
465 
466 #define	LVLAN_INCOMING	0x1
467 #define	LVLAN_DECLARED	0x2
468 
469 struct network *net_lookup_n (ip_t *addr), *net_get_n (ip_t *addr) ;
470 struct network *net_lookup_p (char *addr), *net_get_p (char *addr) ;
471 
472 /******************************************************************************
473 Routed networks
474 ******************************************************************************/
475 
476 struct route
477 {
478     ip_t net ;
479     ip_t gw ;
480     struct route *next ;
481 } ;
482 
483 /* routed network */
484 struct rnet
485 {
486     struct network *net ;		/* IP (v4 or v6) address with mask */
487     struct node *router ;
488     struct node *l3 ;
489     struct node *l2 ;
490     struct node *l1 ;
491     ip_t vrrpaddr ;
492     int vrrpprio ;
493     struct route *routelist ;
494     struct rnet *next ;
495 } ;
496 
497 /******************************************************************************
498 radio parameters seen on interfaces
499 ******************************************************************************/
500 
501 enum ssid_mode
502 {
503     SSID_OPEN,				/* without authentication */
504     SSID_AUTH,				/* with authentication */
505 } ;
506 
507 /* list of ssid on an L1 (radio) interface */
508 struct ssid
509 {
510     char *name ;			/* SSID name */
511     enum ssid_mode mode ;		/* open or auth */
512     struct ssid *next ;			/* next in list for this interface */
513 } ;
514 
515 /******************************************************************************
516 ssid based metrology
517 ******************************************************************************/
518 
519 enum ssidprobe_mode
520 {
521     SSIDPROBE_ASSOC,			/* number of associated machines */
522     SSIDPROBE_AUTH,			/* number of authenticated users */
523 } ;
524 
525 /* list of all ssid probes for metrology */
526 struct ssidprobe
527 {
528     char *name ;			/* name of probe */
529     struct eq *eq ;
530     struct node *l1 ;
531     struct ssid *ssid ;
532     enum ssidprobe_mode mode ;		/* #associated or #authentified */
533     struct ssidprobe *next ;		/* next in list */
534 } ;
535 
536 /******************************************************************************
537 Graph-file binary format
538 ******************************************************************************/
539 
540 struct mobjhdr
541 {
542     int objsiz ;
543     int objcnt ;
544     int listhead ;
545 } ;
546 
547 struct graphhdr
548 {
549     unsigned int magic ;
550     unsigned int version ;
551     unsigned int nbmobj ;
552     struct mobjhdr mobjhdr [NB_MOBJ] ;
553 } ;
554 
555 #define	MAGIC		0x67726571	/* greq (graph of equipements) */
556 #define	VERSION1	1
557 #define	VERSION2	2
558 #define	VERSION3	3
559 #define	VERSION4	4		/* lvlan */
560 #define	VERSION5	5		/* equipement location */
561 #define	VERSION6	6		/* radio parameters & ssid */
562 #define	VERSION7	7		/* ssid based metrology */
563 #define	VERSION8	8		/* native vlans */
564 #define	VERSION9	9		/* disabled interfaces */
565 #define	VERSION10	10		/* voice vlans */
566 #define	VERSION11	11		/* manual configuration */
567 #define	VERSION12	12		/* ipmac and portmac sensor */
568 #define	VERSION13	13		/* optimization */
569 #define	VERSION14	14		/* logical interface name */
570 
571 void abs_to_rel (MOBJ *graph []) ;
572 void rel_to_abs (MOBJ *graph []) ;
573 
574 /******************************************************************************
575 Input-output functions
576 ******************************************************************************/
577 
578 void text_read (FILE *fpin) ;
579 void text_write (FILE *fpin, char *object) ;
580 
581 void bin_read (FILE *fpin, MOBJ *graph []) ;
582 void bin_write (FILE *fpout, MOBJ *graph []) ;
583 
584 /******************************************************************************
585 Sub-graph selection functions
586 ******************************************************************************/
587 
588 void sel_init (void) ;
589 void sel_end (void) ;
590 char *sel_register (int opt, char *arg) ;
591 void sel_mark (void) ;
592