7 static const struct timeval default_timeout={.tv_sec=3, .tv_usec=0};
11 // ---------------------------------------------
12 struct ngadmin* ngadmin_init (const char *iface) {
17 // allocate main structure
18 nga=malloc(sizeof(struct ngadmin));
19 memset(nga, 0, sizeof(struct ngadmin));
21 strncpy(nga->iface, iface, IFNAMSIZ-1);
23 if ( startNetwork(nga)<0 ) {
28 nga->timeout=default_timeout;
29 if ( updateTimeout(nga)<0 ) {
41 // ------------------------------------
42 int ngadmin_close (struct ngadmin *nga) {
60 // ---------------------------------------------
61 int ngadmin_forceInterface (struct ngadmin *nga) {
69 if ( forceInterface(nga)!=0 ) {
79 // --------------------------------------------------------------
80 int ngadmin_setKeepBroadcasting (struct ngadmin *nga, bool value) {
97 // ------------------------------------------------------------
98 int ngadmin_setPassword (struct ngadmin *nga, const char *pass) {
105 strncpy(nga->password, pass, PASSWORD_MAX);
114 // -------------------------------------------------------------------
115 int ngadmin_setTimeout (struct ngadmin *nga, const struct timeval *tv) {
120 if ( nga==NULL || tv==NULL ) {
126 if ( updateTimeout(nga)<0 ) {
137 // -----------------------------------
138 int ngadmin_scan (struct ngadmin *nga) {
141 List *attr, *swiList;
144 sent by official win client:
160 static const unsigned short hello[]={
184 // create attributes for an "hello" request
185 attr=createEmptyList();
187 pushBackList(attr, newEmptyAttr(hello[i]));
188 if ( hello[i]==ATTR_END ) break;
191 // send request to all potential switches
192 i=sendNgPacket(nga, CODE_READ_REQ, attr);
193 destroyList(attr, (void(*)(void*))freeAttr);
199 // try to receive any packets until timeout
200 swiList=createEmptyList();
201 while ( (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))!=NULL ) {
202 sa=malloc(sizeof(struct swi_attr));
203 extractSwitchAttributes(sa, attr);
204 destroyList(attr, (void(*)(void*))freeAttr);
205 pushBackList(swiList, sa);
208 nga->swi_count=swiList->count;
209 nga->swi_tab=convertToArray(swiList, sizeof(struct swi_attr));
218 // -----------------------------------------------------------------------
219 const struct swi_attr* ngadmin_getSwitchTab (struct ngadmin *nga, int *nb) {
222 if ( nga==NULL || nb==NULL ) {
236 // ------------------------------------------------------------------
237 const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga) {
251 // --------------------------------------------
252 int ngadmin_login (struct ngadmin *nga, int id) {
258 unsigned short attr_error;
263 } else if ( id<0 || id>=nga->swi_count ) {
268 sa=&nga->swi_tab[id];
271 attr=createEmptyList();
272 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
273 pushBackList(attr, newEmptyAttr(ATTR_END));
274 i=sendNgPacket(nga, CODE_READ_REQ, attr);
275 destroyList(attr, (void(*)(void*))freeAttr);
276 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, &err, &attr_error))==NULL ) {
283 destroyList(attr, (void(*)(void*))freeAttr);
284 if ( err==7 && attr_error==ATTR_PASSWORD ) {
300 // -------------------------------------------------------------------
301 int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) {
310 if ( nga==NULL || ports==NULL ) {
312 } else if ( nga->current==NULL ) {
317 attr=createEmptyList();
318 pushBackList(attr, newEmptyAttr(ATTR_PORT_STATUS));
319 pushBackList(attr, newEmptyAttr(ATTR_END));
320 i=sendNgPacket(nga, CODE_READ_REQ, attr);
321 destroyList(attr, (void(*)(void*))freeAttr);
322 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
327 for (ln=attr->first; ln!=NULL; ln=ln->next) {
330 if ( at->attr==ATTR_PORT_STATUS && at->size>=2 && (i=p[0]-1)>=0 && i<nga->current->ports ) {
335 destroyList(attr, (void(*)(void*))freeAttr);
346 // --------------------------------------------------------
347 int ngadmin_setName (struct ngadmin *nga, const char *name) {
352 unsigned short attr_error;
357 } else if ( nga->current==NULL ) {
362 attr=createEmptyList();
363 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
365 pushBackList(attr, newEmptyAttr(ATTR_NAME));
367 pushBackList(attr, newAttr(ATTR_NAME, strlen(name), strdup(name)));
369 pushBackList(attr, newEmptyAttr(ATTR_END));
370 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
371 destroyList(attr, (void(*)(void*))freeAttr);
372 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
377 destroyList(attr, (void(*)(void*))freeAttr);
378 if ( err==7 && attr_error==ATTR_PASSWORD ) {
384 // successful, also update local name
386 nga->current->name[0]=0;
388 strncpy(nga->current->name, name, NAME_SIZE);
400 // ------------------------------------------------------------------------
401 int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) {
410 if ( nga==NULL || ps==NULL ) {
412 } else if ( nga->current==NULL ) {
417 attr=createEmptyList();
418 pushBackList(attr, newEmptyAttr(ATTR_PORT_STATISTICS));
419 pushBackList(attr, newEmptyAttr(ATTR_END));
420 i=sendNgPacket(nga, CODE_READ_REQ, attr);
421 destroyList(attr, (void(*)(void*))freeAttr);
422 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
427 for (ln=attr->first; ln!=NULL; ln=ln->next) {
429 if ( at->attr==ATTR_PORT_STATISTICS && at->size>=49 && (port=(int)(*(char*)at->data)-1)>=0 && port<nga->current->ports ) {
430 ps[port].recv=be64toh(*(unsigned long long*)(at->data+1+8*0));
431 ps[port].sent=be64toh(*(unsigned long long*)(at->data+1+8*1));
432 ps[port].crc=be64toh(*(unsigned long long*)(at->data+1+8*5));
433 // all offsets between 2 and 4 inclusive are unknown values
437 destroyList(attr, (void(*)(void*))freeAttr);
448 // ---------------------------------------------------
449 int ngadmin_resetPortsStatistics (struct ngadmin *nga) {
454 unsigned short attr_error;
459 } else if ( nga->current==NULL ) {
464 attr=createEmptyList();
465 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
466 pushBackList(attr, newByteAttr(ATTR_STATS_RESET, 1));
467 pushBackList(attr, newEmptyAttr(ATTR_END));
468 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
469 destroyList(attr, (void(*)(void*))freeAttr);
470 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
475 destroyList(attr, (void(*)(void*))freeAttr);
477 if ( err==7 && attr_error==ATTR_PASSWORD ) {
492 // ---------------------------------------------------------------
493 int ngadmin_changePassword (struct ngadmin *nga, const char* pass) {
498 unsigned short attr_error;
501 if ( nga==NULL || pass==NULL ) {
503 } else if ( nga->current==NULL ) {
508 attr=createEmptyList();
509 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
510 pushBackList(attr, newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass)));
511 pushBackList(attr, newEmptyAttr(ATTR_END));
512 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
513 destroyList(attr, (void(*)(void*))freeAttr);
514 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
519 destroyList(attr, (void(*)(void*))freeAttr);
521 if ( err==7 && attr_error==ATTR_PASSWORD ) {
527 // successful, also update local password
528 strncpy(nga->password, pass, PASSWORD_MAX);
539 // ----------------------------------------------------------
540 int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) {
548 if ( nga==NULL || s==NULL ) {
550 } else if ( nga->current==NULL ) {
555 attr=createEmptyList();
556 pushBackList(attr, newEmptyAttr(ATTR_STORM_ENABLE));
557 pushBackList(attr, newEmptyAttr(ATTR_END));
558 i=sendNgPacket(nga, CODE_READ_REQ, attr);
559 destroyList(attr, (void(*)(void*))freeAttr);
560 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
565 for (ln=attr->first; ln!=NULL; ln=ln->next) {
567 if ( at->attr==ATTR_STORM_ENABLE && at->size>=1 ) {
568 *s= *(char*)at->data!=0 ;
573 destroyList(attr, (void(*)(void*))freeAttr);
584 // ---------------------------------------------------------
585 int ngadmin_setStormFilterState (struct ngadmin *nga, int s) {
590 unsigned short attr_error;
595 } else if ( nga->current==NULL ) {
600 attr=createEmptyList();
601 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
602 pushBackList(attr, newByteAttr(ATTR_STORM_ENABLE, s!=0));
603 pushBackList(attr, newEmptyAttr(ATTR_END));
604 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
605 destroyList(attr, (void(*)(void*))freeAttr);
606 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
611 destroyList(attr, (void(*)(void*))freeAttr);
613 if ( err==7 && attr_error==ATTR_PASSWORD ) {
627 // ---------------------------------------------------------------
628 int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) {
636 if ( nga==NULL || ports==NULL ) {
638 } else if ( nga->current==NULL ) {
643 attr=createEmptyList();
644 pushBackList(attr, newEmptyAttr(ATTR_STORM_BITRATE));
645 pushBackList(attr, newEmptyAttr(ATTR_END));
646 i=sendNgPacket(nga, CODE_READ_REQ, attr);
647 destroyList(attr, (void(*)(void*))freeAttr);
648 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
653 for (ln=attr->first; ln!=NULL; ln=ln->next) {
655 if ( at->attr==ATTR_STORM_BITRATE && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
656 ports[i]=ntohl(*(int*)(1+(char*)at->data));
660 destroyList(attr, (void(*)(void*))freeAttr);
671 // ---------------------------------------------------------------------
672 int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) {
677 unsigned short attr_error;
681 if ( nga==NULL || ports==NULL ) {
683 } else if ( nga->current==NULL ) {
688 attr=createEmptyList();
689 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
691 for (i=0; i<nga->current->ports; ++i) {
692 if ( ports[i]>=0 && ports[i]<=11 ) {
695 *(int*)(p+1)=htonl(ports[i]);
696 pushBackList(attr, newAttr(ATTR_STORM_BITRATE, 5, p));
700 pushBackList(attr, newEmptyAttr(ATTR_END));
701 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
702 destroyList(attr, (void(*)(void*))freeAttr);
703 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
708 destroyList(attr, (void(*)(void*))freeAttr);
710 if ( err==7 && attr_error==ATTR_PASSWORD ) {
724 // -----------------------------------------------------------
725 int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) {
733 if ( nga==NULL || ports==NULL ) {
735 } else if ( nga->current==NULL ) {
740 attr=createEmptyList();
741 pushBackList(attr, newEmptyAttr(ATTR_BITRATE_INPUT));
742 pushBackList(attr, newEmptyAttr(ATTR_BITRATE_OUTPUT));
743 pushBackList(attr, newEmptyAttr(ATTR_END));
744 i=sendNgPacket(nga, CODE_READ_REQ, attr);
745 destroyList(attr, (void(*)(void*))freeAttr);
746 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
751 for (ln=attr->first; ln!=NULL; ln=ln->next) {
753 if ( at->attr==ATTR_BITRATE_INPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
754 ports[i*2+0]=ntohl(*(int*)(1+(char*)at->data));
755 } else if ( at->attr==ATTR_BITRATE_OUTPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
756 ports[i*2+1]=ntohl(*(int*)(1+(char*)at->data));
760 destroyList(attr, (void(*)(void*))freeAttr);
771 // -----------------------------------------------------------------
772 int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) {
777 unsigned short attr_error;
781 if ( nga==NULL || ports==NULL ) {
783 } else if ( nga->current==NULL ) {
788 attr=createEmptyList();
789 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
791 for (i=0; i<nga->current->ports; ++i) {
792 if ( ports[2*i+0]>=0 && ports[2*i+0]<=11 ) {
795 *(int*)(p+1)=htonl(ports[2*i+0]);
796 pushBackList(attr, newAttr(ATTR_BITRATE_INPUT, 5, p));
798 if ( ports[2*i+1]>=0 && ports[2*i+1]<=11 ) {
801 *(int*)(p+1)=htonl(ports[2*i+1]);
802 pushBackList(attr, newAttr(ATTR_BITRATE_OUTPUT, 5, p));
806 pushBackList(attr, newEmptyAttr(ATTR_END));
807 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
808 destroyList(attr, (void(*)(void*))freeAttr);
809 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
814 destroyList(attr, (void(*)(void*))freeAttr);
816 if ( err==7 && attr_error==ATTR_PASSWORD ) {
830 // -------------------------------------------------
831 int ngadmin_getQOSMode (struct ngadmin *nga, int *s) {
839 if ( nga==NULL || s==NULL ) {
841 } else if ( nga->current==NULL ) {
846 attr=createEmptyList();
847 pushBackList(attr, newEmptyAttr(ATTR_QOS_TYPE));
848 pushBackList(attr, newEmptyAttr(ATTR_END));
849 i=sendNgPacket(nga, CODE_READ_REQ, attr);
850 destroyList(attr, (void(*)(void*))freeAttr);
851 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
856 for (ln=attr->first; ln!=NULL; ln=ln->next) {
858 if ( at->attr==ATTR_QOS_TYPE && at->size>=1 ) {
859 *s= *(char*)at->data ;
864 destroyList(attr, (void(*)(void*))freeAttr);
874 // ------------------------------------------------
875 int ngadmin_setQOSMode (struct ngadmin *nga, int s) {
880 unsigned short attr_error;
883 if ( nga==NULL || s<1 || s>2 ) {
885 } else if ( nga->current==NULL ) {
890 attr=createEmptyList();
891 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
892 pushBackList(attr, newByteAttr(ATTR_QOS_TYPE, s));
893 pushBackList(attr, newEmptyAttr(ATTR_END));
894 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
895 destroyList(attr, (void(*)(void*))freeAttr);
896 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
901 destroyList(attr, (void(*)(void*))freeAttr);
903 if ( err==7 && attr_error==ATTR_PASSWORD ) {
917 // -------------------------------------------------------
918 int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) {
927 if ( nga==NULL || ports==NULL ) {
929 } else if ( nga->current==NULL ) {
934 attr=createEmptyList();
935 pushBackList(attr, newEmptyAttr(ATTR_QOS_CONFIG));
936 pushBackList(attr, newEmptyAttr(ATTR_END));
937 i=sendNgPacket(nga, CODE_READ_REQ, attr);
938 destroyList(attr, (void(*)(void*))freeAttr);
939 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
944 for (ln=attr->first; ln!=NULL; ln=ln->next) {
947 if ( at->attr==ATTR_QOS_CONFIG && at->size>=2 && --p[0]>=0 && p[0]<nga->current->ports ) {
948 ports[(int)p[0]]=p[1];
952 destroyList(attr, (void(*)(void*))freeAttr);
963 // --------------------------------------------------------------
964 int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) {
969 unsigned short attr_error;
973 if ( nga==NULL || ports==NULL ) {
975 } else if ( nga->current==NULL ) {
980 attr=createEmptyList();
981 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
983 for (i=0; i<nga->current->ports; ++i) {
984 if ( ports[i]>=PRIO_HIGH && ports[i]<=PRIO_LOW ) {
988 pushBackList(attr, newAttr(ATTR_QOS_CONFIG, 2, p));
992 pushBackList(attr, newEmptyAttr(ATTR_END));
993 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
994 destroyList(attr, (void(*)(void*))freeAttr);
995 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
1000 destroyList(attr, (void(*)(void*))freeAttr);
1002 if ( err==7 && attr_error==ATTR_PASSWORD ) {
1016 // --------------------------------------
1017 int ngadmin_restart (struct ngadmin *nga) {
1022 unsigned short attr_error;
1027 } else if ( nga->current==NULL ) {
1032 attr=createEmptyList();
1033 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
1034 pushBackList(attr, newByteAttr(ATTR_RESTART, 1));
1035 pushBackList(attr, newEmptyAttr(ATTR_END));
1036 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
1037 destroyList(attr, (void(*)(void*))freeAttr);
1038 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
1043 destroyList(attr, (void(*)(void*))freeAttr);
1045 if ( err==7 && attr_error==ATTR_PASSWORD ) {
1059 // ---------------------------------------
1060 int ngadmin_defaults (struct ngadmin *nga) {
1065 unsigned short attr_error;
1070 } else if ( nga->current==NULL ) {
1075 attr=createEmptyList();
1076 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
1077 pushBackList(attr, newByteAttr(ATTR_DEFAULTS, 1));
1078 pushBackList(attr, newEmptyAttr(ATTR_END));
1079 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
1080 destroyList(attr, (void(*)(void*))freeAttr);
1081 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
1086 destroyList(attr, (void(*)(void*))freeAttr);
1088 if ( err==7 && attr_error==ATTR_PASSWORD ) {
1094 // successful: delog and clean list