]> git.sur5r.net Git - ngadmin/blob - spy/src/spy.c
Merge remote-tracking branch 'upstream/master'
[ngadmin] / spy / src / spy.c
1
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <poll.h>
5 #include <ctype.h>
6 #include <signal.h>
7 #include <arpa/inet.h>
8
9 #include <ngadmin.h> /* FIXME */
10 #include <nsdp/protocol.h>
11 #include <nsdp/attr.h>
12 #include <nsdp/net.h>
13 #include <nsdp/str.h>
14
15
16 static void print_password (const char *pass, unsigned int len)
17 {
18         unsigned int i;
19         char *s;
20         
21         
22         if (isStringPrintable(pass, len)) {
23                 /* all characters are printable, cleartext password assumed */
24                 printf("(clear) \"%s\"", pass);
25                 return;
26         }
27         
28         s = malloc(len + 1);
29         if (s == NULL)
30                 return;
31         memcpy(s, pass, len);
32         s[len] = '\0';
33         
34         passwordEndecode(s, len);
35         
36         if (isStringPrintable(s, len)) {
37                 /* all characters are printable, encrypted password assumed */
38                 printf("(encrypted) \"%s\"", s);
39                 free(s);
40                 return;
41         }
42         
43         free(s);
44         
45         /* unknown encoding, fallback to hex display */
46         printf("(hex) ");
47         for (i = 0; i < len; i++)
48                 printf("%02x ", (unsigned char)pass[i]);
49 }
50
51
52 static void print_attr (const struct attr *at)
53 {
54         unsigned char p, ports, *byte = at->data;
55         unsigned short *word = at->data;
56         char *s = at->data;
57         struct ether_addr *eth = at->data;
58         struct in_addr *ip = at->data;
59         struct attr_port_status *apsu = at->data;
60         struct attr_port_stat *apsi = at->data;
61         struct attr_cabletest_do *acd = at->data;
62         struct attr_cabletest_result *acr = at->data;
63         struct attr_vlan_conf *avc = at->data;
64         struct attr_pvid *ap = at->data;
65         struct attr_qos *aq = at->data;
66         struct attr_bitrate *ab = at->data;
67         struct attr_mirror *am = at->data;
68         struct attr_igmp_vlan *aiv = at->data;
69         
70         
71         printf("code = %04X, length = %d\n", at->attr, at->size);
72         
73         if (at->size == 0) {
74                 printf("\tempty\n\n");
75                 return;
76         }
77         
78         switch (at->attr) {
79         
80         case ATTR_PRODUCT:
81                 trim(s, at->size);
82                 printf("\tproduct = %s\n", s);
83                 break;
84         
85         case ATTR_NAME:
86                 trim(s, at->size);
87                 printf("\tname = %s\n", s);
88                 break;
89         
90         case ATTR_MAC:
91                 printf("\tMAC = %s\n", ether_ntoa(eth));
92                 break;
93         
94         case ATTR_IP:
95                 printf("\tIP = %s\n", inet_ntoa(*ip));
96                 break;
97         
98         case ATTR_NETMASK:
99                 printf("\tnetmask = %s\n", inet_ntoa(*ip));
100                 break;
101         
102         case ATTR_GATEWAY:
103                 printf("\tgateway = %s\n", inet_ntoa(*ip));
104                 break;
105         
106         case ATTR_NEW_PASSWORD:
107                 printf("\tnew password = ");
108                 print_password(s, at->size);
109                 printf("\n");
110                 break;
111         
112         case ATTR_PASSWORD:
113                 printf("\tpassword = ");
114                 print_password(s, at->size);
115                 printf("\n");
116                 break;
117         
118         case ATTR_DHCP:
119                 printf("\tDHCP = %s\n", (at->size == 1 ? *byte : *word) ? "yes" : "no");
120                 break;
121         
122         case ATTR_FIRM_VER:
123                 trim(s, at->size);
124                 printf("\tfirmware = %s\n", s);
125                 break;
126         
127         case ATTR_FIRM_UPGRADE:
128                 printf("\tfirmware upgrade requested\n");
129                 break;
130         
131         case ATTR_RESTART:
132                 printf("\trestart requested\n");
133                 break;
134         
135         case ATTR_ENCPASS:
136                 printf("\tpassword must be encrypted\n");
137                 break;
138         
139         case ATTR_DEFAULTS:
140                 printf("\treset parameters requested\n");
141                 break;
142         
143         case ATTR_PORT_STATUS:
144                 printf("\tport status\n");
145                 printf("\tport = %u\n", apsu->port);
146                 printf("\tstate = %s\n", safeStr(getSpeedStr(apsu->status)));
147                 break;
148         
149         case ATTR_PORT_STATISTICS:
150                 printf("\tport statistics\n");
151                 printf("\tport = %u\n", apsi->port);
152                 printf("\treceived = %llu\n", apsi->recv);
153                 printf("\tsend = %llu\n", apsi->sent);
154                 printf("\tCRC = %llu\n", apsi->crc);
155                 break;
156         
157         case ATTR_STATS_RESET:
158                 printf("\tport statistics reset requested\n");
159                 break;
160         
161         
162         case ATTR_CABLETEST_DO:
163                 printf("\tstart cabletest\n");
164                 printf("\tport = %u\n", acd->port);
165                 printf("\taction = %u\n", acd->action);
166                 break;
167         
168         case ATTR_CABLETEST_RESULT:
169                 printf("\tcabletest result\n");
170                 printf("\tport = %u\n", acr->port);
171                 if (at->size > 1) {
172                         printf("\tv1 = %u\n", acr->v1);
173                         printf("\tv2 = %u\n", acr->v2);
174                 }
175                 break;
176         
177         case ATTR_VLAN_TYPE:
178                 printf("\tVLAN type = %s\n", safeStr(getVlanTypeStr(*byte)));
179                 break;
180         
181         case ATTR_VLAN_PORT_CONF:
182                 printf("\tport based VLAN configuration\n");
183                 printf("\tVLAN = %u\n", avc->vlan);
184                 ports = at->size - sizeof(struct attr_vlan_conf);
185                 for (p = 0; p < ports; p++)
186                         printf("\tport %d = %s\n", p + 1, safeStr(getVlanCodeStr(avc->ports[p])));
187                 break;
188         
189         case ATTR_VLAN_DOT_CONF:
190                 printf("\t802.1Q based VLAN configuration\n");
191                 printf("\tVLAN = %u\n", avc->vlan);
192                 ports = at->size - sizeof(struct attr_vlan_conf);
193                 for (p = 0; p < ports; p++)
194                         printf("\tport %d = %s\n", p + 1, safeStr(getVlanCodeStr(avc->ports[p])));
195                 break;
196         
197         case ATTR_VLAN_DESTROY:
198                 printf("\tdestroy VLAN = %u\n", *word);
199                 break;
200         
201         case ATTR_VLAN_PVID:
202                 printf("\tVLAN PVID\n");
203                 printf("\tport = %u\n", ap->port);
204                 printf("\tVLAN = %u\n", ap->vlan);
205                 break;
206         
207         case ATTR_QOS_TYPE:
208                 printf("\tQoS type = %s\n", safeStr(getQosTypeStr(*byte)));
209                 break;
210         
211         case ATTR_QOS_CONFIG:
212                 printf("\tQoS configuration\n");
213                 printf("\tport = %u\n", aq->port);
214                 printf("\tpriority = %s\n", safeStr(getQosPrioStr(aq->prio)));
215                 break;
216         
217         case ATTR_BITRATE_INPUT:
218                 printf("\tinput bitrate\n");
219                 printf("\tport = %u\n", ab->port);
220                 printf("\tbitrate = %s\n", safeStr(getBitrateStr(ab->bitrate)));
221                 break;
222         
223         case ATTR_BITRATE_OUTPUT:
224                 printf("\toutput bitrate\n");
225                 printf("\tport = %u\n", ab->port);
226                 printf("\tbitrate = %s\n", safeStr(getBitrateStr(ab->bitrate)));
227                 break;
228         
229         case ATTR_STORM_ENABLE:
230                 printf("\tstorm filtering = %s\n", *byte ? "yes" : "no");
231                 break;
232         
233         case ATTR_STORM_BITRATE:
234                 printf("\tstorm filtering bitrate\n");
235                 printf("\tport = %u\n", ab->port);
236                 printf("\tbitrate = %s\n", safeStr(getBitrateStr(ab->bitrate)));
237                 break;
238         
239         case ATTR_MIRROR:
240                 printf("\tport mirroring\n");
241                 if (am->outport == 0) {
242                         printf("\tdisabled\n");
243                         break;
244                 }
245                 
246                 printf("\toutput port = %u\n", am->outport);
247                 ports = at->size - sizeof(struct attr_mirror);
248                 for (p = 0; p < ports; p++)
249                         printf("\tport %u = %s\n", p + 1, am->ports[p] ? "yes" : "no");
250                 break;
251         
252         case ATTR_PORTS_COUNT:
253                 printf("\tports count = %u\n", *byte);
254                 break;
255         
256         case ATTR_IGMP_ENABLE_VLAN:
257                 printf("\tIGMP filtering\n");
258                 printf("\tenable = %s\n", aiv->enable ? "yes" : "no");
259                 printf("\tVLAN = %u\n", aiv->vlan);
260                 break;
261         
262         case ATTR_IGMP_BLOCK_UNK:
263                 printf("\tblock unknown IGMP = %s\n", *byte ? "yes" : "no");
264                 break;
265         
266         case ATTR_IGMP_VALID_V3:
267                 printf("\tvalidate IGMPv3 = %s\n", *byte ? "yes" : "no");
268                 break;
269         
270         case ATTR_LOOP_DETECT:
271                 printf("\tloop detection = %s\n", *byte ? "yes" : "no");
272                 break;
273         
274         default:
275                 printf("\tunknown\n");
276         }
277         
278         printf("\n");
279 }
280
281
282 static void print_packet (const List *attr, const struct nsdp_cmd *nc)
283 {
284         const ListNode *ln;
285         const struct attr *at;
286         
287         
288         printf("---------------------------------\n");
289         printf("code = %s (%u)\n", safeStr(getCodeStr(nc->code)), nc->code);
290         printf("error = %s (%u)\n", safeStr(getErrorStr(nc->error)), nc->error);
291         if (nc->attr_error != 0)
292                 printf("erroneous attribute = %04X\n", nc->attr_error);
293         printf("source address = %s:%u\n", inet_ntoa(nc->remote_addr.sin_addr), ntohs(nc->remote_addr.sin_port));
294         printf("client MAC = %s\n", ether_ntoa(&nc->client_mac));
295         printf("switch MAC = %s\n", ether_ntoa(&nc->switch_mac));
296         printf("sequence number = %u\n\n", nc->seqnum);
297         printf("received %d attribute(s)\n\n", attr->count);
298         
299         for (ln = attr->first; ln != NULL; ln = ln->next) {
300                 at = ln->data;
301                 print_attr(at);
302         }
303         
304         printf("---------------------------------\n\n");
305 }
306
307
308 static void handler (int sig)
309 {
310         (void)sig;
311         printf("interrupt\n");
312 }
313
314
315 int main (void)
316 {
317         int err = 0, sw_sock = -1, cl_sock = -1;
318         List *attr;
319         struct nsdp_cmd nc;
320         struct sockaddr_in sw_local, cl_local;
321         struct pollfd fds[2];
322         struct sigaction sa;
323         
324         
325         sw_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
326         if (sw_sock < 0) {
327                 perror("socket");
328                 err = 1;
329                 goto end;
330         };
331         
332         cl_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
333         if (cl_sock < 0) {
334                 perror("socket");
335                 err = 1;
336                 goto end;
337         };
338         
339         
340         memset(&sw_local, 0, sizeof(struct sockaddr_in));
341         sw_local.sin_family = AF_INET;
342         sw_local.sin_addr.s_addr = htonl(INADDR_ANY);
343         sw_local.sin_port = htons(SWITCH_PORT);
344         
345         cl_local = sw_local;
346         cl_local.sin_port = htons(CLIENT_PORT);
347         
348         if (bind(sw_sock, (struct sockaddr*)&sw_local, sizeof(struct sockaddr_in)) < 0) {
349                 perror("bind");
350                 err = 2;
351                 goto end;
352         }
353         
354         if (bind(cl_sock, (struct sockaddr*)&cl_local, sizeof(struct sockaddr_in)) < 0) {
355                 perror("bind");
356                 err = 2;
357                 goto end;
358         }
359         
360         fds[0].fd = sw_sock;
361         fds[0].events = POLLIN;
362         fds[0].revents = 0;
363         fds[1].fd = cl_sock;
364         fds[1].events = POLLIN;
365         fds[1].revents = 0;
366         
367         memset(&sa, 0, sizeof(struct sigaction));
368         sa.sa_handler = handler;
369         sigaction(SIGINT, &sa, NULL);
370         sigaction(SIGTERM, &sa, NULL);
371         
372         attr = createEmptyList();
373         
374         while (1) {
375                 err = poll(fds, 2, -1);
376                 if (err < 0) {
377                         perror("poll");
378                         break;
379                 } else if (err == 0) {
380                         continue;
381                 }
382                 
383                 memset(&nc, 0, sizeof(struct nsdp_cmd));
384                 nc.remote_addr.sin_family = AF_INET;
385                 
386                 if (fds[0].revents & POLLIN) {
387                         nc.remote_addr.sin_port = htons(CLIENT_PORT);
388                         err = recvNsdpPacket(sw_sock, &nc, attr, NULL);
389                 } else {
390                         nc.remote_addr.sin_port = htons(SWITCH_PORT);
391                         err = recvNsdpPacket(cl_sock, &nc, attr, NULL);
392                 }
393                 
394                 if (err < 0)
395                         continue;
396                 
397                 print_packet(attr, &nc);
398                 
399                 clearList(attr, (void(*)(void*))freeAttr);
400         }
401         
402         destroyList(attr, (void(*)(void*))freeAttr);
403         
404 end:
405         close(sw_sock);
406         close(cl_sock);
407         
408         return err;
409 }
410