From ed59e71ff9ef804fab90898bb2708c56b64eb52e Mon Sep 17 00:00:00 2001 From: darkcoven Date: Sun, 20 Nov 2011 12:00:00 +0100 Subject: [PATCH] Added the possibility to specify the command timeout. Added basic support for cable testing. Added support of port mirroring. Added support for IGMP parameters. Lib: added comments to explain some restrictions in the network code. Lib: improved network code by adding higher level helpers. --- cli/admin.c | 16 +- cli/commands.c | 270 +++++++++++++++++++- lib/ngadmin.h | 35 ++- lib/src/lib.h | 8 +- lib/src/network.c | 132 +++++++++- lib/src/network.h | 8 +- lib/src/ngadmin.c | 595 +++++++++++++++++++++++---------------------- lib/src/protocol.c | 13 +- lib/src/protocol.h | 6 +- 9 files changed, 757 insertions(+), 326 deletions(-) diff --git a/cli/admin.c b/cli/admin.c index 3318cbc..9e0aea6 100644 --- a/cli/admin.c +++ b/cli/admin.c @@ -129,10 +129,12 @@ int main (int argc, char **argv) { {"force-interface", no_argument, NULL, 'f'}, {"interface", required_argument, NULL, 'i'}, {"help", no_argument, NULL, 'h'}, + {"timeout", required_argument, NULL, 't'}, {0, 0, 0, 0} }; char *line, *com[MAXCOM]; const char *iface="eth0"; + float timeout=0.f; bool kb=false, force=false; struct ngadmin *nga=NULL; struct timeval tv; @@ -143,7 +145,7 @@ int main (int argc, char **argv) { opterr=0; - while ( (n=getopt_long(argc, argv, "bfi:h", opts, NULL))!=-1 ) { + while ( (n=getopt_long(argc, argv, "bfi:ht:", opts, NULL))!=-1 ) { switch ( n ) { case 'b': @@ -162,6 +164,10 @@ int main (int argc, char **argv) { printf("Usage: %s [-b] [-f] [-i ]\n", argv[0]); goto end; + case 't': + timeout=strtof(optarg, NULL); + break; + case '?': printf("Unknown option: \"%s\"\n", argv[optind-1]); goto end; @@ -187,9 +193,11 @@ int main (int argc, char **argv) { } // set timeout - tv.tv_sec=3; - tv.tv_usec=0; - ngadmin_setTimeout(nga, &tv); + if ( timeout>0.f ) { + tv.tv_sec=(int)timeout; + tv.tv_usec=(int)((timeout-(float)tv.tv_sec)*1e6f); + ngadmin_setTimeout(nga, &tv); + } if ( kb && ngadmin_setKeepBroadcasting(nga, true)!=ERR_OK ) goto end; diff --git a/cli/commands.c b/cli/commands.c index c50f531..c134905 100644 --- a/cli/commands.c +++ b/cli/commands.c @@ -123,11 +123,64 @@ static bool do_bitrate_show (int nb UNUSED, const char **com UNUSED, struct ngad +// ============================================================================= +// cabletest + + +static bool do_cabletest (int nb, const char **com, struct ngadmin *nga) { + + bool ret=true; + const struct swi_attr *sa; + struct cabletest *ct=NULL; + int i, j=0, k=0; + + + if ( nb<1 ) { + printf("Usage: cabletest [ ...]\n"); + goto end; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + ct=malloc(sa->ports*sizeof(struct cabletest)); + memset(ct, 0, sa->ports*sizeof(struct cabletest)); + + while ( k=1 && ct[j].port<=sa->ports ) ++j; + } + + i=ngadmin_cabletest(nga, ct, j); + if ( i<0 ) { + printErrCode(i); + ret=false; + goto end; + } + + + for (i=0; i \n"); + return false; + } + + if ( ngadmin_getCurrentSwitch(nga)==NULL ) { + printf("must be logged\n"); + return false; + } + + ic.enable=strtol(com[0], NULL, 0); + ic.vlan=strtol(com[1], NULL, 0); + ic.validate=strtol(com[2], NULL, 0); + ic.block=strtol(com[3], NULL, 0); + + i=ngadmin_setIGMPConf(nga, &ic); + printErrCode(i); + + + return true; + +} + + + +static bool do_igmp_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + const struct swi_attr *sa; + struct igmp_conf ic; + bool ret=true; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + i=ngadmin_getIGMPConf(nga, &ic); + if ( i!=ERR_OK ) { + printErrCode(i); + ret=false; + goto end; + } + + + printf("IGMP snooping enabled: %s\n", ic.enable ? "yes" : "no" ); + printf("IGMP snooping vlan: %u\n", ic.vlan); + printf("Validate IGMPv3 headers: %s\n", ic.validate ? "yes" : "no" ); + printf("Block unknown multicast addresses: %s\n", ic.block ? "yes" : "no" ); + + + + end: + + return ret; + +} + + + // ============================================================================= // list @@ -259,6 +384,136 @@ static bool do_login (int nb, const char **com, struct ngadmin *nga) { +// ============================================================================= +// mirror + + +static bool do_mirror_disable (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + int i; + + + if ( ngadmin_getCurrentSwitch(nga)==NULL ) { + printf("must be logged\n"); + return false; + } + + + i=ngadmin_setMirror(nga, NULL); + printErrCode(i); + + + return true; + +} + + + +static bool do_mirror_set (int nb, const char **com, struct ngadmin *nga) { + + const struct swi_attr *sa; + char *ports=NULL; + bool ret=true; + int i, k=0; + + + if ( nb<3 ) { + printf("Usage: mirror set clone [ ...]\n"); + goto end; + } + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + ret=false; + goto end; + } + + + ports=malloc((sa->ports+1)*sizeof(char)); + memset(ports, 0, sa->ports+1); + + ports[0]=strtol(com[k++], NULL, 0); + if ( ports[0]<1 || ports[0]>sa->ports || strcasecmp(com[k++], "clone")!=0 ) { + printf("syntax error\n"); + ret=false; + goto end; + } + + + while ( ksa->ports ) { + printf("port out of range\n"); + ret=false; + goto end; + } else if ( i==ports[0] ) { + printf("destination port cannot be in port list\n"); + ret=false; + goto end; + } + ports[i]=1; + } + + + i=ngadmin_setMirror(nga, ports); + printErrCode(i); + + + end: + free(ports); + + return true; + +} + + + +static bool do_mirror_show (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga) { + + const struct swi_attr *sa; + char *ports=NULL; + int i; + + + if ( (sa=ngadmin_getCurrentSwitch(nga))==NULL ) { + printf("must be logged\n"); + return false; + } + + + ports=malloc((sa->ports+1)*sizeof(char)); + + i=ngadmin_getMirror(nga, ports); + if ( i!=ERR_OK ) { + printErrCode(i); + goto end; + } + + if ( ports[0]==0 ) { + printf("port mirroring is disabled\n"); + goto end; + } + + printf("destination: %i\n", ports[0]); + printf("ports: "); + for (i=1; i<=sa->ports; ++i) { + if ( ports[i] ) { + printf("%i ", i); + } + } + printf("\n"); + + + + end: + free(ports); + + return true; + +} + + + // ============================================================================= // name @@ -901,7 +1156,7 @@ COM_ROOT_START(coms) COM_TERM(show, do_bitrate_show, false) COM_END - COM_TERM(cabletest, NULL, true) + COM_TERM(cabletest, do_cabletest, true) COM_TERM(defaults, do_defaults, false) @@ -911,8 +1166,8 @@ COM_ROOT_START(coms) COM_END COM_START(igmp) - COM_TERM(set, NULL, false) - COM_TERM(show, NULL, false) + COM_TERM(set, do_igmp_set, true) + COM_TERM(show, do_igmp_show, false) COM_END COM_TERM(list, do_list, false) @@ -920,10 +1175,9 @@ COM_ROOT_START(coms) COM_TERM(login, do_login, true) COM_START(mirror) - COM_TERM(enable, NULL, false) - COM_TERM(disable, NULL, false) - COM_TERM(set, NULL, true) - COM_TERM(show, NULL, false) + COM_TERM(disable, do_mirror_disable, false) + COM_TERM(set, do_mirror_set, true) + COM_TERM(show, do_mirror_show, false) COM_END COM_START(name) diff --git a/lib/ngadmin.h b/lib/ngadmin.h index 1771a93..50f0bc3 100644 --- a/lib/ngadmin.h +++ b/lib/ngadmin.h @@ -79,7 +79,7 @@ struct net_conf { struct swi_attr { - char product[PRODUCT_SIZE]; // product name (eg. GS108E) + char product[PRODUCT_SIZE]; // product name (eg. GS108EV1) char name[NAME_SIZE]; // custom name char firmware[FIRMWARE_SIZE]; // firmware version string unsigned char ports; // number of ports @@ -95,6 +95,20 @@ struct port_stats { }; +struct igmp_conf { + bool enable; + unsigned short vlan; + bool validate; + bool block; +}; + + +struct cabletest { + char port; + int v1; + int v2; +}; + // initialize NgAdmin lib @@ -204,6 +218,25 @@ int ngadmin_restart (struct ngadmin *nga) EXPORT; int ngadmin_defaults (struct ngadmin *nga) EXPORT; +// +int ngadmin_getMirror (struct ngadmin *nga, char *ports) EXPORT; + + +// +int ngadmin_setMirror (struct ngadmin *nga, const char *ports) EXPORT; + + +// +int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic) EXPORT; + + +// +int ngadmin_setIGMPConf (struct ngadmin *nga, const struct igmp_conf *ic) EXPORT; + + +// +int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb) EXPORT; + #endif diff --git a/lib/src/lib.h b/lib/src/lib.h index f71fb2b..30b654b 100644 --- a/lib/src/lib.h +++ b/lib/src/lib.h @@ -41,6 +41,8 @@ #define ATTR_PORT_STATUS 0x0C00 #define ATTR_PORT_STATISTICS 0x1000 #define ATTR_STATS_RESET 0x1400 +#define ATTR_CABLETEST_DO 0x1800 +#define ATTR_CABLETEST_RESULT 0x1C00 #define ATTR_VLAN_TYPE 0x2000 #define ATTR_VLAN_PORT_CONF 0x2400 #define ATTR_VLAN_DOT_CONF 0x2800 @@ -52,9 +54,9 @@ #define ATTR_STORM_BITRATE 0x5800 #define ATTR_MIRROR 0x5C00 #define ATTR_PORTS_COUNT 0x6000 -#define ATTR_UNK_6800 0x6800 -#define ATTR_UNK_6C00 0x6C00 -#define ATTR_UNK_7000 0x7000 +#define ATTR_IGMP_ENABLE_VLAN 0x6800 +#define ATTR_IGMP_BLOCK_UNK 0x6C00 +#define ATTR_IGMP_VALID_V3 0x7000 #define ATTR_UNK_7400 0x7400 #define ATTR_END 0xFFFF diff --git a/lib/src/network.c b/lib/src/network.c index cf293d0..e71515d 100644 --- a/lib/src/network.c +++ b/lib/src/network.c @@ -29,6 +29,13 @@ int startNetwork (struct ngadmin *nga) { close(nga->sock); return ret; } + /* + Here we have a problem: when you have multiple interfaces, sending a packet to + 255.255.255.255 may not send it to the interface you want. If you bind() to + the address of the interface, you will not be able to receive broadcasts. + The only solution I have found yet is in this case to use + setsockopt(SO_BINDTODEVICE) but this requires root priviledges. + */ //local.sin_addr=(*(struct sockaddr_in*)&ifr.ifr_addr).sin_addr; // FIXME // get the interface MAC address @@ -76,12 +83,22 @@ int forceInterface (struct ngadmin *nga) { + /* + 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; } + /* + If the switch's IP is not in your network range, for instance because you do + not have DHCP enabled or you started the switch after it, this allows to + bypass the routing tables and consider every address is directly reachable on + the interface. + */ ret=1; if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_DONTROUTE, &ret, sizeof(ret)))<0 ) { perror("setsockopt(SO_DONTROUTE)"); @@ -155,15 +172,14 @@ int sendNgPacket (struct ngadmin *nga, char code, const List *attr) { -// ----------------------------------------------------------------------------------------- -List* recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error) { +// --------------------------------------------------------------------------------------------------- +int recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error, List *attr) { char buffer[1500]; struct ng_packet np; struct sockaddr_in remote; socklen_t slen=sizeof(struct sockaddr_in); const struct swi_attr *sa=nga->current; - List *l=NULL; int len; @@ -173,16 +189,120 @@ List* recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short memset(&remote, 0, sizeof(struct sockaddr_in)); remote.sin_family=AF_INET; - while ( (len=recvfrom(nga->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&remote, &slen))>=0 ) { + while ( 1 ) { + + len=recvfrom(nga->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&remote, &slen); + + if ( len<0 ) { + break; + } + 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); + extractPacketAttributes(&np, error, attr_error, attr); + len=0; break; } + + } + + + return len; + +} + + + +// ---------------------------------------------- +int readRequest (struct ngadmin *nga, List *attr) { + + int i, ret=ERR_OK; + unsigned short attr_error; + char err; + + + if ( nga==NULL ) { + ret=ERR_INVARG; + goto end; + } + + // add end attribute to end + pushBackList(attr, newEmptyAttr(ATTR_END)); + + i=sendNgPacket(nga, CODE_READ_REQ, attr); + + // the list will be filled again by recvNgPacket + clearList(attr, (void(*)(void*))freeAttr); + + if ( i<0 || (i=recvNgPacket(nga, CODE_READ_REP, &err, &attr_error, attr))<0 ) { + ret=ERR_NET; + } + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; + } + + + end: + + + return ret; + +} + + + +// ----------------------------------------------- +int writeRequest (struct ngadmin *nga, List *attr) { + + int i, ret=ERR_OK; + unsigned short attr_error; + char err; + + + if ( nga==NULL ) { + ret=ERR_INVARG; + goto end; + } else if ( nga->current==NULL ) { + ret=ERR_NOTLOG; + goto end; + } + + + if ( attr==NULL ) { + attr=createEmptyList(); + } + + // add password attribute to start + pushFrontList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); + + // add end attribute to end + pushBackList(attr, newEmptyAttr(ATTR_END)); + + i=sendNgPacket(nga, CODE_WRITE_REQ, attr); + + // the list will be filled again by recvNgPacket + // but normally it will be still empty + clearList(attr, (void(*)(void*))freeAttr); + + if ( i<0 || (i=recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, attr))<0 ) { + ret=ERR_NET; + goto end; + } + + if ( err==7 && attr_error==ATTR_PASSWORD ) { + ret=ERR_BADPASS; + goto end; } - return l; + end: + // the switch replies to write request by just a header (no attributes), so the list can be destroyed + destroyList(attr, (void(*)(void*))freeAttr); + + + return ret; } diff --git a/lib/src/network.h b/lib/src/network.h index 1d6fc1f..a51992e 100644 --- a/lib/src/network.h +++ b/lib/src/network.h @@ -32,7 +32,13 @@ int updateTimeout (struct ngadmin *nga); int sendNgPacket (struct ngadmin *nga, char code, const List *attr); // -List* recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error); +int recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error, List *attr); + +// +int readRequest (struct ngadmin *nga, List *attr); + +// +int writeRequest (struct ngadmin *nga, List *attr); diff --git a/lib/src/ngadmin.c b/lib/src/ngadmin.c index 57b8e79..d1e33d1 100644 --- a/lib/src/ngadmin.c +++ b/lib/src/ngadmin.c @@ -4,7 +4,7 @@ -static const struct timeval default_timeout={.tv_sec=3, .tv_usec=0}; +static const struct timeval default_timeout={.tv_sec=4, .tv_usec=0}; @@ -190,7 +190,7 @@ int ngadmin_scan (struct ngadmin *nga) { // send request to all potential switches i=sendNgPacket(nga, CODE_READ_REQ, attr); - destroyList(attr, (void(*)(void*))freeAttr); + clearList(attr, (void(*)(void*))freeAttr); if ( i<0 ) { return ERR_NET; } @@ -198,10 +198,10 @@ int ngadmin_scan (struct ngadmin *nga) { // try to receive any packets until timeout swiList=createEmptyList(); - while ( (attr=recvNgPacket(nga, CODE_READ_REP, NULL, NULL))!=NULL ) { + while ( recvNgPacket(nga, CODE_READ_REP, NULL, NULL, attr)>=0 ) { sa=malloc(sizeof(struct swi_attr)); extractSwitchAttributes(sa, attr); - destroyList(attr, (void(*)(void*))freeAttr); + clearList(attr, (void(*)(void*))freeAttr); pushBackList(swiList, sa); } @@ -252,10 +252,8 @@ const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga) { int ngadmin_login (struct ngadmin *nga, int id) { List *attr; - int ret=ERR_OK, i; + int ret=ERR_OK; struct swi_attr *sa; - char err; - unsigned short attr_error; if ( nga==NULL ) { @@ -270,27 +268,14 @@ int ngadmin_login (struct ngadmin *nga, int id) { attr=createEmptyList(); pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); - 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, &err, &attr_error))==NULL ) { - ret=ERR_NET; + if ( (ret=readRequest(nga, attr))!=ERR_OK ) { + // login failed nga->current=NULL; - goto end; } - destroyList(attr, (void(*)(void*))freeAttr); - if ( err==7 && attr_error==ATTR_PASSWORD ) { - ret=ERR_BADPASS; - nga->current=NULL; - goto end; - } - - end: - return ret; } @@ -316,11 +301,7 @@ int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) { attr=createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_PORT_STATUS)); - 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; + if ( (ret=readRequest(nga, attr))!=ERR_OK ) { goto end; } @@ -332,10 +313,9 @@ int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) { } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); return ret; @@ -347,9 +327,7 @@ int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) { int ngadmin_setName (struct ngadmin *nga, const char *name) { List *attr; - int ret=ERR_OK, i; - char err; - unsigned short attr_error; + int ret=ERR_OK; if ( nga==NULL ) { @@ -360,23 +338,8 @@ int ngadmin_setName (struct ngadmin *nga, const char *name) { attr=createEmptyList(); - pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); - if ( name==NULL ) { - pushBackList(attr, newEmptyAttr(ATTR_NAME)); - } else { - pushBackList(attr, newAttr(ATTR_NAME, strlen(name), strdup(name))); - } - 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; + pushBackList(attr, name==NULL ? newEmptyAttr(ATTR_NAME) : newAttr(ATTR_NAME, strlen(name), strdup(name)) ); + if ( (ret=writeRequest(nga, attr))!=ERR_OK ) { goto end; } @@ -403,7 +366,7 @@ int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) { List *attr; ListNode *ln; struct attr *at; - int ret=ERR_OK, i; + int ret=ERR_OK; int port; @@ -416,14 +379,11 @@ int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) { attr=createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_PORT_STATISTICS)); - 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; + 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_PORT_STATISTICS && at->size>=49 && (port=(int)(*(char*)at->data)-1)>=0 && portcurrent->ports ) { @@ -434,10 +394,9 @@ int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) { } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); return ret; @@ -449,41 +408,13 @@ int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) { int ngadmin_resetPortsStatistics (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_STATS_RESET, 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; + return writeRequest(nga, attr); } @@ -493,9 +424,7 @@ int ngadmin_resetPortsStatistics (struct ngadmin *nga) { int ngadmin_changePassword (struct ngadmin *nga, const char* pass) { List *attr; - int ret=ERR_OK, i; - char err; - unsigned short attr_error; + int ret=ERR_OK; if ( nga==NULL || pass==NULL ) { @@ -506,20 +435,8 @@ int ngadmin_changePassword (struct ngadmin *nga, const char* pass) { attr=createEmptyList(); - pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); pushBackList(attr, newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass))); - 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; + if ( (ret=writeRequest(nga, attr))!=ERR_OK ) { goto end; } @@ -542,7 +459,7 @@ int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) { List *attr; ListNode *ln; struct attr *at; - int ret=ERR_OK, i; + int ret=ERR_OK; if ( nga==NULL || s==NULL ) { @@ -554,14 +471,11 @@ int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) { attr=createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_STORM_ENABLE)); - 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; + 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_STORM_ENABLE && at->size>=1 ) { @@ -570,10 +484,9 @@ int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) { } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); return ret; @@ -585,40 +498,13 @@ int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) { int ngadmin_setStormFilterState (struct ngadmin *nga, int s) { 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_STORM_ENABLE, s!=0)); - 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; + return writeRequest(nga, attr); } @@ -642,25 +528,21 @@ int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) { attr=createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_STORM_BITRATE)); - 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; + 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_STORM_BITRATE && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && icurrent->ports ) { + if ( at->attr==ATTR_STORM_BITRATE && at->size>=5 && (i=(int)*(char*)(at->data)-1)>=0 && icurrent->ports ) { ports[i]=ntohl(*(int*)(1+(char*)at->data)); } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); return ret; @@ -672,9 +554,7 @@ int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) { int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) { List *attr; - int ret=ERR_OK, i; - char err; - unsigned short attr_error; + int i; char *p; @@ -686,7 +566,6 @@ int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) { attr=createEmptyList(); - pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); for (i=0; icurrent->ports; ++i) { if ( ports[i]>=0 && ports[i]<=11 ) { @@ -697,25 +576,8 @@ int ngadmin_setStormFilterValues (struct ngadmin *nga, const int *ports) { } } - 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; + return writeRequest(nga, attr); } @@ -740,14 +602,11 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) { attr=createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_BITRATE_INPUT)); pushBackList(attr, newEmptyAttr(ATTR_BITRATE_OUTPUT)); - 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; + 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_BITRATE_INPUT && at->size>=5 && (i=*(char*)(at->data)-1)>=0 && icurrent->ports ) { @@ -757,10 +616,9 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) { } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); return ret; @@ -772,9 +630,7 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) { int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) { List *attr; - int ret=ERR_OK, i; - char err; - unsigned short attr_error; + int i; char *p; @@ -786,7 +642,6 @@ int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) { attr=createEmptyList(); - pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); for (i=0; icurrent->ports; ++i) { if ( ports[2*i+0]>=0 && ports[2*i+0]<=11 ) { @@ -803,25 +658,8 @@ int ngadmin_setBitrateLimits (struct ngadmin *nga, const int *ports) { } } - 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; + return writeRequest(nga, attr); } @@ -833,7 +671,7 @@ int ngadmin_getQOSMode (struct ngadmin *nga, int *s) { List *attr; ListNode *ln; struct attr *at; - int ret=ERR_OK, i; + int ret=ERR_OK; if ( nga==NULL || s==NULL ) { @@ -845,14 +683,11 @@ int ngadmin_getQOSMode (struct ngadmin *nga, int *s) { 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; + 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_QOS_TYPE && at->size>=1 ) { @@ -861,10 +696,9 @@ int ngadmin_getQOSMode (struct ngadmin *nga, int *s) { } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); return ret; @@ -875,40 +709,17 @@ int ngadmin_getQOSMode (struct ngadmin *nga, int *s) { 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 ) { + if ( sQOS_DOT ) { 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; + return writeRequest(nga, attr); } @@ -920,7 +731,7 @@ int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) { List *attr; ListNode *ln; struct attr *at; - int ret=ERR_OK, i; + int ret=ERR_OK; char *p; @@ -933,11 +744,7 @@ int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) { 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; + if ( (ret=readRequest(nga, attr))<0 ) { goto end; } @@ -949,10 +756,10 @@ int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) { } } - destroyList(attr, (void(*)(void*))freeAttr); - end: + destroyList(attr, (void(*)(void*))freeAttr); + return ret; @@ -964,9 +771,7 @@ int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) { int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) { List *attr; - int ret=ERR_OK, i; - char err; - unsigned short attr_error; + int i; char *p; @@ -978,7 +783,6 @@ int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) { 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 ) { @@ -989,22 +793,50 @@ int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) { } } - 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); + return writeRequest(nga, attr); + +} + + + +// -------------------------------------- +int ngadmin_restart (struct ngadmin *nga) { - if ( err==7 && attr_error==ATTR_PASSWORD ) { - ret=ERR_BADPASS; + List *attr; + + + attr=createEmptyList(); + pushBackList(attr, newByteAttr(ATTR_RESTART, 1)); + + + return writeRequest(nga, attr); + +} + + + +// --------------------------------------- +int ngadmin_defaults (struct ngadmin *nga) { + + List *attr; + int ret=ERR_OK; + + + attr=createEmptyList(); + pushBackList(attr, newByteAttr(ATTR_DEFAULTS, 1)); + if ( (ret=writeRequest(nga, attr))!=ERR_OK ) { 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; @@ -1013,42 +845,46 @@ int ngadmin_setQOSValues (struct ngadmin *nga, const char *ports) { -// -------------------------------------- -int ngadmin_restart (struct ngadmin *nga) { +// ----------------------------------------------------- +int ngadmin_getMirror (struct ngadmin *nga, char *ports) { List *attr; + ListNode *ln; + struct attr *at; + struct swi_attr *sa; int ret=ERR_OK, i; - char err; - unsigned short attr_error; + unsigned char *p; - if ( nga==NULL ) { + if ( nga==NULL || ports==NULL ) { return ERR_INVARG; - } else if ( nga->current==NULL ) { + } else if ( (sa=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; + pushBackList(attr, newEmptyAttr(ATTR_MIRROR)); + if ( (ret=readRequest(nga, attr))<0 ) { goto end; } - destroyList(attr, (void(*)(void*))freeAttr); - - if ( err==7 && attr_error==ATTR_PASSWORD ) { - ret=ERR_BADPASS; - goto end; + 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 ) { + ports[0]=p[0]; + for (i=1; i<=sa->ports; ++i) { // FIXME: if ports>8 + ports[i]=(p[2]>>(sa->ports-i))&1; + } + break; + } } end: + destroyList(attr, (void(*)(void*))freeAttr); + return ret; @@ -1056,52 +892,229 @@ int ngadmin_restart (struct ngadmin *nga) { -// --------------------------------------- -int ngadmin_defaults (struct ngadmin *nga) { +// ----------------------------------------------------------- +int ngadmin_setMirror (struct ngadmin *nga, const char *ports) { List *attr; - int ret=ERR_OK, i; - char err; - unsigned short attr_error; + int i; + char *p; + struct swi_attr *sa; if ( nga==NULL ) { return ERR_INVARG; - } else if ( nga->current==NULL ) { + } else if ( (sa=nga->current)==NULL ) { return ERR_NOTLOG; } + p=malloc(3); // FIXME: if ports>8 + memset(p, 0, 3); + + if ( ports!=NULL && ports[0]>0 && ports[0]<=sa->ports ) { + p[0]=ports[0]; + for (i=1; i<=sa->ports; ++i) { + if ( i!=p[0] ) { + p[2]|=(ports[i]&1)<<(sa->ports-i); + } + } + } + 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; + pushBackList(attr, newAttr(ATTR_MIRROR, 3, p)); + + + return writeRequest(nga, attr); + +} + + + +// ---------------------------------------------------------------- +int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic) { + + List *attr; + ListNode *ln; + struct attr *at; + struct swi_attr *sa; + int ret=ERR_OK; + unsigned char *p; + unsigned short *s; + + + if ( nga==NULL || ic==NULL ) { + return ERR_INVARG; + } else if ( (sa=nga->current)==NULL ) { + return ERR_NOTLOG; + } + + /* + ATTR_IGMP_ENABLE_VLAN + ATTR_IGMP_BLOCK_UNK + ATTR_IGMP_VALID_V3 + + Apparently, read-querying theses attributes at the same time causes the switch to reply garbage. + Here we are forced to do like the official win app and send a separate request for each attribute. + */ + + + attr=createEmptyList(); + memset(ic, 0, sizeof(struct igmp_conf)); + + + pushBackList(attr, newEmptyAttr(ATTR_IGMP_ENABLE_VLAN)); + if ( (ret=readRequest(nga, attr))<0 ) { goto end; } - destroyList(attr, (void(*)(void*))freeAttr); + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + s=at->data; + if ( at->attr==ATTR_IGMP_ENABLE_VLAN && at->size>=4 ) { + ic->enable= ntohs(s[0])!=0 ; + ic->vlan=htons(s[1]); + break; + } + } + + clearList(attr, (void(*)(void*))freeAttr); - if ( err==7 && attr_error==ATTR_PASSWORD ) { - ret=ERR_BADPASS; + + pushBackList(attr, newEmptyAttr(ATTR_IGMP_BLOCK_UNK)); + if ( (ret=readRequest(nga, attr))<0 ) { goto end; } + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + p=at->data; + if ( at->attr==ATTR_IGMP_BLOCK_UNK && at->size>=1 ) { + ic->block= p[0]!=0 ; + break; + } + } + + clearList(attr, (void(*)(void*))freeAttr); + + + pushBackList(attr, newEmptyAttr(ATTR_IGMP_VALID_V3)); + if ( (ret=readRequest(nga, attr))<0 ) { + goto end; + } + + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + p=at->data; + if ( at->attr==ATTR_IGMP_VALID_V3 && at->size>=1 ) { + ic->validate= p[0]!=0 ; + break; + } + } - // successful: delog and clean list - free(nga->swi_tab); - nga->swi_tab=NULL; - nga->swi_count=0; - nga->current=NULL; end: + destroyList(attr, (void(*)(void*))freeAttr); + return ret; } + +// ---------------------------------------------------------------------- +int ngadmin_setIGMPConf (struct ngadmin *nga, const struct igmp_conf *ic) { + + List *attr; + short *s; + struct swi_attr *sa; + + + if ( nga==NULL || ic==NULL ) { + return ERR_INVARG; + } else if ( (sa=nga->current)==NULL ) { + return ERR_NOTLOG; + } + + + s=malloc(2*sizeof(short)); + s[0]=htons(ic->enable!=false); + s[1]=htons(ic->vlan&0x0FFF); + + attr=createEmptyList(); + pushBackList(attr, newAttr(ATTR_IGMP_ENABLE_VLAN, 2*sizeof(short), s)); + pushBackList(attr, newByteAttr(ATTR_IGMP_BLOCK_UNK, ic->block!=false )); + pushBackList(attr, newByteAttr(ATTR_IGMP_VALID_V3, ic->validate!=false )); + + + return writeRequest(nga, attr); + +} + + + +// ---------------------------------------------------------------------- +int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb) { + + List *attr; + ListNode *ln; + struct attr *at; + int i, ret=ERR_OK; + struct swi_attr *sa; + char *p; + + + if ( nga==NULL || ct==NULL ) { + return ERR_INVARG; + } else if ( (sa=nga->current)==NULL ) { + return ERR_NOTLOG; + } + + + attr=createEmptyList(); + + for (i=0; i=1 && ct[i].port<=sa->ports ) { + + p=malloc(2); + p[0]=ct[i].port; + p[1]=1; + pushBackList(attr, newAttr(ATTR_CABLETEST_DO, 2, p)); + + ret=writeRequest(nga, attr); + attr=NULL; + if ( ret<0 ) goto end; + + // the list is destroyed by writeRequest, so we need to recreate it + attr=createEmptyList(); + pushBackList(attr, newByteAttr(ATTR_CABLETEST_RESULT, ct[i].port)); + + if ( (ret=readRequest(nga, attr))<0 ) goto end; + + for (ln=attr->first; ln!=NULL; ln=ln->next) { + at=ln->data; + p=at->data; + if ( at->attr==ATTR_CABLETEST_RESULT && at->size>=9 && p[0]==ct[i].port ) { + ct[i].v1=ntohl(*(int*)&p[1]); + ct[i].v2=ntohl(*(int*)&p[5]); + break; + } + } + + // just empty the list, it will be used at next iteration + clearList(attr, (void(*)(void*))freeAttr); + + } + } + + + end: + destroyList(attr, (void(*)(void*))freeAttr); + + return ret; + +} + + + diff --git a/lib/src/protocol.c b/lib/src/protocol.c index b5d930e..a71df2e 100644 --- a/lib/src/protocol.c +++ b/lib/src/protocol.c @@ -189,7 +189,7 @@ struct attr* newIntAttr (unsigned short attr, int value) { int *v=malloc(sizeof(int)); - *v=value; + *v=htonl(value); return newAttr(attr, sizeof(int), v); @@ -209,10 +209,9 @@ void freeAttr (struct attr *at) { -// ------------------------------------------------------------------------------------------ -List* extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error) { +// ----------------------------------------------------------------------------------------------------- +void extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error, List *attr) { - List *l; struct attr *at; @@ -224,8 +223,6 @@ List* extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error=ntohs(np->nh->attr); } - l=createEmptyList(); - while ( getPacketTotalSize(np)maxlen ) { at=malloc(sizeof(struct attr)); @@ -244,7 +241,7 @@ List* extractPacketAttributes (struct ng_packet *np, char *error, unsigned short memcpy(at->data, np->ah->data, at->size); } - pushBackList(l, at); + pushBackList(attr, at); if ( at->attr==ATTR_END ) { break; @@ -255,8 +252,6 @@ List* extractPacketAttributes (struct ng_packet *np, char *error, unsigned short } - return l; - } diff --git a/lib/src/protocol.h b/lib/src/protocol.h index ee832f8..4b4407b 100644 --- a/lib/src/protocol.h +++ b/lib/src/protocol.h @@ -24,8 +24,8 @@ struct ng_header { char unk2; // always 0 unsigned short attr; // attribute code which caused error char unk3[2]; // always 0 - char client_mac[6]; - char switch_mac[6]; + char client_mac[ETH_ALEN]; + char switch_mac[ETH_ALEN]; unsigned int seqnum; char proto_id[4]; // always "NSDP" char unk4[4]; // always 0 @@ -106,7 +106,7 @@ struct attr* newIntAttr (unsigned short attr, int value); void freeAttr (struct attr *at); // -List* extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error); +void extractPacketAttributes (struct ng_packet *np, char *error, unsigned short *attr_error, List *attr); // void extractSwitchAttributes (struct swi_attr *sa, const List *l); -- 2.39.5