]> git.sur5r.net Git - ngadmin/blob - lib/src/ngadmin.c
CLI: added program options.
[ngadmin] / lib / src / ngadmin.c
1
2 #include "lib.h"
3 #include "network.h"
4
5
6
7 static const struct timeval default_timeout={.tv_sec=3, .tv_usec=0};
8
9
10
11 // ---------------------------------------------
12 struct ngadmin* ngadmin_init (const char *iface) {
13  
14  struct ngadmin *nga;
15  
16  
17  // allocate main structure
18  nga=malloc(sizeof(struct ngadmin));
19  memset(nga, 0, sizeof(struct ngadmin));
20  
21  strncpy(nga->iface, iface, IFNAMSIZ-1);
22  
23  if ( startNetwork(nga)<0 ) {
24   free(nga);
25   return NULL;
26  }
27  
28  nga->timeout=default_timeout;
29  if ( updateTimeout(nga)<0 ) {
30   free(nga);
31   return NULL;
32  }
33  
34  
35  return nga;
36  
37 }
38
39
40
41 // ------------------------------------
42 int ngadmin_close (struct ngadmin *nga) {
43  
44  if ( nga==NULL ) {
45   return ERR_INVARG;
46  }
47  
48  
49  stopNetwork(nga);
50  free(nga->swi_tab);
51  free(nga);
52  
53  
54  return ERR_OK;
55  
56 }
57
58
59
60 // ---------------------------------------------
61 int ngadmin_forceInterface (struct ngadmin *nga) {
62  
63  
64  if ( nga==NULL ) {
65   return ERR_INVARG;
66  }
67  
68  
69  if ( forceInterface(nga)!=0 ) {
70   return ERR_NET;
71  } else {
72   return ERR_OK;
73  }
74  
75 }
76
77
78
79 // --------------------------------------------------------------
80 int ngadmin_setKeepBroadcasting (struct ngadmin *nga, bool value) {
81  
82  
83  if ( nga==NULL ) {
84   return ERR_INVARG;
85  }
86  
87  
88  nga->keepbroad=value;
89  
90  
91  return ERR_OK;
92  
93 }
94
95
96
97 // ------------------------------------------------------------
98 int ngadmin_setPassword (struct ngadmin *nga, const char *pass) {
99  
100  if ( nga==NULL ) {
101   return ERR_INVARG;
102  }
103  
104  
105  strncpy(nga->password, pass, PASSWORD_MAX);
106  
107  
108  return ERR_OK;
109  
110 }
111
112
113
114 // -------------------------------------------------------------------
115 int ngadmin_setTimeout (struct ngadmin *nga, const struct timeval *tv) {
116  
117  int ret=ERR_OK;
118  
119  
120  if ( nga==NULL || tv==NULL ) {
121   return ERR_INVARG;
122  }
123  
124  
125  nga->timeout=*tv;
126  if ( updateTimeout(nga)<0 ) {
127   ret=ERR_NET;
128  }
129  
130  
131  return ret;
132  
133 }
134
135
136
137 // -----------------------------------
138 int ngadmin_scan (struct ngadmin *nga) {
139  
140  int i;
141  List *attr, *swiList;
142  struct swi_attr *sa;
143  /*
144  sent by official win client:
145   ATTR_PRODUCT, 
146   ATTR_UNK2, 
147   ATTR_NAME, 
148   ATTR_MAC, 
149   ATTR_UNK5, 
150   ATTR_IP, 
151   ATTR_NETMASK, 
152   ATTR_GATEWAY, 
153   ATTR_DHCP, 
154   ATTR_UNK12, 
155   ATTR_FIRM_VER, 
156   ATTR_UNK14, 
157   ATTR_UNK15, 
158   ATTR_END
159  */
160  static const unsigned short hello[]={
161   ATTR_PRODUCT, 
162   ATTR_NAME, 
163   ATTR_MAC, 
164   ATTR_IP, 
165   ATTR_NETMASK, 
166   ATTR_GATEWAY, 
167   ATTR_DHCP, 
168   ATTR_FIRM_VER, 
169   ATTR_PORTS_COUNT, 
170   ATTR_END
171  };
172  
173  
174  if ( nga==NULL ) {
175   return ERR_INVARG;
176  }
177  
178  free(nga->swi_tab);
179  nga->swi_count=0;
180  nga->current=NULL;
181  
182  
183  // create attributes for an "hello" request
184  attr=createEmptyList();
185  for (i=0; ; ++i) {
186   pushBackList(attr, newEmptyAttr(hello[i]));
187   if ( hello[i]==ATTR_END ) break;
188  }
189  
190  // send request to all potential switches
191  i=sendNgPacket(nga, CODE_READ_REQ, attr);
192  destroyList(attr, (void(*)(void*))freeAttr);
193  if ( i<0 ) {
194   return ERR_NET;
195  }
196  
197  
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);
205  }
206  
207  nga->swi_count=swiList->count;
208  nga->swi_tab=convertToArray(swiList, sizeof(struct swi_attr));
209  
210  
211  return ERR_OK;
212  
213 }
214
215
216
217 // -----------------------------------------------------------------------
218 const struct swi_attr* ngadmin_getSwitchTab (struct ngadmin *nga, int *nb) {
219  
220  
221  if ( nga==NULL || nb==NULL ) {
222   return NULL;
223  }
224  
225  
226  *nb=nga->swi_count;
227  
228  
229  return nga->swi_tab;
230  
231 }
232
233
234
235 // ------------------------------------------------------------------
236 const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga) {
237  
238  
239  if ( nga==NULL ) {
240   return NULL;
241  }
242  
243  
244  return nga->current;
245  
246 }
247
248
249
250 // --------------------------------------------
251 int ngadmin_login (struct ngadmin *nga, int id) {
252  
253  List *attr;
254  int ret=ERR_OK, i;
255  struct swi_attr *sa;
256  char err;
257  unsigned short attr_error;
258  
259  
260  if ( nga==NULL ) {
261   return ERR_INVARG;
262  } else if ( id<0 || id>=nga->swi_count ) {
263   return ERR_BADID;
264  }
265  
266  
267  sa=&nga->swi_tab[id];
268  nga->current=sa;
269  
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 ) {
276   ret=ERR_NET;
277   nga->current=NULL;
278   goto end;
279  }
280  
281  
282  destroyList(attr, (void(*)(void*))freeAttr);
283  if ( err==7 && attr_error==ATTR_PASSWORD ) {
284   ret=ERR_BADPASS;
285   nga->current=NULL;
286   goto end;
287  }
288  
289  
290  
291  end:
292  
293  return ret;
294  
295 }
296
297
298
299 // -------------------------------------------------------------------
300 int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) {
301  
302  List *attr;
303  ListNode *ln;
304  struct attr *at;
305  int ret=ERR_OK, i;
306  char *p;
307  
308  
309  if ( nga==NULL || ports==NULL ) {
310   return ERR_INVARG;
311  } else if ( nga->current==NULL ) {
312   return ERR_NOTLOG;
313  }
314  
315  
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 ) {
322   ret=ERR_NET;
323   goto end;
324  }
325  
326  for (ln=attr->first; ln!=NULL; ln=ln->next) {
327   at=ln->data;
328   p=at->data;
329   if ( at->attr==ATTR_PORT_STATUS && at->size>=2 && (i=p[0]-1)>=0 && i<nga->current->ports ) {
330    ports[i]=p[1];
331   }
332  }
333  
334  destroyList(attr, (void(*)(void*))freeAttr);
335  
336  
337  end:
338  
339  return ret;
340  
341 }
342
343
344
345 // --------------------------------------------------------
346 int ngadmin_setName (struct ngadmin *nga, const char *name) {
347  
348  List *attr;
349  int ret=ERR_OK, i;
350  char err;
351  unsigned short attr_error;
352  
353  
354  if ( nga==NULL ) {
355   return ERR_INVARG;
356  } else if ( nga->current==NULL ) {
357   return ERR_NOTLOG;
358  }
359  
360  
361  attr=createEmptyList();
362  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
363  if ( name==NULL ) {
364   pushBackList(attr, newEmptyAttr(ATTR_NAME));
365  } else {
366   pushBackList(attr, newAttr(ATTR_NAME, strlen(name), strdup(name)));
367  }
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 ) {
372   ret=ERR_NET;
373   goto end;
374  }
375  
376  destroyList(attr, (void(*)(void*))freeAttr);
377  if ( err==7 && attr_error==ATTR_PASSWORD ) {
378   ret=ERR_BADPASS;
379   goto end;
380  }
381  
382  
383  // successful, also update local name
384  if ( name==NULL ) {
385   nga->current->name[0]=0;
386  } else {
387   strncpy(nga->current->name, name, NAME_SIZE);
388  }
389  
390  
391  end:
392  
393  return ret;
394  
395 }
396
397
398
399 // ------------------------------------------------------------------------
400 int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) {
401  
402  List *attr;
403  ListNode *ln;
404  struct attr *at;
405  int ret=ERR_OK, i;
406  int port;
407  
408  
409  if ( nga==NULL || ps==NULL ) {
410   return ERR_INVARG;
411  } else if ( nga->current==NULL ) {
412   return ERR_NOTLOG;
413  }
414  
415  
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 ) {
422   ret=ERR_NET;
423   goto end;
424  }
425  
426  for (ln=attr->first; ln!=NULL; ln=ln->next) {
427   at=ln->data;
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
433   }
434  }
435  
436  destroyList(attr, (void(*)(void*))freeAttr);
437  
438  
439  end:
440  
441  return ret;
442  
443 }
444
445
446
447 // ---------------------------------------------------
448 int ngadmin_resetPortsStatistics (struct ngadmin *nga) {
449  
450  List *attr;
451  int ret=ERR_OK, i;
452  char err;
453  unsigned short attr_error;
454  
455  
456  if ( nga==NULL ) {
457   return ERR_INVARG;
458  } else if ( nga->current==NULL ) {
459   return ERR_NOTLOG;
460  }
461  
462  
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 ) {
470   ret=ERR_NET;
471   goto end;
472  }
473  
474  destroyList(attr, (void(*)(void*))freeAttr);
475  
476  if ( err==7 && attr_error==ATTR_PASSWORD ) {
477   ret=ERR_BADPASS;
478   goto end;
479  }
480  
481  
482  
483  end:
484  
485  return ret;
486  
487 }
488
489
490
491 // ---------------------------------------------------------------
492 int ngadmin_changePassword (struct ngadmin *nga, const char* pass) {
493  
494  List *attr;
495  int ret=ERR_OK, i;
496  char err;
497  unsigned short attr_error;
498  
499  
500  if ( nga==NULL || pass==NULL ) {
501   return ERR_INVARG;
502  } else if ( nga->current==NULL ) {
503   return ERR_NOTLOG;
504  }
505  
506  
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 ) {
514   ret=ERR_NET;
515   goto end;
516  }
517  
518  destroyList(attr, (void(*)(void*))freeAttr);
519  
520  if ( err==7 && attr_error==ATTR_PASSWORD ) {
521   ret=ERR_BADPASS;
522   goto end;
523  }
524  
525  
526  // successful, also update local password
527  strncpy(nga->password, pass, PASSWORD_MAX);
528  
529  
530  end:
531  
532  return ret;
533  
534 }
535
536
537
538 // ----------------------------------------------------------
539 int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) {
540  
541  List *attr;
542  ListNode *ln;
543  struct attr *at;
544  int ret=ERR_OK, i;
545  
546  
547  if ( nga==NULL || s==NULL ) {
548   return ERR_INVARG;
549  } else if ( nga->current==NULL ) {
550   return ERR_NOTLOG;
551  }
552  
553  
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 ) {
560   ret=ERR_NET;
561   goto end;
562  }
563  
564  for (ln=attr->first; ln!=NULL; ln=ln->next) {
565   at=ln->data;
566   if ( at->attr==ATTR_STORM_ENABLE && at->size>=1 ) {
567    *s= *(char*)at->data!=0 ;
568    break;
569   }
570  }
571  
572  destroyList(attr, (void(*)(void*))freeAttr);
573  
574  
575  end:
576  
577  return ret;
578  
579 }
580
581
582
583 // ---------------------------------------------------------
584 int ngadmin_setStormFilterState (struct ngadmin *nga, int s) {
585  
586  List *attr;
587  int ret=ERR_OK, i;
588  char err;
589  unsigned short attr_error;
590  
591  
592  if ( nga==NULL ) {
593   return ERR_INVARG;
594  } else if ( nga->current==NULL ) {
595   return ERR_NOTLOG;
596  }
597  
598  
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 ) {
606   ret=ERR_NET;
607   goto end;
608  }
609  
610  destroyList(attr, (void(*)(void*))freeAttr);
611  
612  if ( err==7 && attr_error==ATTR_PASSWORD ) {
613   ret=ERR_BADPASS;
614   goto end;
615  }
616  
617  
618  end:
619  
620  return ret;
621  
622 }
623
624
625
626 // ---------------------------------------------------------------
627 int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) {
628  
629  List *attr;
630  ListNode *ln;
631  struct attr *at;
632  int ret=ERR_OK, i;
633  
634  
635  if ( nga==NULL || ports==NULL ) {
636   return ERR_INVARG;
637  } else if ( nga->current==NULL ) {
638   return ERR_NOTLOG;
639  }
640  
641  
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 ) {
648   ret=ERR_NET;
649   goto end;
650  }
651  
652  for (ln=attr->first; ln!=NULL; ln=ln->next) {
653   at=ln->data;
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));
656   }
657  }
658  
659  destroyList(attr, (void(*)(void*))freeAttr);
660  
661  
662  end:
663  
664  return ret;
665  
666 }
667
668
669
670 // ---------------------------------------------------------------------
671 int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) {
672  
673  List *attr;
674  int ret=ERR_OK, i;
675  char err;
676  unsigned short attr_error;
677  char *p;
678  
679  
680  if ( nga==NULL || ports==NULL ) {
681   return ERR_INVARG;
682  } else if ( nga->current==NULL ) {
683   return ERR_NOTLOG;
684  }
685  
686  
687  attr=createEmptyList();
688  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
689  
690  for (i=0; i<nga->current->ports; ++i) {
691   if ( ports[i]>=0 && ports[i]<=11 ) {
692    p=malloc(5);
693    *p=i+1;
694    *(int*)(p+1)=htonl(ports[i]);
695    pushBackList(attr, newAttr(ATTR_STORM_BITRATE, 5, p));
696   }
697  }
698  
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 ) {
703   ret=ERR_NET;
704   goto end;
705  }
706  
707  destroyList(attr, (void(*)(void*))freeAttr);
708  
709  if ( err==7 && attr_error==ATTR_PASSWORD ) {
710   ret=ERR_BADPASS;
711   goto end;
712  }
713  
714  
715  end:
716  
717  return ret;
718  
719 }
720
721
722
723 // -----------------------------------------------------------
724 int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) {
725  
726  List *attr;
727  ListNode *ln;
728  struct attr *at;
729  int ret=ERR_OK, i;
730  
731  
732  if ( nga==NULL || ports==NULL ) {
733   return ERR_INVARG;
734  } else if ( nga->current==NULL ) {
735   return ERR_NOTLOG;
736  }
737  
738  
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 ) {
746   ret=ERR_NET;
747   goto end;
748  }
749  
750  for (ln=attr->first; ln!=NULL; ln=ln->next) {
751   at=ln->data;
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));
756   }
757  }
758  
759  destroyList(attr, (void(*)(void*))freeAttr);
760  
761  
762  end:
763  
764  return ret;
765  
766 }
767
768
769
770 // -----------------------------------------------------------------
771 int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) {
772  
773  List *attr;
774  int ret=ERR_OK, i;
775  char err;
776  unsigned short attr_error;
777  char *p;
778  
779  
780  if ( nga==NULL || ports==NULL ) {
781   return ERR_INVARG;
782  } else if ( nga->current==NULL ) {
783   return ERR_NOTLOG;
784  }
785  
786  
787  attr=createEmptyList();
788  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
789  
790  for (i=0; i<nga->current->ports; ++i) {
791   if ( ports[2*i+0]>=0 && ports[2*i+0]<=11 ) {
792    p=malloc(5);
793    *p=i+1;
794    *(int*)(p+1)=htonl(ports[2*i+0]);
795    pushBackList(attr, newAttr(ATTR_BITRATE_INPUT, 5, p));
796   }
797   if ( ports[2*i+1]>=0 && ports[2*i+1]<=11 ) {
798    p=malloc(5);
799    *p=i+1;
800    *(int*)(p+1)=htonl(ports[2*i+1]);
801    pushBackList(attr, newAttr(ATTR_BITRATE_OUTPUT, 5, p));
802   }
803  }
804  
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 ) {
809   ret=ERR_NET;
810   goto end;
811  }
812  
813  destroyList(attr, (void(*)(void*))freeAttr);
814  
815  if ( err==7 && attr_error==ATTR_PASSWORD ) {
816   ret=ERR_BADPASS;
817   goto end;
818  }
819  
820  
821  end:
822  
823  return ret;
824  
825 }
826
827