From 32cd44158f6f7de54afc5bc71a38216dd3ba48b0 Mon Sep 17 00:00:00 2001 From: darkcoven Date: Sat, 19 Nov 2011 12:00:00 +0100 Subject: [PATCH] Added support for clearing the switch settings to the defaults. Added support of QoS. Added support for restarting the switch. Lib: added an extra check of the remote port. --- cli/commands.c | 238 ++++++++++++++++++++++++++++++++++++++- cli/commands.h | 2 +- cli/common.c | 23 ++++ cli/common.h | 4 +- lib/ngadmin.h | 25 +++++ lib/src/network.c | 3 +- lib/src/ngadmin.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 566 insertions(+), 9 deletions(-) diff --git a/cli/commands.c b/cli/commands.c index e17891c..c50f531 100644 --- a/cli/commands.c +++ b/cli/commands.c @@ -123,6 +123,41 @@ static bool do_bitrate_show (int nb UNUSED, const char **com UNUSED, struct ngad +// ============================================================================= +// defaults + + +static bool do_defaults (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) { + + int i, ret=true; + const struct swi_attr *sa; + char line[16]; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + printf("The switch settings will be CLEARED. Continue ? [y/N]: "); + fflush(stdout); + + if ( fgets(line, sizeof(line), stdin)!=NULL && strcasecmp(line, "y\n")==0 ) { + i=ngadmin_defaults(nga); + printErrCode(i); + } + + + end: + + return ret; + +} + + + // ============================================================================= // firmware @@ -448,6 +483,159 @@ static bool do_ports_statistics_show (int nb UNUSED, const char **com UNUSED, st + +// ============================================================================= +// qos + + + +static bool do_qos_mode (int nb, const char **com, struct ngadmin *nga) { + + int i, s, ret=true; + const struct swi_attr *sa; + + + if ( nb==0 ) { + printf("Usage: qos mode port|802.1p\n"); + goto end; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + if ( strcasecmp(com[0], "port")==0 ) { + s=QOS_PORT; + } else if ( strcasecmp(com[0], "802.1p")==0 ) { + s=QOS_DOT; + } else { + printf("Unknown QOS mode\n"); + ret=false; + goto end; + } + + + i=ngadmin_setQOSMode(nga, s); + printErrCode(i); + + + end: + + return ret; + +} + + + +static bool do_qos_set (int nb, const char **com, struct ngadmin *nga) { + + int i, p; + const struct swi_attr *sa; + bool ret=true; + char d=PRIO_UNSPEC, *ports=NULL; + + + if ( nb<2 ) { + printf("Usage: qos set (all )|( [ ...])\n"); + ret=false; + goto end; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + ports=malloc(sa->ports*sizeof(char)); + + if ( strcmp(com[0], "all")==0 ) { + d=parsePrio(com[1]); + com+=2; + nb-=2; + } + + for (i=0; iports; ++i) { + ports[i]=d; + } + + for (i=0; isa->ports ) continue; + ports[p-1]=parsePrio(com[i+1]); + } + + + i=ngadmin_setQOSValues(nga, ports); + printErrCode(i); + + + end: + free(ports); + + return ret; + +} + + + +static bool do_qos_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i, s=0, ret=true; + const struct swi_attr *sa; + char *ports=NULL; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + if ( (i=ngadmin_getQOSMode(nga, &s))!=ERR_OK ) { + printErrCode(i); + ret=false; + goto end; + } + + + printf("QOS mode: "); + + if ( s==QOS_DOT ) { + printf("802.1p\n"); + goto end; + } else if ( s!=QOS_PORT ) { + printf("unknown (%i)\n", s); + goto end; + } + + printf("port based\n"); + + ports=malloc(sa->ports*sizeof(char)); + + if ( (i=ngadmin_getQOSValues(nga, ports))!=ERR_OK ) { + printErrCode(i); + ret=false; + goto end; + } + + for (i=0; iports; ++i) { + printf("port %i: %s\n", i+1, prio[(int)ports[i]]); + } + + + end: + free(ports); + + return ret; + +} + + + // ============================================================================= // quit @@ -462,6 +650,41 @@ static bool do_quit (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga +// ============================================================================= +// restart + + +static bool do_restart (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) { + + int i, ret=true; + const struct swi_attr *sa; + char line[16]; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + printf("The switch will be restarted. Continue ? [y/N]: "); + fflush(stdout); + + if ( fgets(line, sizeof(line), stdin)!=NULL && strcasecmp(line, "y\n")==0 ) { + i=ngadmin_restart(nga); + printErrCode(i); + } + + + end: + + return ret; + +} + + + // ============================================================================= // scan @@ -680,13 +903,18 @@ COM_ROOT_START(coms) COM_TERM(cabletest, NULL, true) - COM_TERM(defaults, NULL, false) + COM_TERM(defaults, do_defaults, false) COM_START(firmware) COM_TERM(show, do_firmware_show, false) COM_TERM(upgrade, do_firmware_upgrade, true) COM_END + COM_START(igmp) + COM_TERM(set, NULL, false) + COM_TERM(show, NULL, false) + COM_END + COM_TERM(list, do_list, false) COM_TERM(login, do_login, true) @@ -723,14 +951,14 @@ COM_ROOT_START(coms) COM_END COM_START(qos) - COM_TERM(mode, NULL, true) - COM_TERM(set, NULL, true) - COM_TERM(show, NULL, false) + COM_TERM(mode, do_qos_mode, true) + COM_TERM(set, do_qos_set, true) + COM_TERM(show, do_qos_show, false) COM_END COM_TERM(quit, do_quit, false) - COM_TERM(restart, NULL, false) + COM_TERM(restart, do_restart, false) COM_TERM(scan, do_scan, false) diff --git a/cli/commands.h b/cli/commands.h index f289e71..3877d9d 100644 --- a/cli/commands.h +++ b/cli/commands.h @@ -19,8 +19,8 @@ struct TreeNode { #define COM_ROOT_START(v) const struct TreeNode v={.name="", .comfunc=NULL, .hasArgs=false, .sub=(const struct TreeNode[]){ #define COM_ROOT_END {.name=NULL, .comfunc=NULL, .hasArgs=false, .sub=NULL}}}; #define COM_START(nam) {.name=#nam, .comfunc=NULL, .hasArgs=false, .sub=(const struct TreeNode[]){ -#define COM_TERM(nam, func, args) {.name=#nam, .comfunc=func, .hasArgs=args, .sub=NULL}, #define COM_END {.name=NULL, .comfunc=NULL, .hasArgs=false, .sub=NULL}}}, +#define COM_TERM(nam, func, args) {.name=#nam, .comfunc=func, .hasArgs=args, .sub=NULL}, extern const struct TreeNode coms; diff --git a/cli/common.c b/cli/common.c index f621d0b..ab8bdbb 100644 --- a/cli/common.c +++ b/cli/common.c @@ -44,6 +44,15 @@ const char* bitrates[]={ }; +const char* prio[]={ + NULL, + "high", + "medium", + "normal", + "low", + NULL +}; + int parseBitrate (const char *s) { @@ -59,6 +68,20 @@ int parseBitrate (const char *s) { +char parsePrio (const char *s) { + + int i; + + + for (i=1; prio[i]!=NULL && strcasecmp(prio[i], s)!=0; ++i); + + + return (char)i; + +} + + + void displaySwitchTab (const struct swi_attr *sa, int nb) { int i=0; diff --git a/cli/common.h b/cli/common.h index 3d4b5e0..d746977 100644 --- a/cli/common.h +++ b/cli/common.h @@ -17,12 +17,14 @@ extern int cont; -extern const char* bitrates[]; +extern const char *bitrates[], *prio[]; void displaySwitchTab (const struct swi_attr *sa, int nb); void printErrCode (int err); int parseBitrate (const char *s); +char parsePrio (const char *s); + // int trim (char *txt, int start); diff --git a/lib/ngadmin.h b/lib/ngadmin.h index 0326d32..1771a93 100644 --- a/lib/ngadmin.h +++ b/lib/ngadmin.h @@ -180,6 +180,31 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) EXPORT; int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) EXPORT; +// +int ngadmin_getQOSMode (struct ngadmin *nga, int *s) EXPORT; + + +// +int ngadmin_setQOSMode (struct ngadmin *nga, int s) EXPORT; + + +// +int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) EXPORT; + + +// +int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) EXPORT; + + +// +int ngadmin_restart (struct ngadmin *nga) EXPORT; + + +// +int ngadmin_defaults (struct ngadmin *nga) EXPORT; + + + #endif diff --git a/lib/src/network.c b/lib/src/network.c index 793dc00..cf293d0 100644 --- a/lib/src/network.c +++ b/lib/src/network.c @@ -172,10 +172,9 @@ List* recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short memset(&remote, 0, sizeof(struct sockaddr_in)); remote.sin_family=AF_INET; - remote.sin_port=htons(SWITCH_PORT); while ( (len=recvfrom(nga->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&remote, &slen))>=0 ) { - if ( len>=(int)sizeof(struct ng_header) && validateNgHeader(np.nh, code, &nga->localmac, sa==NULL ? NULL : &sa->mac , nga->seq) ) { + if ( ntohs(remote.sin_port)==SWITCH_PORT && len>=(int)sizeof(struct ng_header) && validateNgHeader(np.nh, code, &nga->localmac, sa==NULL ? NULL : &sa->mac , nga->seq) ) { initNgPacket(&np); l=extractPacketAttributes(&np, error, attr_error); break; diff --git a/lib/src/ngadmin.c b/lib/src/ngadmin.c index 179302e..57b8e79 100644 --- a/lib/src/ngadmin.c +++ b/lib/src/ngadmin.c @@ -176,6 +176,7 @@ int ngadmin_scan (struct ngadmin *nga) { } free(nga->swi_tab); + nga->swi_tab=NULL; nga->swi_count=0; nga->current=NULL; @@ -825,3 +826,282 @@ int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) { } + +// ------------------------------------------------- +int ngadmin_getQOSMode (struct ngadmin *nga, int *s) { + + List *attr; + ListNode *ln; + struct attr *at; + int ret=ERR_OK, i; + + + if ( nga==NULL || s==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newEmptyAttr(ATTR_QOS_TYPE)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_READ_REQ, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) { + ret=ERR_NET; + goto end; + } + + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + if ( at->attr==ATTR_QOS_TYPE && at->size>=1 ) { + *s= *(char*)at->data ; + break; + } + } + + destroyList(attr, (void(*)(void*))freeAttr); + + + end: + + return ret; + +} + + +// ------------------------------------------------ +int ngadmin_setQOSMode (struct ngadmin *nga, int s) { + + List *attr; + int ret=ERR_OK, i; + char err; + unsigned short attr_error; + + + if ( nga==NULL || s<1 || s>2 ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + pushBackList(attr, newByteAttr(ATTR_QOS_TYPE, s)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_WRITE_REQ, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) { + ret=ERR_NET; + goto end; + } + + destroyList(attr, (void(*)(void*))freeAttr); + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + end: + + return ret; + +} + + + +// ------------------------------------------------------- +int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) { + + List *attr; + ListNode *ln; + struct attr *at; + int ret=ERR_OK, i; + char *p; + + + if ( nga==NULL || ports==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newEmptyAttr(ATTR_QOS_CONFIG)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_READ_REQ, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))==NULL ) { + ret=ERR_NET; + goto end; + } + + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + p=at->data; + if ( at->attr==ATTR_QOS_CONFIG && at->size>=2 && --p[0]>=0 && p[0]current->ports ) { + ports[(int)p[0]]=p[1]; + } + } + + destroyList(attr, (void(*)(void*))freeAttr); + + + end: + + return ret; + +} + + + +// -------------------------------------------------------------- +int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) { + + List *attr; + int ret=ERR_OK, i; + char err; + unsigned short attr_error; + char *p; + + + if ( nga==NULL || ports==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + + for (i=0; icurrent->ports; ++i) { + if ( ports[i]>=PRIO_HIGH && ports[i]<=PRIO_LOW ) { + p=malloc(2); + p[0]=i+1; + p[1]=ports[i]; + pushBackList(attr, newAttr(ATTR_QOS_CONFIG, 2, p)); + } + } + + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_WRITE_REQ, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) { + ret=ERR_NET; + goto end; + } + + destroyList(attr, (void(*)(void*))freeAttr); + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + end: + + return ret; + +} + + + +// -------------------------------------- +int ngadmin_restart (struct ngadmin *nga) { + + List *attr; + int ret=ERR_OK, i; + char err; + unsigned short attr_error; + + + if ( nga==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + pushBackList(attr, newByteAttr(ATTR_RESTART, 1)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_WRITE_REQ, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) { + ret=ERR_NET; + goto end; + } + + destroyList(attr, (void(*)(void*))freeAttr); + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + end: + + return ret; + +} + + + +// --------------------------------------- +int ngadmin_defaults (struct ngadmin *nga) { + + List *attr; + int ret=ERR_OK, i; + char err; + unsigned short attr_error; + + + if ( nga==NULL ) { + return ERR_INVARG; + } else if ( nga->current==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + pushBackList(attr, newByteAttr(ATTR_DEFAULTS, 1)); + pushBackList(attr, newEmptyAttr(ATTR_END)); + i=sendNgPacket(nga, CODE_WRITE_REQ, attr); + destroyList(attr, (void(*)(void*))freeAttr); + if ( i<0 || (attr=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error))==NULL ) { + ret=ERR_NET; + goto end; + } + + destroyList(attr, (void(*)(void*))freeAttr); + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + // successful: delog and clean list + free(nga->swi_tab); + nga->swi_tab=NULL; + nga->swi_count=0; + nga->current=NULL; + + + end: + + return ret; + +} + + -- 2.39.5