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)
84 static const char* vlan_type_code (unsigned char type)
92 return "basic port based";
95 return "advanced port based";
98 return "basic 802.1Q";
101 return "advanced 802.1Q";
109 static const char* vlan_code_str (unsigned char code)
128 static const char* qos_type_str (unsigned char type)
144 static const char* qos_prio_str (unsigned char prio)
166 static const char* bitrate_str (unsigned int bitrate)
170 case BITRATE_NOLIMIT:
212 static void print_attr (const struct attr *at)
214 unsigned char p, ports, *byte = at->data;
215 unsigned short *word = at->data;
217 struct ether_addr *eth = at->data;
218 struct in_addr *ip = at->data;
219 struct attr_port_status *apsu = at->data;
220 struct attr_port_stat *apsi = at->data;
221 struct attr_cabletest_do *acd = at->data;
222 struct attr_cabletest_result *acr = at->data;
223 struct attr_vlan_conf *avc = at->data;
224 struct attr_pvid *ap = at->data;
225 struct attr_qos *aq = at->data;
226 struct attr_bitrate *ab = at->data;
227 struct attr_mirror *am = at->data;
228 struct attr_igmp_vlan *aiv = at->data;
231 printf("code = %04X, length = %d\n", at->attr, at->size);
234 printf("\tempty\n\n");
242 printf("\tproduct = %s\n", s);
247 printf("\tname = %s\n", s);
251 printf("\tMAC = %s\n", ether_ntoa(eth));
255 printf("\tIP = %s\n", inet_ntoa(*ip));
259 printf("\tnetmask = %s\n", inet_ntoa(*ip));
263 printf("\tgateway = %s\n", inet_ntoa(*ip));
266 case ATTR_NEW_PASSWORD:
267 printf("\tnew password = ");
268 print_password(s, at->size);
273 printf("\tpassword = ");
274 print_password(s, at->size);
279 printf("\tDHCP = %s\n", (at->size == 1 ? *byte : *word) ? "yes" : "no");
284 printf("\tfirmware = %s\n", s);
287 case ATTR_FIRM_UPGRADE:
288 printf("\tfirmware upgrade requested\n");
292 printf("\trestart requested\n");
296 printf("\tpassword must be encrypted\n");
300 printf("\treset parameters requested\n");
303 case ATTR_PORT_STATUS:
304 printf("\tport status\n");
305 printf("\tport = %u\n", apsu->port);
306 printf("\tstate = %s\n", port_status_str(apsu->status));
309 case ATTR_PORT_STATISTICS:
310 printf("\tport statistics\n");
311 printf("\tport = %u\n", apsi->port);
312 printf("\treceived = %llu\n", apsi->recv);
313 printf("\tsend = %llu\n", apsi->sent);
314 printf("\tCRC = %llu\n", apsi->crc);
317 case ATTR_STATS_RESET:
318 printf("\tport statistics reset requested\n");
322 case ATTR_CABLETEST_DO:
323 printf("\tstart cabletest\n");
324 printf("\tport = %u\n", acd->port);
325 printf("\taction = %u\n", acd->action);
328 case ATTR_CABLETEST_RESULT:
329 printf("\tcabletest result\n");
330 printf("\tport = %u\n", acr->port);
332 printf("\tv1 = %u\n", acr->v1);
333 printf("\tv2 = %u\n", acr->v2);
338 printf("\tVLAN type = %s\n", vlan_type_code(*byte));
341 case ATTR_VLAN_PORT_CONF:
342 printf("\tport based VLAN configuration\n");
343 printf("\tVLAN = %u\n", avc->vlan);
344 ports = at->size - sizeof(struct attr_vlan_conf);
345 for (p = 0; p < ports; p++)
346 printf("\tport %d = %s\n", p + 1, vlan_code_str(avc->ports[p]));
349 case ATTR_VLAN_DOT_CONF:
350 printf("\t802.1Q based VLAN configuration\n");
351 printf("\tVLAN = %u\n", avc->vlan);
352 ports = at->size - sizeof(struct attr_vlan_conf);
353 for (p = 0; p < ports; p++)
354 printf("\tport %d = %s\n", p + 1, vlan_code_str(avc->ports[p]));
357 case ATTR_VLAN_DESTROY:
358 printf("\tdestroy VLAN = %u\n", *word);
362 printf("\tVLAN PVID\n");
363 printf("\tport = %u\n", ap->port);
364 printf("\tVLAN = %u\n", ap->vlan);
368 printf("\tQoS type = %s\n", qos_type_str(*byte));
371 case ATTR_QOS_CONFIG:
372 printf("\tQoS configuration\n");
373 printf("\tport = %u\n", aq->port);
374 printf("\tpriority = %s\n", qos_prio_str(aq->prio));
377 case ATTR_BITRATE_INPUT:
378 printf("\tinput bitrate\n");
379 printf("\tport = %u\n", ab->port);
380 printf("\tbitrate = %s\n", bitrate_str(ab->bitrate));
383 case ATTR_BITRATE_OUTPUT:
384 printf("\toutput bitrate\n");
385 printf("\tport = %u\n", ab->port);
386 printf("\tbitrate = %s\n", bitrate_str(ab->bitrate));
389 case ATTR_STORM_ENABLE:
390 printf("\tstorm filtering = %s\n", *byte ? "yes" : "no");
393 case ATTR_STORM_BITRATE:
394 printf("\tstorm filtering bitrate\n");
395 printf("\tport = %u\n", ab->port);
396 printf("\tbitrate = %s\n", bitrate_str(ab->bitrate));
400 printf("\tport mirroring\n");
401 if (am->outport == 0) {
402 printf("\tdisabled\n");
406 printf("\toutput port = %u\n", am->outport);
407 ports = at->size - sizeof(struct attr_mirror);
408 for (p = 0; p < ports; p++)
409 printf("\tport %u = %s\n", p + 1, am->ports[p] ? "yes" : "no");
412 case ATTR_PORTS_COUNT:
413 printf("\tports count = %u\n", *byte);
416 case ATTR_IGMP_ENABLE_VLAN:
417 printf("\tIGMP filtering\n");
418 printf("\tenable = %s\n", aiv->enable ? "yes" : "no");
419 printf("\tVLAN = %u\n", aiv->vlan);
422 case ATTR_IGMP_BLOCK_UNK:
423 printf("\tblock unknown IGMP = %s\n", *byte ? "yes" : "no");
426 case ATTR_IGMP_VALID_V3:
427 printf("\tvalidate IGMPv3 = %s\n", *byte ? "yes" : "no");
431 printf("\tunknown\n");
438 static const char* code_str (unsigned char code)
443 return "read request";
449 return "write request";
452 return "write reply";
460 static const char* error_str (unsigned char err)
470 case ERROR_INVALID_VALUE:
471 return "invalid value";
474 return "access denied";
482 static void print_packet (const List *attr, const struct nsdp_cmd *nc)
485 const struct attr *at;
488 printf("---------------------------------\n");
489 printf("code = %s (%u)\n", code_str(nc->code), nc->code);
490 printf("error = %s (%u)\n", error_str(nc->error), nc->error);
491 if (nc->attr_error != 0)
492 printf("erroneous attribute = %04X\n", nc->attr_error);
493 printf("source address = %s:%u\n", inet_ntoa(nc->remote_addr.sin_addr), ntohs(nc->remote_addr.sin_port));
494 printf("client MAC = %s\n", ether_ntoa(&nc->client_mac));
495 printf("switch MAC = %s\n", ether_ntoa(&nc->switch_mac));
496 printf("sequence number = %u\n\n", nc->seqnum);
497 printf("received %d attribute(s)\n\n", attr->count);
499 for (ln = attr->first; ln != NULL; ln = ln->next) {
504 printf("---------------------------------\n\n");
508 static void handler (int sig)
511 printf("interrupt\n");
517 int err = 0, sw_sock = -1, cl_sock = -1;
520 struct sockaddr_in sw_local, cl_local;
521 struct pollfd fds[2];
525 sw_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
532 cl_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
540 memset(&sw_local, 0, sizeof(struct sockaddr_in));
541 sw_local.sin_family = AF_INET;
542 sw_local.sin_addr.s_addr = htonl(INADDR_ANY);
543 sw_local.sin_port = htons(SWITCH_PORT);
546 cl_local.sin_port = htons(CLIENT_PORT);
548 if (bind(sw_sock, (struct sockaddr*)&sw_local, sizeof(struct sockaddr_in)) < 0) {
554 if (bind(cl_sock, (struct sockaddr*)&cl_local, sizeof(struct sockaddr_in)) < 0) {
561 fds[0].events = POLLIN;
564 fds[1].events = POLLIN;
567 memset(&sa, 0, sizeof(struct sigaction));
568 sa.sa_handler = handler;
569 sigaction(SIGINT, &sa, NULL);
570 sigaction(SIGTERM, &sa, NULL);
572 attr = createEmptyList();
575 err = poll(fds, 2, -1);
579 } else if (err == 0) {
583 memset(&nc, 0, sizeof(struct nsdp_cmd));
584 nc.remote_addr.sin_family = AF_INET;
586 if (fds[0].revents & POLLIN) {
587 nc.remote_addr.sin_port = htons(CLIENT_PORT);
588 err = recvNsdpPacket(sw_sock, &nc, attr, NULL);
590 nc.remote_addr.sin_port = htons(SWITCH_PORT);
591 err = recvNsdpPacket(cl_sock, &nc, attr, NULL);
597 print_packet(attr, &nc);
599 clearList(attr, (void(*)(void*))freeAttr);
602 destroyList(attr, (void(*)(void*))freeAttr);