From: darkcoven Date: Tue, 2 Apr 2013 21:24:48 +0000 (+0200) Subject: Raw: separate attribute filtering in a separate function. X-Git-Url: https://git.sur5r.net/?p=ngadmin;a=commitdiff_plain;h=83114dbb67bdf35b81f2404e061b681c3627b564 Raw: separate attribute filtering in a separate function. Raw: do not extract the errors from the header. --- diff --git a/dump/dump.c b/dump/dump.c index d57fc82..df374ee 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -57,10 +57,10 @@ int main (void) attr = createEmptyList(); - if (ntohs(remote.sin_port) != CLIENT_PORT || + if (ntohs(remote.sin_port) != CLIENT_PORT || len < (int)sizeof(struct ng_header) || !validateNgHeader(np.nh, 0, NULL, NULL, 0) || - extractPacketAttributes(&np, &error, &attr_error, attr, ATTR_END, 0) < 0) { + extractPacketAttributes(&np, attr, 0) < 0) { printf("wrong packet\n"); goto end; } diff --git a/lib/src/network.c b/lib/src/network.c index fce65c3..3b144ba 100644 --- a/lib/src/network.c +++ b/lib/src/network.c @@ -9,8 +9,9 @@ #include #include -#include "attr.h" -#include "protocol.h" +#include +#include + #include "network.h" @@ -176,7 +177,7 @@ int sendNgPacket (struct ngadmin *nga, char code, const List *attr) } -int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr, unsigned short filter_attr) +int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr) { char buffer[1500]; struct ng_packet np; @@ -212,9 +213,14 @@ int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned 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) || - extractPacketAttributes(&np, error, attr_error, attr, filter_attr, sa == NULL ? 0 : sa->ports) < 0) + extractPacketAttributes(&np, attr, sa == NULL ? 0 : sa->ports) < 0) continue; + if (error != NULL) + *error = np.nh->error; + if (attr_error != NULL) + *attr_error = ntohs(np.nh->attr); + len = 0; break; } @@ -237,7 +243,7 @@ static int checkErrorCode (unsigned char err, unsigned short attr_error) } -int readRequest (struct ngadmin *nga, List *attr, unsigned short filter_attr) +int readRequest (struct ngadmin *nga, List *attr) { int i, ret = ERR_OK; unsigned char err; @@ -258,7 +264,7 @@ int readRequest (struct ngadmin *nga, List *attr, unsigned short filter_attr) clearList(attr, (void(*)(void*))freeAttr); if (i >= 0) - i = recvNgPacket(nga, CODE_READ_REP, &err, &attr_error, attr, filter_attr); + i = recvNgPacket(nga, CODE_READ_REP, &err, &attr_error, attr); if (i == -EINVAL) { ret = ERR_INVARG; @@ -310,7 +316,7 @@ int writeRequest (struct ngadmin *nga, List *attr) clearList(attr, (void(*)(void*))freeAttr); if (i >= 0) - i = recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, attr, ATTR_END); + i = recvNgPacket(nga, CODE_WRITE_REP, &err, &attr_error, attr); if (i == -EINVAL) { ret = ERR_INVARG; diff --git a/lib/src/network.h b/lib/src/network.h index 7349278..c071f10 100644 --- a/lib/src/network.h +++ b/lib/src/network.h @@ -22,10 +22,10 @@ int updateTimeout (struct ngadmin *nga); int sendNgPacket (struct ngadmin *nga, char code, const List *attr); -int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr, unsigned short filter_attr); +int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr); -int readRequest (struct ngadmin *nga, List *attr, unsigned short filter_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 4ab3306..d599be0 100644 --- a/lib/src/ngadmin.c +++ b/lib/src/ngadmin.c @@ -3,11 +3,11 @@ #include +#include +#include + #include "lib.h" #include "network.h" -#include "attr.h" -#include "protocol.h" - static const struct timeval default_timeout = {.tv_sec = 4, .tv_usec = 0}; @@ -177,7 +177,7 @@ int ngadmin_scan (struct ngadmin *nga) /* try to receive any packets until timeout */ swiList = createEmptyList(); /* FIXME: end after timeout whatever received packet is good or not */ - while (recvNgPacket(nga, CODE_READ_REP, NULL, NULL, attr, ATTR_END) >= 0) { + while (recvNgPacket(nga, CODE_READ_REP, NULL, NULL, attr) >= 0) { sa = malloc(sizeof(struct swi_attr)); if (sa == NULL) return ERR_MEM; @@ -233,7 +233,7 @@ int ngadmin_login (struct ngadmin *nga, int id) attr = createEmptyList(); pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); - ret = readRequest(nga, attr, ATTR_END); + ret = readRequest(nga, attr); if (ret == ERR_OK ) { /* login succeeded */ /* TODO: if keep broadcasting is disabled, connect() the UDP @@ -286,10 +286,12 @@ int ngadmin_getPortsStatus (struct ngadmin *nga, unsigned char *ports) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_PORT_STATUS)); - ret = readRequest(nga, attr, ATTR_PORT_STATUS); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_PORT_STATUS, ATTR_END); + memset(ports, SPEED_UNK, nga->current->ports); for (ln = attr->first; ln != NULL; ln = ln->next) { @@ -351,10 +353,12 @@ int ngadmin_getPortsStatistics (struct ngadmin *nga, struct port_stats *ps) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_PORT_STATISTICS)); - ret = readRequest(nga, attr, ATTR_PORT_STATISTICS); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_PORT_STATISTICS, ATTR_END); + memset(ps, 0, nga->current->ports * sizeof(struct port_stats)); for (ln = attr->first; ln != NULL; ln = ln->next) { @@ -429,10 +433,12 @@ int ngadmin_getStormFilterState (struct ngadmin *nga, int *s) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_STORM_ENABLE)); - ret = readRequest(nga, attr, ATTR_STORM_ENABLE); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_STORM_ENABLE, ATTR_END); + *s = 0; if (attr->first != NULL) { @@ -479,10 +485,12 @@ int ngadmin_getStormFilterValues (struct ngadmin *nga, int *ports) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_STORM_BITRATE)); - ret = readRequest(nga, attr, ATTR_STORM_BITRATE); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_STORM_BITRATE, ATTR_END); + for (port = 0; port < nga->current->ports; port++) ports[port] = BITRATE_UNSPEC; @@ -549,7 +557,7 @@ int ngadmin_getBitrateLimits (struct ngadmin *nga, int *ports) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_BITRATE_INPUT)); pushBackList(attr, newEmptyAttr(ATTR_BITRATE_OUTPUT)); - ret = readRequest(nga, attr, ATTR_END); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; @@ -630,10 +638,12 @@ int ngadmin_getQOSMode (struct ngadmin *nga, int *s) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_QOS_TYPE)); - ret = readRequest(nga, attr, ATTR_QOS_TYPE); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_QOS_TYPE, ATTR_END); + *s = 0; if (attr->first != NULL) { @@ -680,10 +690,12 @@ int ngadmin_getQOSValues (struct ngadmin *nga, char *ports) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_QOS_CONFIG)); - ret = readRequest(nga, attr, ATTR_QOS_CONFIG); + ret = readRequest(nga, attr); if (ret < 0) goto end; + filterAttributes(attr, ATTR_QOS_CONFIG, ATTR_END); + for (port = 0; port < nga->current->ports; port++) ports[port] = PRIO_UNSPEC; @@ -785,10 +797,12 @@ int ngadmin_getMirror (struct ngadmin *nga, char *ports) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_MIRROR)); - ret = readRequest(nga, attr, ATTR_MIRROR); + ret = readRequest(nga, attr); if (ret < 0) goto end; + filterAttributes(attr, ATTR_MIRROR, ATTR_END); + memset(ports, 0, 1 + nga->current->ports); if (attr->first != NULL) { @@ -862,10 +876,12 @@ int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic) pushBackList(attr, newEmptyAttr(ATTR_IGMP_ENABLE_VLAN)); - ret = readRequest(nga, attr, ATTR_IGMP_ENABLE_VLAN); + ret = readRequest(nga, attr); if (ret < 0) goto end; + filterAttributes(attr, ATTR_IGMP_ENABLE_VLAN, ATTR_END); + if (attr->first != NULL) { at = attr->first->data; aiv = at->data; @@ -877,10 +893,12 @@ int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic) pushBackList(attr, newEmptyAttr(ATTR_IGMP_BLOCK_UNK)); - ret = readRequest(nga, attr, ATTR_IGMP_BLOCK_UNK); + ret = readRequest(nga, attr); if (ret < 0) goto end; + filterAttributes(attr, ATTR_IGMP_BLOCK_UNK, ATTR_END); + if (attr->first != NULL) { at = attr->first->data; ic->block = *(char*)at->data; @@ -890,10 +908,12 @@ int ngadmin_getIGMPConf (struct ngadmin *nga, struct igmp_conf *ic) pushBackList(attr, newEmptyAttr(ATTR_IGMP_VALID_V3)); - ret = readRequest(nga, attr, ATTR_IGMP_VALID_V3); + ret = readRequest(nga, attr); if (ret < 0) goto end; + filterAttributes(attr, ATTR_IGMP_VALID_V3, ATTR_END); + if (attr->first != NULL) { at = attr->first->data; ic->validate = *(char*)at->data; @@ -972,10 +992,12 @@ int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb) /* the list is destroyed by writeRequest, so we need to recreate it */ attr = createEmptyList(); pushBackList(attr, newByteAttr(ATTR_CABLETEST_RESULT, ct[i].port)); - ret = readRequest(nga, attr, ATTR_CABLETEST_RESULT); + ret = readRequest(nga, attr); if (ret < 0) goto end; + filterAttributes(attr, ATTR_CABLETEST_RESULT, ATTR_END); + for (ln = attr->first; ln != NULL; ln = ln->next) { at = ln->data; acr = at->data; @@ -1067,10 +1089,12 @@ int ngadmin_getVLANType (struct ngadmin *nga, int *t) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_VLAN_TYPE)); - ret=readRequest(nga, attr, ATTR_VLAN_TYPE); + ret=readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_VLAN_TYPE, ATTR_END); + *t = VLAN_DISABLED; if (attr->first != NULL) { @@ -1126,10 +1150,12 @@ int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsig attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF)); - ret = readRequest(nga, attr, ATTR_VLAN_DOT_CONF); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END); + memset(vlans, 0, total * sizeof(unsigned short)); memset(ports, 0, total * nga->current->ports); @@ -1174,10 +1200,12 @@ int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned c attr = createEmptyList(); pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan)); - ret = readRequest(nga, attr, ATTR_END); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END); + memset(ports, 0, nga->current->ports); for (ln = attr->first; ln != NULL; ln = ln->next) { @@ -1232,10 +1260,12 @@ int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsi if (memchr(ports, VLAN_UNSPEC, sa->ports) != NULL) { pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan)); - ret = readRequest(nga, attr, ATTR_VLAN_DOT_CONF); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END); + if (attr->first != NULL) { at = attr->first->data; memcpy(avd, at->data, sizeof(struct attr_vlan_dot) + sa->ports); @@ -1301,10 +1331,12 @@ int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports) attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_VLAN_PVID)); - ret = readRequest(nga, attr, ATTR_VLAN_PVID); + ret = readRequest(nga, attr); if (ret != ERR_OK) goto end; + filterAttributes(attr, ATTR_VLAN_PVID, ATTR_END); + memset(ports, 0, nga->current->ports * sizeof(unsigned short)); for (ln = attr->first; ln != NULL; ln = ln->next) { diff --git a/raw/include/list.h b/raw/include/list.h index 3eaf2ba..9dc9d34 100644 --- a/raw/include/list.h +++ b/raw/include/list.h @@ -55,6 +55,9 @@ void* popBackList (List *l); // Clears all the items of the list, and eventually frees them void clearList (List *l, void (*freefunc)(void*)); +// +bool destroyElement (List *l, ListNode *ln, void (*freefunc)(void*)); + // Find and destroy a particular element of the list, and eventually frees it bool findAndDestroy (List *l, void* data, void (*freefunc)(void*)); diff --git a/raw/include/protocol.h b/raw/include/protocol.h index 3064fd4..d2064f6 100644 --- a/raw/include/protocol.h +++ b/raw/include/protocol.h @@ -150,7 +150,10 @@ void freeAttr (struct attr *at); int addPacketAttributes (struct ng_packet *np, const List* attr, unsigned char ports); -int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr, unsigned short filter_attr, unsigned char ports); +int extractPacketAttributes (struct ng_packet *np, List *attr, unsigned char ports); + + +void filterAttributes (List *attr, ...); #endif diff --git a/raw/src/list.c b/raw/src/list.c index 88a222b..52b6d45 100644 --- a/raw/src/list.c +++ b/raw/src/list.c @@ -276,6 +276,59 @@ void clearList (List *l, void (*freefunc)(void*)) { +static void __destroyElement (List *l, ListNode *ln, void (*freefunc)(void*)) { + + + if ( ln->prev==NULL ) { + l->first=ln->next; + } else { + ln->prev->next=ln->next; + } + + if ( ln->next==NULL ) { + l->last=ln->prev; + } else { + ln->next->prev=ln->prev; + } + + + if ( freefunc!=NULL ) { + freefunc(ln->data); + } + + l->count--; + free(ln); + +} + + + +// ----------------------------------------------------------------- +bool destroyElement (List *l, ListNode *ln, void (*freefunc)(void*)) { + + + if ( l==NULL || ln==NULL ) { + return false; + } + + + #ifdef MT_SAFE_LIST + pthread_mutex_lock(&l->mutex); + #endif + + __destroyElement(l, ln, freefunc); + + #ifdef MT_SAFE_LIST + pthread_mutex_unlock(&l->mutex); + #endif + + + return true; + +} + + + // --------------------------------------------------------------- bool findAndDestroy (List *l, void* data, void (*freefunc)(void*)) { @@ -302,24 +355,7 @@ bool findAndDestroy (List *l, void* data, void (*freefunc)(void*)) { } else { - if ( ln->prev==NULL ) { - l->first=ln->next; - } else { - ln->prev->next=ln->next; - } - - if ( ln->next==NULL ) { - l->last=ln->prev; - } else { - ln->next->prev=ln->prev; - } - - - if ( freefunc!=NULL ) { - freefunc(data); - } - - l->count--; + __destroyElement(l, ln, freefunc); #ifdef MT_SAFE_LIST pthread_mutex_unlock(&l->mutex); diff --git a/raw/src/protocol.c b/raw/src/protocol.c index de2c451..c41a649 100644 --- a/raw/src/protocol.c +++ b/raw/src/protocol.c @@ -149,7 +149,7 @@ int addPacketAttributes (struct ng_packet *np, const List* attr, unsigned char p } -int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr, unsigned short filter_attr, unsigned char ports) +int extractPacketAttributes (struct ng_packet *np, List *attr, unsigned char ports) { struct attr *at; const struct attr_handler *ah; @@ -158,11 +158,6 @@ int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigne bool valid; - if (error != NULL) - *error = np->nh->error; - if (attr_error != NULL) - *attr_error = ntohs(np->nh->attr); - while (getPacketTotalSize(np) < np->maxlen) { /* no room for an attribute header: error */ @@ -197,11 +192,6 @@ int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigne /* decode attribute data */ valid = true; - if (filter_attr != ATTR_END && at->attr != filter_attr) { - valid = false; - goto next; - } - ah = getAttrHandler(at->attr); if (at->data == NULL || ah == NULL) goto next; @@ -235,3 +225,37 @@ next: } +void filterAttributes (List *attr, ...) +{ + va_list ap; + ListNode *ln, *pr; + struct attr *at; + unsigned short attrcode; + bool keep; + + + ln = attr->first; + while (ln != NULL) { + at = ln->data; + + va_start(ap, attr); + keep = false; + attrcode = 0; + while (!keep && attrcode != ATTR_END) { + attrcode = (unsigned short)va_arg(ap, unsigned int); + keep = keep || (at->attr == attrcode); + } + va_end(ap); + + if (keep) { + ln = ln->next; + } else { + pr = ln; + ln = ln->next; + destroyElement(attr, pr, (void(*)(void*))freeAttr); + } + } + +} + +