+// -------------------------------------------------------------
+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) {
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;
+// --------------------------------------------------------------------
+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) {
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;
}
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);
}
}
}
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
}
}
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 ) {
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;
}
// ----------------------------------------------------------------------------------------------
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;
+
}
pushBackList(attr, newAttr(ATTR_VLAN_PVID, 3, p));
- return writeRequest(nga, attr);;
+ return writeRequest(nga, attr);
}