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[]={
183 // create attributes for an "hello" request
184 attr=createEmptyList();
186 pushBackList(attr, newEmptyAttr(hello[i]));
187 if ( hello[i]==ATTR_END ) break;
190 // send request to all potential switches
191 i=sendNgPacket(nga, CODE_READ_REQ, attr);
192 destroyList(attr, (void(*)(void*))freeAttr);
198 // try to receive any packets until timeout
199 swiList=createEmptyList();
200 while ( (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))!=NULL ) {
201 sa=malloc(sizeof(struct swi_attr));
202 extractSwitchAttributes(sa, attr);
203 destroyList(attr, (void(*)(void*))freeAttr);
204 pushBackList(swiList, sa);
207 nga->swi_count=swiList->count;
208 nga->swi_tab=convertToArray(swiList, sizeof(struct swi_attr));
217 // -----------------------------------------------------------------------
218 const struct swi_attr* ngadmin_getSwitchTab (struct ngadmin *nga, int *nb) {
221 if ( nga==NULL || nb==NULL ) {
235 // ------------------------------------------------------------------
236 const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga) {
250 // --------------------------------------------
251 int ngadmin_login (struct ngadmin *nga, int id) {
257 unsigned short attr_error;
262 } else if ( id<0 || id>=nga->swi_count ) {
267 sa=&nga->swi_tab[id];
270 attr=createEmptyList();
271 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
272 pushBackList(attr, newEmptyAttr(ATTR_END));
273 i=sendNgPacket(nga, CODE_READ_REQ, attr);
274 destroyList(attr, (void(*)(void*))freeAttr);
275 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, &err, &attr_error))==NULL ) {
282 destroyList(attr, (void(*)(void*))freeAttr);
283 if ( err==7 && attr_error==ATTR_PASSWORD ) {
299 // -------------------------------------------------------------------
300 int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) {
309 if ( nga==NULL || ports==NULL ) {
311 } else if ( nga->current==NULL ) {
316 attr=createEmptyList();
317 pushBackList(attr, newEmptyAttr(ATTR_PORT_STATUS));
318 pushBackList(attr, newEmptyAttr(ATTR_END));
319 i=sendNgPacket(nga, CODE_READ_REQ, attr);
320 destroyList(attr, (void(*)(void*))freeAttr);
321 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
326 for (ln=attr->first; ln!=NULL; ln=ln->next) {
329 if ( at->attr==ATTR_PORT_STATUS && at->size>=2 && (i=p[0]-1)>=0 && i<nga->current->ports ) {
334 destroyList(attr, (void(*)(void*))freeAttr);
345 // --------------------------------------------------------
346 int ngadmin_setName (struct ngadmin *nga, const char *name) {
351 unsigned short attr_error;
356 } else if ( nga->current==NULL ) {
361 attr=createEmptyList();
362 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
364 pushBackList(attr, newEmptyAttr(ATTR_NAME));
366 pushBackList(attr, newAttr(ATTR_NAME, strlen(name), strdup(name)));
368 pushBackList(attr, newEmptyAttr(ATTR_END));
369 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
370 destroyList(attr, (void(*)(void*))freeAttr);
371 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
376 destroyList(attr, (void(*)(void*))freeAttr);
377 if ( err==7 && attr_error==ATTR_PASSWORD ) {
383 // successful, also update local name
385 nga->current->name[0]=0;
387 strncpy(nga->current->name, name, NAME_SIZE);
399 // ------------------------------------------------------------------------
400 int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) {
409 if ( nga==NULL || ps==NULL ) {
411 } else if ( nga->current==NULL ) {
416 attr=createEmptyList();
417 pushBackList(attr, newEmptyAttr(ATTR_PORT_STATISTICS));
418 pushBackList(attr, newEmptyAttr(ATTR_END));
419 i=sendNgPacket(nga, CODE_READ_REQ, attr);
420 destroyList(attr, (void(*)(void*))freeAttr);
421 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
426 for (ln=attr->first; ln!=NULL; ln=ln->next) {
428 if ( at->attr==ATTR_PORT_STATISTICS && at->size>=49 && (port=(int)(*(char*)at->data)-1)>=0 && port<nga->current->ports ) {
429 ps[port].recv=be64toh(*(unsigned long long*)(at->data+1+8*0));
430 ps[port].sent=be64toh(*(unsigned long long*)(at->data+1+8*1));
431 ps[port].crc=be64toh(*(unsigned long long*)(at->data+1+8*5));
432 // all offsets between 2 and 4 inclusive are unknown values
436 destroyList(attr, (void(*)(void*))freeAttr);
447 // ---------------------------------------------------
448 int ngadmin_resetPortsStatistics (struct ngadmin *nga) {
453 unsigned short attr_error;
458 } else if ( nga->current==NULL ) {
463 attr=createEmptyList();
464 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
465 pushBackList(attr, newByteAttr(ATTR_STATS_RESET, 1));
466 pushBackList(attr, newEmptyAttr(ATTR_END));
467 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
468 destroyList(attr, (void(*)(void*))freeAttr);
469 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
474 destroyList(attr, (void(*)(void*))freeAttr);
476 if ( err==7 && attr_error==ATTR_PASSWORD ) {
491 // ---------------------------------------------------------------
492 int ngadmin_changePassword (struct ngadmin *nga, const char* pass) {
497 unsigned short attr_error;
500 if ( nga==NULL || pass==NULL ) {
502 } else if ( nga->current==NULL ) {
507 attr=createEmptyList();
508 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
509 pushBackList(attr, newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass)));
510 pushBackList(attr, newEmptyAttr(ATTR_END));
511 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
512 destroyList(attr, (void(*)(void*))freeAttr);
513 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
518 destroyList(attr, (void(*)(void*))freeAttr);
520 if ( err==7 && attr_error==ATTR_PASSWORD ) {
526 // successful, also update local password
527 strncpy(nga->password, pass, PASSWORD_MAX);
538 // ----------------------------------------------------------
539 int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) {
547 if ( nga==NULL || s==NULL ) {
549 } else if ( nga->current==NULL ) {
554 attr=createEmptyList();
555 pushBackList(attr, newEmptyAttr(ATTR_STORM_ENABLE));
556 pushBackList(attr, newEmptyAttr(ATTR_END));
557 i=sendNgPacket(nga, CODE_READ_REQ, attr);
558 destroyList(attr, (void(*)(void*))freeAttr);
559 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
564 for (ln=attr->first; ln!=NULL; ln=ln->next) {
566 if ( at->attr==ATTR_STORM_ENABLE && at->size>=1 ) {
567 *s= *(char*)at->data!=0 ;
572 destroyList(attr, (void(*)(void*))freeAttr);
583 // ---------------------------------------------------------
584 int ngadmin_setStormFilterState (struct ngadmin *nga, int s) {
589 unsigned short attr_error;
594 } else if ( nga->current==NULL ) {
599 attr=createEmptyList();
600 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
601 pushBackList(attr, newByteAttr(ATTR_STORM_ENABLE, s!=0));
602 pushBackList(attr, newEmptyAttr(ATTR_END));
603 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
604 destroyList(attr, (void(*)(void*))freeAttr);
605 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
610 destroyList(attr, (void(*)(void*))freeAttr);
612 if ( err==7 && attr_error==ATTR_PASSWORD ) {
626 // ---------------------------------------------------------------
627 int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) {
635 if ( nga==NULL || ports==NULL ) {
637 } else if ( nga->current==NULL ) {
642 attr=createEmptyList();
643 pushBackList(attr, newEmptyAttr(ATTR_STORM_BITRATE));
644 pushBackList(attr, newEmptyAttr(ATTR_END));
645 i=sendNgPacket(nga, CODE_READ_REQ, attr);
646 destroyList(attr, (void(*)(void*))freeAttr);
647 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
652 for (ln=attr->first; ln!=NULL; ln=ln->next) {
654 if ( at->attr==ATTR_STORM_BITRATE && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
655 ports[i]=ntohl(*(int*)(1+(char*)at->data));
659 destroyList(attr, (void(*)(void*))freeAttr);
670 // ---------------------------------------------------------------------
671 int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) {
676 unsigned short attr_error;
680 if ( nga==NULL || ports==NULL ) {
682 } else if ( nga->current==NULL ) {
687 attr=createEmptyList();
688 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
690 for (i=0; i<nga->current->ports; ++i) {
691 if ( ports[i]>=0 && ports[i]<=11 ) {
694 *(int*)(p+1)=htonl(ports[i]);
695 pushBackList(attr, newAttr(ATTR_STORM_BITRATE, 5, p));
699 pushBackList(attr, newEmptyAttr(ATTR_END));
700 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
701 destroyList(attr, (void(*)(void*))freeAttr);
702 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
707 destroyList(attr, (void(*)(void*))freeAttr);
709 if ( err==7 && attr_error==ATTR_PASSWORD ) {
723 // -----------------------------------------------------------
724 int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) {
732 if ( nga==NULL || ports==NULL ) {
734 } else if ( nga->current==NULL ) {
739 attr=createEmptyList();
740 pushBackList(attr, newEmptyAttr(ATTR_BITRATE_INPUT));
741 pushBackList(attr, newEmptyAttr(ATTR_BITRATE_OUTPUT));
742 pushBackList(attr, newEmptyAttr(ATTR_END));
743 i=sendNgPacket(nga, CODE_READ_REQ, attr);
744 destroyList(attr, (void(*)(void*))freeAttr);
745 if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) {
750 for (ln=attr->first; ln!=NULL; ln=ln->next) {
752 if ( at->attr==ATTR_BITRATE_INPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
753 ports[i*2+0]=ntohl(*(int*)(1+(char*)at->data));
754 } else if ( at->attr==ATTR_BITRATE_OUTPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
755 ports[i*2+1]=ntohl(*(int*)(1+(char*)at->data));
759 destroyList(attr, (void(*)(void*))freeAttr);
770 // -----------------------------------------------------------------
771 int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) {
776 unsigned short attr_error;
780 if ( nga==NULL || ports==NULL ) {
782 } else if ( nga->current==NULL ) {
787 attr=createEmptyList();
788 pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
790 for (i=0; i<nga->current->ports; ++i) {
791 if ( ports[2*i+0]>=0 && ports[2*i+0]<=11 ) {
794 *(int*)(p+1)=htonl(ports[2*i+0]);
795 pushBackList(attr, newAttr(ATTR_BITRATE_INPUT, 5, p));
797 if ( ports[2*i+1]>=0 && ports[2*i+1]<=11 ) {
800 *(int*)(p+1)=htonl(ports[2*i+1]);
801 pushBackList(attr, newAttr(ATTR_BITRATE_OUTPUT, 5, p));
805 pushBackList(attr, newEmptyAttr(ATTR_END));
806 i=sendNgPacket(nga, CODE_WRITE_REQ, attr);
807 destroyList(attr, (void(*)(void*))freeAttr);
808 if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) {
813 destroyList(attr, (void(*)(void*))freeAttr);
815 if ( err==7 && attr_error==ATTR_PASSWORD ) {