]> git.sur5r.net Git - ngadmin/blob - lib/src/ngadmin.c
bdcc9b53ee402ccc655ac646e7b938a07b7d4572
[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_setPassword (struct ngadmin *nga, const char *pass) {
62  
63  if ( nga==NULL ) {
64   return ERR_INVARG;
65  }
66  
67  
68  strncpy(nga->password, pass, PASSWORD_MAX);
69  
70  
71  return ERR_OK;
72  
73 }
74
75
76
77 // -------------------------------------------------------------------
78 int ngadmin_setTimeout (struct ngadmin *nga, const struct timeval *tv) {
79  
80  int ret=ERR_OK;
81  
82  
83  if ( nga==NULL || tv==NULL ) {
84   return ERR_INVARG;
85  }
86  
87  
88  nga->timeout=*tv;
89  if ( updateTimeout(nga)<0 ) {
90   ret=ERR_NET;
91  }
92  
93  
94  return ret;
95  
96 }
97
98
99
100 // -----------------------------------
101 int ngadmin_scan (struct ngadmin *nga) {
102  
103  int i;
104  List *attr, *swiList;
105  struct swi_attr *sa;
106  /*
107  sent by official win client:
108   ATTR_PRODUCT, 
109   ATTR_UNK2, 
110   ATTR_NAME, 
111   ATTR_MAC, 
112   ATTR_UNK5, 
113   ATTR_IP, 
114   ATTR_NETMASK, 
115   ATTR_GATEWAY, 
116   ATTR_DHCP, 
117   ATTR_UNK12, 
118   ATTR_FIRM_VER, 
119   ATTR_UNK14, 
120   ATTR_UNK15, 
121   ATTR_END
122  */
123  static const unsigned short hello[]={
124   ATTR_PRODUCT, 
125   ATTR_NAME, 
126   ATTR_MAC, 
127   ATTR_IP, 
128   ATTR_NETMASK, 
129   ATTR_GATEWAY, 
130   ATTR_DHCP, 
131   ATTR_FIRM_VER, 
132   ATTR_PORTS_COUNT, 
133   ATTR_END
134  };
135  
136  
137  if ( nga==NULL ) {
138   return ERR_INVARG;
139  }
140  
141  free(nga->swi_tab);
142  nga->swi_count=0;
143  nga->current=NULL;
144  
145  
146  // create attributes for an "hello" request
147  attr=createEmptyList();
148  for (i=0; ; ++i) {
149   pushBackList(attr, newEmptyAttr(hello[i]));
150   if ( hello[i]==ATTR_END ) break;
151  }
152  
153  // send request to all potential switches
154  i=sendNgPacket(nga, CODE_READ_REQ, NULL, ++nga->seq, attr);
155  destroyList(attr, (void(*)(void*))freeAttr);
156  if ( i<0 ) {
157   return ERR_NET;
158  }
159  
160  
161  // try to receive any packets until timeout
162  swiList=createEmptyList();
163  while ( (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL, NULL, nga->seq))!=NULL ) {
164   sa=malloc(sizeof(struct swi_attr));
165   extractSwitchAttributes(sa, attr);
166   destroyList(attr, (void(*)(void*))freeAttr);
167   pushBackList(swiList, sa);
168  }
169  
170  nga->swi_count=swiList->count;
171  nga->swi_tab=convertToArray(swiList, sizeof(struct swi_attr));
172  
173  
174  return ERR_OK;
175  
176 }
177
178
179
180 // -----------------------------------------------------------------------
181 const struct swi_attr* ngadmin_getSwitchTab (struct ngadmin *nga, int *nb) {
182  
183  
184  if ( nga==NULL || nb==NULL ) {
185   return NULL;
186  }
187  
188  
189  *nb=nga->swi_count;
190  
191  
192  return nga->swi_tab;
193  
194 }
195
196
197
198 // ------------------------------------------------------------------
199 const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga) {
200  
201  
202  if ( nga==NULL ) {
203   return NULL;
204  }
205  
206  
207  return nga->current;
208  
209 }
210
211
212
213 // --------------------------------------------
214 int ngadmin_login (struct ngadmin *nga, int id) {
215  
216  List *attr;
217  int ret=ERR_OK, i;
218  struct swi_attr *sa;
219  char err;
220  unsigned short attr_error;
221  
222  
223  if ( nga==NULL ) {
224   return ERR_INVARG;
225  } else if ( id<0 || id>=nga->swi_count ) {
226   return ERR_BADID;
227  }
228  
229  
230  nga->current=NULL;
231  sa=&nga->swi_tab[id];
232  
233  attr=createEmptyList();
234  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
235  pushBackList(attr, newEmptyAttr(ATTR_END));
236  i=sendNgPacket(nga, CODE_READ_REQ, &sa->mac, ++nga->seq, attr);
237  destroyList(attr, (void(*)(void*))freeAttr);
238  if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, &err, &attr_error, &sa->mac, nga->seq))==NULL ) {
239   ret=ERR_NET;
240   goto end;
241  }
242  
243  
244  destroyList(attr, (void(*)(void*))freeAttr);
245  if ( err==7 && attr_error==ATTR_PASSWORD ) {
246   ret=ERR_BADPASS;
247   goto end;
248  }
249  
250  
251  // login successful
252  nga->current=sa;
253  
254  end:
255  
256  
257  return ret;
258  
259 }
260
261
262
263 // -------------------------------------------------------------------
264 int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) {
265  
266  List *attr;
267  ListNode *ln;
268  struct attr *at;
269  int ret=ERR_OK, i;
270  char *p;
271  
272  
273  if ( nga==NULL || ports==NULL ) {
274   return ERR_INVARG;
275  } else if ( nga->current==NULL ) {
276   return ERR_NOTLOG;
277  }
278  
279  
280  attr=createEmptyList();
281  pushBackList(attr, newEmptyAttr(ATTR_PORT_STATUS));
282  pushBackList(attr, newEmptyAttr(ATTR_END));
283  i=sendNgPacket(nga, CODE_READ_REQ, &nga->current->mac, ++nga->seq, attr);
284  destroyList(attr, (void(*)(void*))freeAttr);
285  if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL, &nga->current->mac, nga->seq))==NULL ) {
286   ret=ERR_NET;
287   goto end;
288  }
289  
290  for (ln=attr->first; ln!=NULL; ln=ln->next) {
291   at=ln->data;
292   p=at->data;
293   if ( at->attr==ATTR_PORT_STATUS && at->size>=2 && (i=p[0]-1)>=0 && i<nga->current->ports ) {
294    ports[i]=p[1];
295   }
296  }
297  
298  destroyList(attr, (void(*)(void*))freeAttr);
299  
300  
301  end:
302  
303  return ret;
304  
305 }
306
307
308
309 // --------------------------------------------------------
310 int ngadmin_setName (struct ngadmin *nga, const char *name) {
311  
312  List *attr;
313  int ret=ERR_OK, i;
314  char err;
315  unsigned short attr_error;
316  
317  
318  if ( nga==NULL ) {
319   return ERR_INVARG;
320  } else if ( nga->current==NULL ) {
321   return ERR_NOTLOG;
322  }
323  
324  
325  attr=createEmptyList();
326  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
327  if ( name==NULL ) {
328   pushBackList(attr, newEmptyAttr(ATTR_NAME));
329  } else {
330   pushBackList(attr, newAttr(ATTR_NAME, strlen(name), strdup(name)));
331  }
332  pushBackList(attr, newEmptyAttr(ATTR_END));
333  i=sendNgPacket(nga, CODE_WRITE_REQ, &nga->current->mac, ++nga->seq, attr);
334  destroyList(attr, (void(*)(void*))freeAttr);
335  if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, &nga->current->mac, nga->seq))==NULL ) {
336   ret=ERR_NET;
337   goto end;
338  }
339  
340  destroyList(attr, (void(*)(void*))freeAttr);
341  if ( err==7 && attr_error==ATTR_PASSWORD ) {
342   ret=ERR_BADPASS;
343   goto end;
344  }
345  
346  
347  // successful, also update local name
348  if ( name==NULL ) {
349   nga->current->name[0]=0;
350  } else {
351   strncpy(nga->current->name, name, NAME_SIZE);
352  }
353  
354  
355  end:
356  
357  return ret;
358  
359 }
360
361
362
363 // ------------------------------------------------------------------------
364 int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) {
365  
366  List *attr;
367  ListNode *ln;
368  struct attr *at;
369  int ret=ERR_OK, i;
370  int port;
371  
372  
373  if ( nga==NULL || ps==NULL ) {
374   return ERR_INVARG;
375  } else if ( nga->current==NULL ) {
376   return ERR_NOTLOG;
377  }
378  
379  
380  attr=createEmptyList();
381  pushBackList(attr, newEmptyAttr(ATTR_PORT_STATISTICS));
382  pushBackList(attr, newEmptyAttr(ATTR_END));
383  i=sendNgPacket(nga, CODE_READ_REQ, &nga->current->mac, ++nga->seq, attr);
384  destroyList(attr, (void(*)(void*))freeAttr);
385  if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL, &nga->current->mac, nga->seq))==NULL ) {
386   ret=ERR_NET;
387   goto end;
388  }
389  
390  for (ln=attr->first; ln!=NULL; ln=ln->next) {
391   at=ln->data;
392   if ( at->attr==ATTR_PORT_STATISTICS && at->size>=49 && (port=(int)(*(char*)at->data)-1)>=0 && port<nga->current->ports ) {
393    ps[port].recv=be64toh(*(unsigned long long*)(at->data+1+8*0));
394    ps[port].sent=be64toh(*(unsigned long long*)(at->data+1+8*1));
395    ps[port].crc=be64toh(*(unsigned long long*)(at->data+1+8*5));
396    // all offsets between 2 and 4 inclusive are unknown values
397   }
398  }
399  
400  destroyList(attr, (void(*)(void*))freeAttr);
401  
402  
403  end:
404  
405  return ret;
406  
407  
408 }
409
410
411
412 // ---------------------------------------------------
413 int ngadmin_resetPortsStatistics (struct ngadmin *nga) {
414  
415  List *attr;
416  int ret=ERR_OK, i;
417  char err;
418  unsigned short attr_error;
419  
420  
421  if ( nga==NULL ) {
422   return ERR_INVARG;
423  } else if ( nga->current==NULL ) {
424   return ERR_NOTLOG;
425  }
426  
427  
428  attr=createEmptyList();
429  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
430  pushBackList(attr, newByteAttr(ATTR_STATS_RESET, 1));
431  pushBackList(attr, newEmptyAttr(ATTR_END));
432  i=sendNgPacket(nga, CODE_WRITE_REQ, &nga->current->mac, ++nga->seq, attr);
433  destroyList(attr, (void(*)(void*))freeAttr);
434  if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, &nga->current->mac, nga->seq))==NULL ) {
435   ret=ERR_NET;
436   goto end;
437  }
438  
439  destroyList(attr, (void(*)(void*))freeAttr);
440  
441  if ( err==7 && attr_error==ATTR_PASSWORD ) {
442   ret=ERR_BADPASS;
443   goto end;
444  }
445  
446  
447  
448  end:
449  
450  return ret;
451  
452 }
453
454
455
456 // ---------------------------------------------------------------
457 int ngadmin_changePassword (struct ngadmin *nga, const char* pass) {
458  
459  List *attr;
460  int ret=ERR_OK, i;
461  char err;
462  unsigned short attr_error;
463  
464  
465  if ( nga==NULL || pass==NULL ) {
466   return ERR_INVARG;
467  } else if ( nga->current==NULL ) {
468   return ERR_NOTLOG;
469  }
470  
471  
472  attr=createEmptyList();
473  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
474  pushBackList(attr, newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass)));
475  pushBackList(attr, newEmptyAttr(ATTR_END));
476  i=sendNgPacket(nga, CODE_WRITE_REQ, &nga->current->mac, ++nga->seq, attr);
477  destroyList(attr, (void(*)(void*))freeAttr);
478  if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, &nga->current->mac, nga->seq))==NULL ) {
479   ret=ERR_NET;
480   goto end;
481  }
482  
483  destroyList(attr, (void(*)(void*))freeAttr);
484  
485  if ( err==7 && attr_error==ATTR_PASSWORD ) {
486   ret=ERR_BADPASS;
487   goto end;
488  }
489  
490  
491  // successful, also update local password
492  strncpy(nga->password, pass, PASSWORD_MAX);
493  
494  
495  end:
496  
497  return ret;
498  
499 }
500
501