9 #include <ngadmin.h> /* FIXME */
10 #include <nsdp/protocol.h>
11 #include <nsdp/attr.h>
13 #include <nsdp/misc.h>
16 static void print_password (const char *pass, unsigned int len)
22 for (i = 0; i < len; i++) {
23 if (!isprint(pass[i]))
28 /* all characters are printable, cleartext password assumed */
29 printf("(clear) \"%s\"", pass);
39 passwordEndecode(s, len);
41 for (i = 0; i < len; i++) {
47 /* all characters are printable, encrypted password assumed */
48 printf("(encrypted) \"%s\"", s);
55 /* unknown encoding, fallback to hex display */
57 for (i = 0; i < len; i++)
58 printf("%02x ", (unsigned char)pass[i]);
62 static const char* port_status_str (unsigned char status)
70 return "10M half-duplex";
73 return "10M full-duplex";
76 return "100M half-duplex";
79 return "100M full-duplex";
82 return "1000M full-duplex";
90 static const char* vlan_type_code (unsigned char type)
98 return "basic port based";
101 return "advanced port based";
104 return "basic 802.1Q";
107 return "advanced 802.1Q";
115 static const char* vlan_code_str (unsigned char code)
134 static const char* qos_type_str (unsigned char type)
150 static const char* qos_prio_str (unsigned char prio)
172 static const char* bitrate_str (unsigned int bitrate)
176 case BITRATE_NOLIMIT:
218 static void print_attr (const struct attr *at)
220 unsigned char p, ports, *byte = at->data;
221 unsigned short *word = at->data;
223 struct ether_addr *eth = at->data;
224 struct in_addr *ip = at->data;
225 struct attr_port_status *apsu = at->data;
226 struct attr_port_stat *apsi = at->data;
227 struct attr_cabletest_do *acd = at->data;
228 struct attr_cabletest_result *acr = at->data;
229 struct attr_vlan_conf *avc = at->data;
230 struct attr_pvid *ap = at->data;
231 struct attr_qos *aq = at->data;
232 struct attr_bitrate *ab = at->data;
233 struct attr_mirror *am = at->data;
234 struct attr_igmp_vlan *aiv = at->data;
237 printf("code = %04X, length = %d\n", at->attr, at->size);
240 printf("\tempty\n\n");
248 printf("\tproduct = %s\n", s);
253 printf("\tname = %s\n", s);
257 printf("\tMAC = %s\n", ether_ntoa(eth));
261 printf("\tIP = %s\n", inet_ntoa(*ip));
265 printf("\tnetmask = %s\n", inet_ntoa(*ip));
269 printf("\tgateway = %s\n", inet_ntoa(*ip));
272 case ATTR_NEW_PASSWORD:
273 printf("\tnew password = ");
274 print_password(s, at->size);
279 printf("\tpassword = ");
280 print_password(s, at->size);
285 printf("\tDHCP = %s\n", (at->size == 1 ? *byte : *word) ? "yes" : "no");
290 printf("\tfirmware = %s\n", s);
293 case ATTR_FIRM_UPGRADE:
294 printf("\tfirmware upgrade requested\n");
298 printf("\trestart requested\n");
302 printf("\tpassword must be encrypted\n");
306 printf("\treset parameters requested\n");
309 case ATTR_PORT_STATUS:
310 printf("\tport status\n");
311 printf("\tport = %u\n", apsu->port);
312 printf("\tstate = %s\n", port_status_str(apsu->status));
315 case ATTR_PORT_STATISTICS:
316 printf("\tport statistics\n");
317 printf("\tport = %u\n", apsi->port);
318 printf("\treceived = %llu\n", apsi->recv);
319 printf("\tsend = %llu\n", apsi->sent);
320 printf("\tCRC = %llu\n", apsi->crc);
323 case ATTR_STATS_RESET:
324 printf("\tport statistics reset requested\n");
328 case ATTR_CABLETEST_DO:
329 printf("\tstart cabletest\n");
330 printf("\tport = %u\n", acd->port);
331 printf("\taction = %u\n", acd->action);
334 case ATTR_CABLETEST_RESULT:
335 printf("\tcabletest result\n");
336 printf("\tport = %u\n", acr->port);
338 printf("\tv1 = %u\n", acr->v1);
339 printf("\tv2 = %u\n", acr->v2);
344 printf("\tVLAN type = %s\n", vlan_type_code(*byte));
347 case ATTR_VLAN_PORT_CONF:
348 printf("\tport based VLAN configuration\n");
349 printf("\tVLAN = %u\n", avc->vlan);
350 ports = at->size - sizeof(struct attr_vlan_conf);
351 for (p = 0; p < ports; p++)
352 printf("\tport %d = %s\n", p + 1, vlan_code_str(avc->ports[p]));
355 case ATTR_VLAN_DOT_CONF:
356 printf("\t802.1Q based VLAN configuration\n");
357 printf("\tVLAN = %u\n", avc->vlan);
358 ports = at->size - sizeof(struct attr_vlan_conf);
359 for (p = 0; p < ports; p++)
360 printf("\tport %d = %s\n", p + 1, vlan_code_str(avc->ports[p]));
363 case ATTR_VLAN_DESTROY:
364 printf("\tdestroy VLAN = %u\n", *word);
368 printf("\tVLAN PVID\n");
369 printf("\tport = %u\n", ap->port);
370 printf("\tVLAN = %u\n", ap->vlan);
374 printf("\tQoS type = %s\n", qos_type_str(*byte));
377 case ATTR_QOS_CONFIG:
378 printf("\tQoS configuration\n");
379 printf("\tport = %u\n", aq->port);
380 printf("\tpriority = %s\n", qos_prio_str(aq->prio));
383 case ATTR_BITRATE_INPUT:
384 printf("\tinput bitrate\n");
385 printf("\tport = %u\n", ab->port);
386 printf("\tbitrate = %s\n", bitrate_str(ab->bitrate));
389 case ATTR_BITRATE_OUTPUT:
390 printf("\toutput bitrate\n");
391 printf("\tport = %u\n", ab->port);
392 printf("\tbitrate = %s\n", bitrate_str(ab->bitrate));
395 case ATTR_STORM_ENABLE:
396 printf("\tstorm filtering = %s\n", *byte ? "yes" : "no");
399 case ATTR_STORM_BITRATE:
400 printf("\tstorm filtering bitrate\n");
401 printf("\tport = %u\n", ab->port);
402 printf("\tbitrate = %s\n", bitrate_str(ab->bitrate));
406 printf("\tport mirroring\n");
407 if (am->outport == 0) {
408 printf("\tdisabled\n");
412 printf("\toutput port = %u\n", am->outport);
413 ports = at->size - sizeof(struct attr_mirror);
414 for (p = 0; p < ports; p++)
415 printf("\tport %u = %s\n", p + 1, am->ports[p] ? "yes" : "no");
418 case ATTR_PORTS_COUNT:
419 printf("\tports count = %u\n", *byte);
422 case ATTR_IGMP_ENABLE_VLAN:
423 printf("\tIGMP filtering\n");
424 printf("\tenable = %s\n", aiv->enable ? "yes" : "no");
425 printf("\tVLAN = %u\n", aiv->vlan);
428 case ATTR_IGMP_BLOCK_UNK:
429 printf("\tblock unknown IGMP = %s\n", *byte ? "yes" : "no");
432 case ATTR_IGMP_VALID_V3:
433 printf("\tvalidate IGMPv3 = %s\n", *byte ? "yes" : "no");
437 printf("\tunknown\n");
444 static const char* code_str (unsigned char code)
449 return "read request";
455 return "write request";
458 return "write reply";
466 static const char* error_str (unsigned char err)
476 case ERROR_INVALID_VALUE:
477 return "invalid value";
480 return "access denied";
488 static void print_packet (const List *attr, const struct nsdp_cmd *nc)
491 const struct attr *at;
494 printf("---------------------------------\n");
495 printf("code = %s (%u)\n", code_str(nc->code), nc->code);
496 printf("error = %s (%u)\n", error_str(nc->error), nc->error);
497 if (nc->attr_error != 0)
498 printf("erroneous attribute = %04X\n", nc->attr_error);
499 printf("source address = %s:%u\n", inet_ntoa(nc->remote_addr.sin_addr), ntohs(nc->remote_addr.sin_port));
500 printf("client MAC = %s\n", ether_ntoa(&nc->client_mac));
501 printf("switch MAC = %s\n", ether_ntoa(&nc->switch_mac));
502 printf("sequence number = %u\n\n", nc->seqnum);
503 printf("received %d attribute(s)\n\n", attr->count);
505 for (ln = attr->first; ln != NULL; ln = ln->next) {
510 printf("---------------------------------\n\n");
514 static void handler (int sig)
517 printf("interrupt\n");
523 int err = 0, sw_sock = -1, cl_sock = -1;
526 struct sockaddr_in sw_local, cl_local;
527 struct pollfd fds[2];
531 sw_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
538 cl_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
546 memset(&sw_local, 0, sizeof(struct sockaddr_in));
547 sw_local.sin_family = AF_INET;
548 sw_local.sin_addr.s_addr = htonl(INADDR_ANY);
549 sw_local.sin_port = htons(SWITCH_PORT);
552 cl_local.sin_port = htons(CLIENT_PORT);
554 if (bind(sw_sock, (struct sockaddr*)&sw_local, sizeof(struct sockaddr_in)) < 0) {
560 if (bind(cl_sock, (struct sockaddr*)&cl_local, sizeof(struct sockaddr_in)) < 0) {
567 fds[0].events = POLLIN;
570 fds[1].events = POLLIN;
573 memset(&sa, 0, sizeof(struct sigaction));
574 sa.sa_handler = handler;
575 sigaction(SIGINT, &sa, NULL);
576 sigaction(SIGTERM, &sa, NULL);
578 attr = createEmptyList();
581 err = poll(fds, 2, -1);
585 } else if (err == 0) {
589 memset(&nc, 0, sizeof(struct nsdp_cmd));
590 nc.remote_addr.sin_family = AF_INET;
592 if (fds[0].revents & POLLIN) {
593 nc.remote_addr.sin_port = htons(CLIENT_PORT);
594 err = recvNsdpPacket(sw_sock, &nc, attr, NULL);
596 nc.remote_addr.sin_port = htons(SWITCH_PORT);
597 err = recvNsdpPacket(cl_sock, &nc, attr, NULL);
603 print_packet(attr, &nc);
605 clearList(attr, (void(*)(void*))freeAttr);
608 destroyList(attr, (void(*)(void*))freeAttr);