]> git.sur5r.net Git - ngadmin/commitdiff
Added support for changing the network configuration.
authordarkcoven <admin@darkcoven.tk>
Wed, 23 Nov 2011 11:00:00 +0000 (12:00 +0100)
committerdarkcoven <admin@darkcoven.tk>
Sat, 29 Dec 2012 21:36:59 +0000 (22:36 +0100)
Added very basic support of VLANs, read only.
Lib: handling error code on 2 bytes instead of 1.

cli/commands.c
cli/common.c
lib/ngadmin.h
lib/src/lib.h
lib/src/network.c
lib/src/network.h
lib/src/ngadmin.c
lib/src/protocol.c
lib/src/protocol.h

index c1349055edbde2be69149412dd64163bb436b94f..a35b8bf2356d30829b646096523fbdd1bed5921f 100644 (file)
@@ -462,7 +462,7 @@ static bool do_mirror_set (int nb, const char **com, struct ngadmin *nga) {
  end:
  free(ports);
  
- return true;
+ return ret;
  
 }
 
@@ -584,6 +584,85 @@ static bool do_name_clear (int nb UNUSED, const char **com UNUSED, struct ngadmi
 
 
 
+// =============================================================================
+// netconf
+
+
+static bool do_netconf_set (int nb, const char **com, struct ngadmin *nga) {
+ int i, k;
+ const struct swi_attr *sa;
+ struct net_conf nc;
+ bool ret=true;
+ if ( nb==0 ) {
+  printf("Usage: netconf set [dhcp yes|no] [ip <ip>] [mask <mask>] [gw <gw>]\n");
+  return false;
+ }
+ if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) {
+  printf("must be logged\n");
+  return false;
+ }
+ memset(&nc, 0, sizeof(struct net_conf));
+ for (k=0; k<nb; k+=2) {
+  
+  if ( strcasecmp(com[k], "dhcp")==0 ) {
+   if ( strcasecmp(com[k+1], "yes")==0 ) {
+    nc.dhcp=true;
+   } else if ( strcasecmp(com[k+1], "no")==0 ) {
+    nc.dhcp=false;
+   } else {
+    printf("Incorrect DHCP value\n");
+    ret=false;
+    goto end;
+   }
+   
+  } else if ( strcasecmp(com[k], "ip")==0 ) {
+   if ( inet_aton(com[k+1], &nc.ip)==0 ) {
+    printf("Incorrect IP value\n");
+    ret=false;
+    goto end;
+   }
+   
+  } else if ( strcasecmp(com[k], "mask")==0 ) {
+   if ( inet_aton(com[k+1], &nc.netmask)==0 ) { // TODO: check if it is a correct mask
+    printf("Incorrect mask value\n");
+    ret=false;
+    goto end;
+   }
+   
+  } else if ( strcasecmp(com[k], "gw")==0 ) {
+   if ( inet_aton(com[k+1], &nc.gw)==0 ) {
+    printf("Incorrect gateway value\n");
+    ret=false;
+    goto end;
+   }
+   
+  }
+  
+ }
+ i=ngadmin_setNetConf(nga, &nc);
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+ }
+ end:
+ return ret;
+}
+
+
+
 // =============================================================================
 // password
 
@@ -595,7 +674,7 @@ static bool do_password_change (int nb, const char **com, struct ngadmin *nga) {
  
  
  if ( nb!=1 ) {
-  printf("Usage: password set <value>\n");
+  printf("Usage: password change <value>\n");
   return false;
  }
  
@@ -1146,6 +1225,102 @@ static bool do_tree (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga
 
 
 
+// =============================================================================
+// vlan
+
+
+static char vlan_char (int t) {
+ switch ( t ) {
+  case VLAN_TAGGED: return 'T';
+  case VLAN_UNTAGGED: return 'U'; 
+  case VLAN_NO: return ' ';
+  default: return '?';
+ }
+}
+
+
+static bool print_vlan_dot_adv (struct ngadmin *nga) {
+ char buffer[512], *b=buffer;
+ const struct swi_attr *sa;
+ int i, t;
+ sa=ngadmin_getCurrentSwitch(nga);
+ t=sizeof(buffer);
+ i=ngadmin_getVLANDotConf(nga, buffer, &t);
+ if ( i!=ERR_OK ) {
+  printErrCode(i);
+  return false;
+ }
+ printf("Ports configuration: \n");
+ printf("VLAN\t");
+ for (i=1; i<=sa->ports; ++i) {
+  printf("%i\t", i);
+ }
+ putchar('\n');
+ while ( b-buffer<t ) {
+  printf("%u\t", *(unsigned short*)b);b+=2;
+  for (i=1; i<=sa->ports; ++i) {
+   printf("%c\t", vlan_char(*b++));
+  }
+  putchar('\n');
+ }
+ return true;
+}
+
+
+static bool do_vlan_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) {
+ int i, t, ret=true;
+ if ( ngadmin_getCurrentSwitch(nga)==NULL ) {
+  printf("must be logged\n");
+  ret=false;
+  goto end;
+ }
+ if ( (i=ngadmin_getVLANType(nga, &t))!=ERR_OK ) {
+  printErrCode(i);
+  ret=false;
+  goto end;
+ }
+ printf("VLAN type: ");
+ switch ( t ) {
+  case VLAN_DISABLED: printf("disabled\n"); break;
+  case VLAN_PORT_BASIC: printf("port basic\n"); break;
+  case VLAN_PORT_ADV: printf("port advanced\n"); break;
+  case VLAN_DOT_BASIC: printf("802.1Q basic\n"); break;
+  
+  case VLAN_DOT_ADV:
+   printf("802.1Q advanced\n\n");
+   ret=print_vlan_dot_adv(nga);
+  break;
+  
+  default: printf("unknown (%i)\n", t);
+ }
+ end:
+ return ret;
+}
+
+
+
 // =============================================================================
 
 
@@ -1187,8 +1362,7 @@ COM_ROOT_START(coms)
  COM_END
  
  COM_START(netconf)
-  COM_TERM(show, NULL, false)
-  COM_TERM(set, NULL, true)
+  COM_TERM(set, do_netconf_set, true)
  COM_END
  
  COM_START(password)
@@ -1226,7 +1400,7 @@ COM_ROOT_START(coms)
  COM_TERM(tree, do_tree, false)
  
  COM_START(vlan)
-  COM_TERM(show, NULL, false)
+  COM_TERM(show, do_vlan_show, false)
   COM_TERM(mode, NULL, true)
  COM_END
  
index ab8bdbbb968cb141669a69830146fbede53d8374..59f7058bfbae5ce360a885ed87d9d6d777be5085 100644 (file)
@@ -93,7 +93,7 @@ void displaySwitchTab (const struct swi_attr *sa, int nb) {
  }
  
  
- printf("Num\tMac\t\t\tProduct\t\tName\t\t\tIP/mask\t\t\t\tDHCP\tPorts\tFirmware\n");
+ printf("Num\tMac\t\t\tProduct\t\tName\t\t\tIP/mask\t\t\tDHCP\tPorts\tFirmware\n");
  
  for (i=0; i<nb; ++i) {
   printf("%i\t%s\t%s\t\t%s\t%s/", i, ether_ntoa(&sa[i].mac), sa[i].product, sa[i].name, inet_ntoa(sa[i].nc.ip));
index 50f0bc375439d62d25940504b828caf81bff62c5..d0d61def8b102dfd45db25815d63be00ab93a04b 100644 (file)
 #define SPEED_100              4
 #define SPEED_1000             5
 
+#define VLAN_DISABLED          0
 #define VLAN_PORT_BASIC                1
 #define VLAN_PORT_ADV          2
 #define VLAN_DOT_BASIC         3
 #define VLAN_DOT_ADV           4
 
+#define VLAN_NO                        0
+#define VLAN_UNTAGGED          1
+#define VLAN_TAGGED            2
+
 #define QOS_PORT               1
 #define QOS_DOT                        2
 
@@ -238,6 +243,19 @@ int ngadmin_setIGMPConf (struct ngadmin *nga, const struct igmp_conf *ic) EXPORT
 int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb) EXPORT;
 
 
+// 
+int ngadmin_setNetConf (struct ngadmin *nga, const struct net_conf *nc) EXPORT;
+
+
+// 
+int ngadmin_getVLANType (struct ngadmin *nga, int *t) EXPORT;
+
+
+// 
+int ngadmin_getVLANDotConf (struct ngadmin *nga, char *buf, int *len) EXPORT;
+
+
+
 
 #endif
 
index 30b654b2a83cdf60853239e030cb38f06f4a78a8..ecb5b71e8e9f7d152ef3227d5117547cf81d2dd3 100644 (file)
@@ -46,6 +46,8 @@
 #define ATTR_VLAN_TYPE         0x2000
 #define ATTR_VLAN_PORT_CONF    0x2400
 #define ATTR_VLAN_DOT_CONF     0x2800
+#define ATTR_VLAN_DESTROY      0x2C00
+#define ATTR_VLAN_PVID         0x3000
 #define ATTR_QOS_TYPE          0x3400
 #define ATTR_QOS_CONFIG                0x3800
 #define ATTR_BITRATE_INPUT     0x4C00
@@ -54,6 +56,7 @@
 #define ATTR_STORM_BITRATE     0x5800
 #define ATTR_MIRROR            0x5C00
 #define ATTR_PORTS_COUNT       0x6000
+#define ATTR_UNK_6400          0x6400
 #define ATTR_IGMP_ENABLE_VLAN  0x6800
 #define ATTR_IGMP_BLOCK_UNK    0x6C00
 #define ATTR_IGMP_VALID_V3     0x7000
index e71515d6ed5090129d9fe5ba03c00dbd35f36197..d976e3e19e7c38f7ef5d5d219ab8fb826d02676e 100644 (file)
@@ -82,12 +82,10 @@ int forceInterface (struct ngadmin *nga) {
  int ret;
  
  
  /*
  As described bellow, when you have multiple interfaces, this forces the packet 
  to go to a particular interface. 
  */
- ret=1;
  if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_BINDTODEVICE, nga->iface, strlen(nga->iface)+1))<0 ) {
   perror("setsockopt(SO_BINDTODEVICE)");
   return ret;
@@ -172,8 +170,8 @@ int sendNgPacket (struct ngadmin *nga, char code, const List *attr) {
 
 
 
-// ---------------------------------------------------------------------------------------------------
-int recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error, List *attr) {
+// -------------------------------------------------------------------------------------------------------------
+int recvNgPacket (struct ngadmin *nga, char code, unsigned short *error, unsigned short *attr_error, List *attr) {
  
  char buffer[1500];
  struct ng_packet np;
@@ -217,8 +215,7 @@ int recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *a
 int readRequest (struct ngadmin *nga, List *attr) {
  
  int i, ret=ERR_OK;
- unsigned short attr_error;
- char err;
+ unsigned short err, attr_error;
  
  
  if ( nga==NULL ) {
@@ -238,7 +235,7 @@ int readRequest (struct ngadmin *nga, List *attr) {
   ret=ERR_NET;
  }
  
- if ( err==7 && attr_error==ATTR_PASSWORD ) {
+ if ( err==0x0700 && attr_error==ATTR_PASSWORD ) {
   ret=ERR_BADPASS;
   goto end;
  }
@@ -257,8 +254,7 @@ int readRequest (struct ngadmin *nga, List *attr) {
 int writeRequest (struct ngadmin *nga, List *attr) {
  
  int i, ret=ERR_OK;
- unsigned short attr_error;
- char err;
+ unsigned short err, attr_error;
  
  
  if ( nga==NULL ) {
@@ -291,11 +287,13 @@ int writeRequest (struct ngadmin *nga, List *attr) {
   goto end;
  }
  
- if ( err==7 && attr_error==ATTR_PASSWORD ) {
+ if ( err==0x0700 && attr_error==ATTR_PASSWORD ) {
   ret=ERR_BADPASS;
   goto end;
  }
  
+ // err==0x0500
  
  end:
  // the switch replies to write request by just a header (no attributes), so the list can be destroyed
index a51992ea28aeef6b3b5c14613e73fcb907672290..c9043d2e871be961cbdee163d3706dccd51a3b0e 100644 (file)
@@ -32,7 +32,7 @@ int updateTimeout (struct ngadmin *nga);
 int sendNgPacket (struct ngadmin *nga, char code, const List *attr);
 
 // 
-int recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error, List *attr);
+int recvNgPacket (struct ngadmin *nga, char code, unsigned short *error, unsigned short *attr_error, List *attr);
 
 // 
 int readRequest (struct ngadmin *nga, List *attr);
index d1e33d1cc566696faa6d9cf82c8a2ef64bd493ee..1f32d09d88f3109e54ebe239914967847a0dd874 100644 (file)
@@ -589,7 +589,11 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) {
  List *attr;
  ListNode *ln;
  struct attr *at;
- int ret=ERR_OK, i;
+ int ret=ERR_OK;
+ struct {
+  char port;
+  int bitrate;
+ } __attribute__((packed)) *p;
  
  
  if ( nga==NULL || ports==NULL ) {
@@ -609,10 +613,12 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) {
  
  for (ln=attr->first; ln!=NULL; ln=ln->next) {
   at=ln->data;
-  if ( at->attr==ATTR_BITRATE_INPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
-   ports[i*2+0]=ntohl(*(int*)(1+(char*)at->data));
-  } else if ( at->attr==ATTR_BITRATE_OUTPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && i<nga->current->ports ) {
-   ports[i*2+1]=ntohl(*(int*)(1+(char*)at->data));
+  p=at->data;
+  if ( at->size<sizeof(*p) || p->port<1 || p->port>nga->current->ports ) continue;
+  if ( at->attr==ATTR_BITRATE_INPUT ) {
+   ports[(p->port-1)*2+0]=ntohl(p->bitrate);
+  } else if ( at->attr==ATTR_BITRATE_OUTPUT ) {
+   ports[(p->port-1)*2+1]=ntohl(p->bitrate);
   }
  }
  
@@ -872,7 +878,7 @@ int ngadmin_getMirror (struct ngadmin *nga, char *ports) {
  for (ln=attr->first; ln!=NULL; ln=ln->next) {
   at=ln->data;
   p=at->data;
-  if ( at->attr==ATTR_MIRROR && at->size>=2+sa->ports/8 && p[0]<=nga->current->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;
@@ -1118,3 +1124,143 @@ int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb) {
 
 
 
+// --------------------------------------------------------------------
+int ngadmin_setNetConf (struct ngadmin *nga, const struct net_conf *nc) {
+ List *attr;
+ struct swi_attr *sa;
+ int ret=ERR_OK;
+ if ( nga==NULL || nc==NULL ) {
+  return ERR_INVARG;
+ } else if ( (sa=nga->current)==NULL ) {
+  return ERR_NOTLOG;
+ }
+ attr=createEmptyList();
+ if ( nc->dhcp ) {
+  pushBackList(attr, newByteAttr(ATTR_DHCP, 1));
+ } else {
+  pushBackList(attr, newByteAttr(ATTR_DHCP, 0));
+  if ( nc->ip.s_addr!=0 ) pushBackList(attr, newAddrAttr(ATTR_IP, nc->ip));
+  if ( nc->netmask.s_addr!=0 ) pushBackList(attr, newAddrAttr(ATTR_NETMASK, nc->netmask));
+  if ( nc->gw.s_addr!=0 ) pushBackList(attr, newAddrAttr(ATTR_GATEWAY, nc->gw));
+ }
+ if ( (ret=writeRequest(nga, attr))!=ERR_OK ) {
+  goto end;
+ }
+ if ( nc->dhcp ) {
+  sa->nc.dhcp=true;
+ } else {
+  memcpy(&sa->nc, nc, sizeof(struct net_conf));
+ }
+ end:
+ return ret;
+}
+
+
+
+// --------------------------------------------------
+int ngadmin_getVLANType (struct ngadmin *nga, int *t) {
+ List *attr;
+ ListNode *ln;
+ struct attr *at;
+ int ret=ERR_OK;
+ if ( nga==NULL || t==NULL ) {
+  return ERR_INVARG;
+ } else if ( nga->current==NULL ) {
+  return ERR_NOTLOG;
+ }
+ attr=createEmptyList();
+ pushBackList(attr, newEmptyAttr(ATTR_VLAN_TYPE));
+ 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_TYPE && at->size>=1 ) {
+   *t= (int)*(char*)at->data ;
+   break;
+  }
+ }
+ end:
+ destroyList(attr, (void(*)(void*))freeAttr);
+ return ret;
+}
+
+
+
+// ------------------------------------------------------------------
+int ngadmin_getVLANDotConf (struct ngadmin *nga, char *buf, int *len) {
+ List *attr;
+ ListNode *ln;
+ struct attr *at;
+ struct swi_attr *sa;
+ int ret=ERR_OK, i;
+ char *b=buf, *p=NULL;
+ if ( nga==NULL || buf==NULL || len==NULL || *len<=0 ) {
+  return ERR_INVARG;
+ } else if ( (sa=nga->current)==NULL ) {
+  return ERR_NOTLOG;
+ }
+ attr=createEmptyList();
+ pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
+ if ( (ret=readRequest(nga, attr))!=ERR_OK ) {
+  goto end;
+ }
+ for (ln=attr->first; ln!=NULL; ln=ln->next) {
+  at=ln->data;
+  p=at->data;
+  if ( (b-buf)+2+sa->ports>*len ) break; // no more room
+  if ( at->attr==ATTR_VLAN_DOT_CONF && at->size>=4 ) {
+   *(unsigned short*)b=ntohs(*(unsigned short*)p);b+=2;
+   for (i=1; i<=sa->ports; ++i) {
+    if ( (p[3]>>(sa->ports-i))&1 ) *b++=VLAN_TAGGED; // tagged
+    else if ( (p[2]>>(sa->ports-i))&1 ) *b++=VLAN_UNTAGGED; // untagged
+    else *b++=VLAN_NO;
+   }
+  }
+ }
+ *len=b-buf;
+ end:
+ destroyList(attr, (void(*)(void*))freeAttr);
+ return ret;
+}
+
+
+
+
+
index a71df2eaa9740bf2b80c06a103a0025828e80484..a342c96761dd8e75fe202411f6c150d0e97044e0 100644 (file)
@@ -50,11 +50,7 @@ bool validateNgHeader (const struct ng_header *nh, char code, const struct ether
   return false;
  }
  
- if ( nh->unk2!=0 ) {
-  return false;
- }
- if ( *(unsigned short*)nh->unk3!=0 ) {
+ if ( *(unsigned short*)nh->unk2!=0 ) {
   return false;
  }
  
@@ -70,7 +66,7 @@ bool validateNgHeader (const struct ng_header *nh, char code, const struct ether
   return false;
  }
  
- if ( *(unsigned int*)nh->unk4!=0 ) {
+ if ( *(unsigned int*)nh->unk3!=0 ) {
   return false;
  }
  
@@ -184,6 +180,19 @@ struct attr* newByteAttr (unsigned short attr, unsigned char value) {
 
 
 
+// ---------------------------------------------------------
+struct attr* newShortAttr (unsigned short attr, short value) {
+ short *v=malloc(sizeof(short));
+ *v=value;
+ return newAttr(attr, sizeof(short), v);
+}
+
+
+
 // -----------------------------------------------------
 struct attr* newIntAttr (unsigned short attr, int value) {
  
@@ -197,6 +206,19 @@ struct attr* newIntAttr (unsigned short attr, int value) {
 
 
 
+// -----------------------------------------------------------------
+struct attr* newAddrAttr (unsigned short attr, struct in_addr value) {
+ struct in_addr *v=malloc(sizeof(struct in_addr));
+ *v=value;
+ return newAttr(attr, sizeof(struct in_addr), v);
+}
+
+
+
 // ----------------------------
 void freeAttr (struct attr *at) {
  
@@ -209,19 +231,14 @@ void freeAttr (struct attr *at) {
 
 
 
-// -----------------------------------------------------------------------------------------------------
-void extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error, List *attr) {
+// ---------------------------------------------------------------------------------------------------------------
+void extractPacketAttributes (struct ng_packet *np, unsigned short *error, unsigned short *attr_error, List *attr) {
  
  struct attr *at;
  
  
- if ( error!=NULL ) {
-  *error=np->nh->error;
- }
- if ( attr_error!=NULL ) {
-  *attr_error=ntohs(np->nh->attr);
- }
+ if ( error!=NULL ) *error=ntohs(np->nh->error);
+ if ( attr_error!=NULL ) *attr_error=ntohs(np->nh->attr);
  
  while ( getPacketTotalSize(np)<np->maxlen ) {
   
index 4b4407b094ec82456f28ff689a5605389a0514aa..3b26f1dfe1defa9c579c069d69130963d4e49c94 100644 (file)
 
 
 struct ng_header {
- char unk1; // always 1
- char code;
- char error;
- char unk2; // always 0
- unsigned short attr; // attribute code which caused error
- char unk3[2]; // always 0
- char client_mac[ETH_ALEN];
- char switch_mac[ETH_ALEN];
- unsigned int seqnum;
- char proto_id[4]; // always "NSDP"
- char unk4[4]; // always 0
+ char unk1;                    // always 1, maybe version
+ char code;                    // request code: read request, read reply, write request, write reply
+ unsigned short error;         // error code, 0 when no error
+ unsigned short attr;          // attribute code which caused error, 0 when no error
+ char unk2[2];                         // always 0, unknown
+ char client_mac[ETH_ALEN];    // client MAC address
+ char switch_mac[ETH_ALEN];    // switch MAC address
+ unsigned int seqnum;          // sequence number
+ char proto_id[4];             // always "NSDP", maybe short for "Netgear Switch Description Protocol"
+ char unk3[4];                         // always 0, unknown
  char data[0];
 } __attribute__((packed)) ;
 
@@ -57,8 +56,6 @@ struct attr {
 
 
 
-extern const unsigned short helloRequest[];
-
 extern const struct ether_addr nullMac;
 
 
@@ -99,14 +96,20 @@ struct attr* newAttr (unsigned short attr, unsigned short size, void *data);
 // 
 struct attr* newByteAttr (unsigned short attr, unsigned char value);
 
+// 
+struct attr* newShortAttr (unsigned short attr, short value);
+
 // 
 struct attr* newIntAttr (unsigned short attr, int value);
 
+// 
+struct attr* newAddrAttr (unsigned short attr, struct in_addr value);
+
 // 
 void freeAttr (struct attr *at);
 
 // 
-void extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error, List *attr);
+void extractPacketAttributes (struct ng_packet *np, unsigned short *error, unsigned short *attr_error, List *attr);
 
 // 
 void extractSwitchAttributes (struct swi_attr *sa, const List *l);