]> git.sur5r.net Git - ngadmin/blobdiff - lib/src/ngadmin.c
Added the possibility to use global broadcast.
[ngadmin] / lib / src / ngadmin.c
index 8248345b67612cc2b7e775f77e8795667439be89..6473465bba03f7dc9da0b5ef5e48d9423e90e1e3 100644 (file)
@@ -94,6 +94,24 @@ int ngadmin_setKeepBroadcasting (struct ngadmin *nga, bool value) {
 
 
 
+// -------------------------------------------------------------
+int ngadmin_useGlobalBroadcast (struct ngadmin *nga, bool value) {
+ if ( nga==NULL ) {
+  return ERR_INVARG;
+ }
+ nga->globalbroad=value;
+ return ERR_OK;
+}
+
+
+
 // ------------------------------------------------------------
 int ngadmin_setPassword (struct ngadmin *nga, const char *pass) {
  
@@ -270,7 +288,7 @@ int ngadmin_login (struct ngadmin *nga, int id) {
  pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
  if ( (ret=readRequest(nga, attr))==ERR_OK ) {
   // login succeeded
-  // TODO: if keep broadcasting is disabled, connect() the UDP socket so icmp errors messages (port unreachable, TTL exceeded in transit, ...)can be received
+  // TODO: if keep broadcasting is disabled, connect() the UDP socket so icmp errors messages (port unreachable, TTL exceeded in transit, ...) can be received
  } else {
   // login failed
   nga->current=NULL;
@@ -285,6 +303,30 @@ int ngadmin_login (struct ngadmin *nga, int id) {
 
 
 
+// --------------------------------------------------------------------
+int ngadmin_upgradeFirmware (struct ngadmin *nga, const char *filename) {
+ if ( nga==NULL || filename==NULL || *filename==0 ) {
+  return ERR_INVARG;
+ } else if ( nga->current==NULL ) {
+  return ERR_NOTLOG;
+ }
+ /*
+ Firmware upgrade is not yet implemented. 
+ This would require much more work and the use of a TFTP client. 
+ Overall, it could be quite dangerous, as the switch may not check the binary 
+ content sent to it. 
+ */
+ return ERR_NOTIMPL;
+}
+
+
+
 // -------------------------------------------------------------------
 int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) {
  
@@ -884,7 +926,7 @@ int ngadmin_getMirror (struct ngadmin *nga, char *ports) {
   if ( at->attr==ATTR_MIRROR && at->size>=3 && p[0]<=nga->current->ports ) {
    ports[0]=p[0];
    for (i=1; i<=sa->ports; ++i) { // FIXME: if ports>8
-    ports[i]=(p[2]>>(sa->ports-i))&1;
+    ports[i]=(p[2]>>(8-i))&1;
    }
    break;
   }
@@ -924,7 +966,7 @@ int ngadmin_setMirror (struct ngadmin *nga, const char *ports) {
   p[0]=ports[0];
   for (i=1; i<=sa->ports; ++i) {
    if ( i!=p[0] ) {
-    p[2]|=(ports[i]&1)<<(sa->ports-i);
+    p[2]|=(ports[i]&1)<<(8-i);
    }
   }
  }
@@ -1272,16 +1314,15 @@ int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsig
  for (ln=attr->first; ln!=NULL; ln=ln->next) {
   at=ln->data;
   p=at->data;
-  if ( *nb>=sa->ports ) break; // no more room
   if ( at->attr==ATTR_VLAN_DOT_CONF && at->size>=4 ) {
-   for (i=1; i<=sa->ports; ++i) {
-    if ( (p[3]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_TAGGED; // tagged
-    else if ( (p[2]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_UNTAGGED; // untagged
-    else ports[i-1]=VLAN_NO;
+   for (i=0; i<sa->ports; ++i) {
+    if ( (p[3]>>(7-i))&1 ) ports[i]=VLAN_TAGGED; // tagged
+    else if ( (p[2]>>(7-i))&1 ) ports[i]=VLAN_UNTAGGED; // untagged
+    else ports[i]=VLAN_NO;
    }
    *vlans++=ntohs(*(unsigned short*)p);
    ports+=sa->ports;
-   ++*nb;
+   if ( ++*nb>total ) break; // no more room
   }
  }
  
@@ -1306,14 +1347,13 @@ int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned c
  char *p=NULL;
  
  
- if ( nga==NULL || ports==NULL ) {
+ if ( nga==NULL || vlan<1 || vlan>VLAN_MAX || ports==NULL ) {
   return ERR_INVARG;
  } else if ( (sa=nga->current)==NULL ) {
   return ERR_NOTLOG;
  }
  
  
  attr=createEmptyList();
  pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
  if ( (ret=readRequest(nga, attr))!=ERR_OK ) {
@@ -1325,10 +1365,10 @@ int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned c
   at=ln->data;
   p=at->data;
   if ( at->attr==ATTR_VLAN_DOT_CONF && at->size>=4 ) {
-   for (i=1; i<=sa->ports; ++i) {
-    if ( (p[3]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_TAGGED; // tagged
-    else if ( (p[2]>>(sa->ports-i))&1 ) ports[i-1]=VLAN_UNTAGGED; // untagged
-    else ports[i-1]=VLAN_NO;
+   for (i=0; i<sa->ports; ++i) {
+    if ( (p[3]>>(7-i))&1 ) ports[i]=VLAN_TAGGED; // tagged
+    else if ( (p[2]>>(7-i))&1 ) ports[i]=VLAN_UNTAGGED; // untagged
+    else ports[i]=VLAN_NO;
    }
    break;
   }
@@ -1347,40 +1387,83 @@ int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned c
 // ----------------------------------------------------------------------------------------------
 int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsigned char *ports) {
  
- List *attr;
+ List *attr=NULL;
+ ListNode *ln;
+ struct attr *at;
  struct swi_attr *sa;
int i;
char *p;
char *p, fl;
int ret=ERR_OK, i;
  
  
- if ( nga==NULL || ports==NULL || vlan<1 || vlan>VLAN_MAX ) {
+ if ( nga==NULL || vlan<1 || vlan>VLAN_MAX || ports==NULL ) {
   return ERR_INVARG;
  } else if ( (sa=nga->current)==NULL ) {
   return ERR_NOTLOG;
  }
  
  
+ // if nothing is to be changed, do nothing
+ for (i=0; i<sa->ports && ports[i]==VLAN_UNSPEC; ++i);
+ if ( i==sa->ports ) goto end;
  
  attr=createEmptyList();
  p=malloc(4);
  *(unsigned short*)p=htons(vlan);
+ *(unsigned short*)&p[2]=0;
+ // if all is to be changed, we do not need to read old config
+ if ( memchr(ports, VLAN_UNSPEC, sa->ports)!=NULL ) {
+  
+  pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
+  if ( (ret=readRequest(nga, attr))!=ERR_OK ) {
+   goto end;
+  }
+  
+  for (ln=attr->first; ln!=NULL; ln=ln->next) {
+   at=ln->data;
+   if ( at->attr==ATTR_VLAN_DOT_CONF && at->size>=4 ) {
+    *(unsigned short*)&p[2]=*(unsigned short*)(at->data+2);
+    break;
+   }
+  }
+  
+  clearList(attr, (void(*)(void*))freeAttr);
+  
+ }
  
- for (i=1; i<=sa->ports; ++i) {
-  if ( ports[i-1]==VLAN_TAGGED ) { // tagged
-   p[3]|=(1<<(sa->ports-i));
-  } else if ( ports[i-1]==VLAN_UNTAGGED ) { // untagged
-   p[2]|=(1<<(sa->ports-i));
+ // apply changes
+ for (i=0; i<sa->ports; ++i) {
+  fl=(1<<(7-i));
+  switch ( ports[i] ) {
+   case VLAN_NO:
+    p[2]&=~fl;
+    p[3]&=~fl;
+   break;
+   case VLAN_UNTAGGED:
+    p[2]|=fl;
+    p[3]&=~fl;
+   break;
+   case VLAN_TAGGED:
+    p[2]|=fl;
+    p[3]|=fl;
   }
  }
  
- // tagged ports must be also present in untagged ports
- p[2]|=ports[3];
  
  
  pushBackList(attr, newAttr(ATTR_VLAN_DOT_CONF, 4, p));
+ ret=writeRequest(nga, attr);
+ attr=NULL;
  
  
- return writeRequest(nga, attr);
+ end:
+ destroyList(attr, (void(*)(void*))freeAttr);
+ return ret;
  
 }
 
@@ -1478,7 +1561,7 @@ int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vla
  pushBackList(attr, newAttr(ATTR_VLAN_PVID, 3, p));
  
  
- return writeRequest(nga, attr);;
+ return writeRequest(nga, attr);
  
 }