1 /*
2 */
3
4 #include "graph.h"
5
6 /******************************************************************************
7 Example of output format
8
9
10 eq crc-cc1 cisco WS-C4506 45464748 <manual|auto>
11 iface GigaEthernet0/1
12 <radio>
13 <M123 ou ->
14 <Ether ou Trunk ou Disabled>
15 {X / L33 crc-rc1 ge-0/0/0}
16 <nativevlan ou -1>
17 <desc> {0 {} <ip> ...} {7 <vlan-desc-en-hexa> 172.16.....} ...
18 <all ifaces>
19 vlan <id> <desc> <voip>
20
21 with <radio> = {<channel> <power> <ssid> <ssid> ...} ou {}
22 ******************************************************************************/
23
24 #define LB '{'
25 #define RB '}'
26
27 /******************************************************************************
28 Output routines
29 ******************************************************************************/
30
output_eq(FILE * fp,struct eq * eq)31 void output_eq (FILE *fp, struct eq *eq)
32 {
33 fprintf (fp, "eq %s %s %s %s %s\n", eq->name, eq->type, eq->model,
34 (eq->location == NULL ? "-" : eq->location),
35 (eq->manual ? "manual" : "auto")
36 ) ;
37 }
38
output_iface(FILE * fp,struct node * n)39 void output_iface (FILE *fp, struct node *n)
40 {
41 char *ifname ;
42 char *stat ;
43 char *type ;
44 char *desc ;
45 struct node *peer ;
46 struct linklist *ll1, *ll2, *ll3 ;
47 vlan_t native ;
48
49 ifname = n->u.l1.ifname ;
50 stat = (n->u.l1.stat == NULL) ? "-" : n->u.l1.stat ;
51 switch (n->u.l1.l1type)
52 {
53 case L1T_DISABLED :
54 type = "Disabled" ;
55 break ;
56 case L1T_TRUNK :
57 type = "Trunk" ;
58 break ;
59 case L1T_ETHER :
60 type = "Ether" ;
61 break ;
62 }
63 desc = (n->u.l1.ifdesc == NULL) ? "-" : n->u.l1.ifdesc ;
64
65 fprintf (fp, "iface %s", ifname) ;
66
67 /*
68 * Check radio parameters
69 */
70
71 fprintf (fp, " %c", LB) ;
72 if (n->u.l1.radio.ssid != NULL)
73 {
74 struct ssid *s ;
75
76 switch (n->u.l1.radio.channel)
77 {
78 case CHAN_DFS :
79 fprintf (fp, "dfs") ;
80 break ;
81 default :
82 fprintf (fp, "%d", n->u.l1.radio.channel) ;
83 }
84 fprintf (fp, " %d", n->u.l1.radio.power) ;
85 for (s = n->u.l1.radio.ssid ; s != NULL ; s = s->next)
86 fprintf (fp, " %s", s->name) ;
87 }
88
89 fprintf (fp, "%c %s %s %s", RB, stat, type, desc) ;
90
91 peer = get_neighbour (n, NT_L1) ;
92 if (peer == NULL)
93 fprintf (fp, " {X}") ;
94 else
95 {
96 for (ll1 = n->linklist ; ll1 != NULL ; ll1 = ll1->next)
97 if (getlinkpeer (ll1->link, n) == peer)
98 break ;
99 if (ll1 != NULL)
100 fprintf (fp, " {%s %s %s}",
101 ll1->link->name,
102 peer->eq->name,
103 peer->u.l1.ifname) ;
104 }
105
106 /*
107 * Search all L2 interfaces to detect native vlan if any
108 */
109
110 native = -1 ;
111 for (ll2 = n->linklist ; ll2 != NULL ; ll2 = ll2->next)
112 {
113 struct node *peer2 ;
114
115 peer2 = getlinkpeer (ll2->link, n) ;
116 if (peer2->nodetype == NT_L2 && MK_ISSELECTED (peer2))
117 {
118 if (peer2->u.l2.native)
119 native = peer2->u.l2.vlan ;
120 }
121 }
122 fprintf (fp, " %d", native) ;
123
124 /*
125 * Search all L2 interfaces
126 */
127
128 for (ll2 = n->linklist ; ll2 != NULL ; ll2 = ll2->next)
129 {
130 struct node *peer2 ;
131
132 peer2 = getlinkpeer (ll2->link, n) ;
133 if (peer2->nodetype == NT_L2 && MK_ISSELECTED (peer2))
134 {
135 vlan_t vlanid ;
136 char *desc ;
137 int first ;
138
139 vlanid = peer2->u.l2.vlan ;
140 stat = (peer2->u.l2.stat == NULL) ? "-" : peer2->u.l2.stat ;
141 desc = ((struct vlan *) mobj_data (vlanmobj)) [vlanid].name ;
142 if (desc == NULL)
143 desc = "-" ;
144 fprintf (fp, " %c%d %s %s", LB, vlanid, desc, stat) ;
145
146 /*
147 * Search all L3 interfaces
148 */
149
150 first = 1 ;
151 for (ll3 = peer2->linklist ; ll3 != NULL ; ll3 = ll3->next)
152 {
153 struct node *peer3 ;
154
155 peer3 = getlinkpeer (ll3->link, peer2) ;
156 if (peer3->nodetype == NT_L3)
157 {
158 iptext_t a ;
159
160 if (ip_ntop (&peer3->u.l3.addr, a, 1))
161 {
162 if (first)
163 fprintf (fp, " %c", LB) ;
164 else
165 fprintf (fp, " ") ;
166 fprintf (fp, "%s", a) ;
167 first = 0 ;
168 }
169 }
170 }
171 if (first == 0)
172 fprintf (fp, "%c", RB) ;
173
174 fprintf (fp, "%c", RB) ;
175 }
176 }
177
178 fprintf (fp, "\n") ;
179 }
180
output_vlan(FILE * fp,vlan_t v,struct vlan * vobj,struct eq * eq)181 void output_vlan (FILE *fp, vlan_t v, struct vlan *vobj, struct eq *eq)
182 {
183 struct lvlan *lv ;
184 int found ;
185
186 /*
187 * Is this vlan present on this equipement ?
188 */
189
190 found = 0 ;
191 for (lv = vobj->lvlan ; lv != NULL ; lv = lv->next)
192 {
193 if (lv->eq == eq)
194 {
195 found = 1;
196 break ;
197 }
198 }
199
200 if (found)
201 fprintf (fp, "vlan %d %s %d\n", v, vobj->name, vobj->voice) ;
202 }
203
204 /******************************************************************************
205 Main function
206 ******************************************************************************/
207
208 MOBJ *mobjlist [NB_MOBJ] ;
209
usage(char * progname)210 void usage (char *progname)
211 {
212 fprintf (stderr, "Usage : %s [-a|-n cidr|-v vlan|-e regexp|-E regexp|-t|-m]* eq [iface]\n", progname) ;
213 exit (1) ;
214 }
215
main(int argc,char * argv[])216 int main (int argc, char *argv [])
217 {
218 struct node *n ;
219 char *prog, *errstr ;
220 char *eqname, *iface ;
221 struct eq *eq ;
222 int c, err ;
223 vlan_t v ;
224 struct vlan *vlantab ;
225
226 prog = argv [0] ;
227 err = 0 ;
228
229 sel_init () ;
230
231 while ((c = getopt (argc, argv, "an:e:E:tv:m")) != -1)
232 {
233 switch (c)
234 {
235 case 'a' :
236 case 'n' :
237 case 'e' :
238 case 'E' :
239 case 't' :
240 case 'v' :
241 case 'm' :
242 if ((errstr = sel_register (c, optarg)) != NULL)
243 {
244 fprintf (stderr, "%s: %s\n", prog, errstr) ;
245 err = 1 ;
246 }
247 break ;
248 case '?' :
249 default :
250 usage (prog) ;
251 }
252 }
253
254 if (err)
255 exit (1) ;
256
257 argc -= optind ;
258 argv += optind ;
259
260 switch (argc)
261 {
262 case 1 :
263 eqname = argv [0] ;
264 iface = NULL ;
265 break ;
266 case 2 :
267 eqname = argv [0] ;
268 iface = argv [1] ;
269 break ;
270 default :
271 usage (prog) ;
272 exit (1) ; /* to calm down clang */
273 }
274
275 /*
276 * Read the graph
277 */
278
279 bin_read (stdin, mobjlist) ;
280 sel_mark () ;
281
282 /*
283 * Search selected equipement
284 */
285
286 eq = eq_lookup (eqname) ;
287 if (eq != NULL && MK_ISSELECTED (eq))
288 {
289 /*
290 * Output the final result
291 */
292
293 output_eq (stdout, eq) ;
294
295 for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next)
296 if (n->eq == eq && n->nodetype == NT_L1 && MK_ISSELECTED (n))
297 if (iface == NULL || strcmp (iface, n->u.l1.ifname) == 0)
298 output_iface (stdout, n) ;
299
300 vlantab = mobj_data (vlanmobj) ;
301 for (v = 0 ; v < MAXVLAN ; v++)
302 if (vlantab [v].name != NULL && MK_ISSELECTED (&vlantab [v]))
303 output_vlan (stdout, v, &vlantab [v], eq) ;
304 }
305
306 sel_end () ;
307 exit (0) ;
308 }
309