]> git.sur5r.net Git - ngadmin/commitdiff
Separated lib in two parts : low level and high level.
authordarkcoven <admin@darkcoven.tk>
Mon, 1 Apr 2013 17:48:42 +0000 (19:48 +0200)
committerdarkcoven <admin@darkcoven.tk>
Mon, 1 Apr 2013 17:48:42 +0000 (19:48 +0200)
17 files changed:
.gitignore
Makefile
lib/src/Makefile
lib/src/attr.c [deleted file]
lib/src/attr.h [deleted file]
lib/src/list.c [deleted file]
lib/src/list.h [deleted file]
lib/src/protocol.c [deleted file]
lib/src/protocol.h [deleted file]
raw/Makefile [new file with mode: 0644]
raw/include/attr.h [new file with mode: 0644]
raw/include/list.h [new file with mode: 0644]
raw/include/protocol.h [new file with mode: 0644]
raw/src/Makefile [new file with mode: 0644]
raw/src/attr.c [new file with mode: 0644]
raw/src/list.c [new file with mode: 0644]
raw/src/protocol.c [new file with mode: 0644]

index 777604b54522153298fe57511c6f738810e2530b..561952841617d47f6a5f3e44b8fe05a7492da4fc 100644 (file)
@@ -1,7 +1,9 @@
 *.o
 *~
 *.so
+*.a
 admin
 admind
 lib/doc/
+raw/doc/
 brouillon
index 73ffad0922d2870ddfc5ba9848ba4083e442ad91..8af2203a994c3713a14b4a1078c5c61111b01fd7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,14 @@
 
 
-all: lib libdoc cli
+all: raw lib libdoc cli
        
 
 
-lib: force
+raw: force
+       @+$(MAKE) -C raw lib
+
+
+lib: raw force
        @+$(MAKE) -C lib lib
 
 
@@ -12,7 +16,7 @@ libdoc: force
        @+$(MAKE) -C lib libdoc
 
 
-cli: force
+cli: lib force
        @+$(MAKE) -C cli
 
 
@@ -22,10 +26,12 @@ force:
 
 
 clean:
+       @+$(MAKE) -C raw clean
        @+$(MAKE) -C lib clean
        @+$(MAKE) -C cli clean
 
 mrproper: clean
+       @+$(MAKE) -C raw mrproper
        @+$(MAKE) -C lib mrproper
        @+$(MAKE) -C cli mrproper
 
index 786f8272c0d23faa5284a978eefaa6bbc371050f..b88451f2e1bbfd98ec75f3f0321b08ca17ecf9a6 100644 (file)
@@ -1,7 +1,7 @@
 
 CC=gcc
-CFLAGS=-DBUILD_LIB -I../include/ -W -Wall -Wextra -Os -fno-strict-aliasing -fvisibility=hidden -fPIC
-LDFLAGS=
+CFLAGS=-DBUILD_LIB -I../../raw/include/ -I../include/ -W -Wall -Wextra -Os -fno-strict-aliasing -fvisibility=hidden -fPIC
+LDFLAGS=-L../../raw/ -lrawnsdp
 EXEC=../libngadmin.so
 
 SRC=$(wildcard *.c)
diff --git a/lib/src/attr.c b/lib/src/attr.c
deleted file mode 100644 (file)
index 3e12690..0000000
+++ /dev/null
@@ -1,465 +0,0 @@
-
-#include <ngadmin.h>
-
-#include "lib.h"
-#include "attr.h"
-#include "protocol.h"
-
-
-#define ATTR_HANDLER_ENTRY(at, sz, enc, dec)   {.attr = at, .size = sz, .encode = enc, .decode = dec}
-
-
-
-static bool bool_endecode (struct attr *at, unsigned char ports UNUSED)
-{
-       *(char*)at->data = (*(char*)at->data != 0);
-       
-       return true;
-}
-
-
-static bool ports_status_decode (struct attr *at, unsigned char ports)
-{
-       struct attr_port_status *ps = at->data;
-       
-       if (ps->port < 1 || ps->port > ports)
-               return false;
-       
-       switch (ps->status) {
-       case SPEED_DOWN:
-       case SPEED_10:
-       case SPEED_100:
-       case SPEED_1000:
-               break;
-       default:
-               return false;
-       }
-       
-       return true;
-}
-
-
-static bool port_stat_decode (struct attr *at, unsigned char ports)
-{
-       struct attr_port_stat *ps = at->data;
-       unsigned long long *v;
-       
-       if (ps->port < 1 || ps->port > ports)
-               return false;
-       
-       for (v = &ps->recv; ((char*)v) - ((char*)ps) < (int)sizeof(struct attr_port_stat); v++)
-               *v = be64toh(*v);
-       
-       
-       return true;
-}
-
-
-static bool bitrate_decode (struct attr *at, unsigned char ports)
-{
-       struct attr_bitrate *sb = at->data;
-       
-       if (sb->port < 1 || sb->port > ports)
-               return false;
-       
-       sb->bitrate = ntohl(sb->bitrate);
-       if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
-               return false;
-       
-       return true;
-}
-
-
-static bool bitrate_encode (struct attr *at, unsigned char ports)
-{
-       struct attr_bitrate *sb = at->data;
-       
-       if (sb->port < 1 || sb->port > ports)
-               return false;
-       
-       if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
-               return false;
-       sb->bitrate = htonl(sb->bitrate);
-       
-       return true;
-}
-
-
-static bool qos_mode_endecode (struct attr *at, unsigned char ports UNUSED)
-{
-       unsigned char v = *(char*)at->data;
-       
-       return (v == QOS_PORT || v == QOS_DOT);
-}
-
-
-static bool qos_endecode (struct attr *at, unsigned char ports)
-{
-       struct attr_qos *aq = at->data;
-       
-       if (aq->port < 1 || aq->port > ports)
-               return false;
-       
-       return (aq->prio >= PRIO_HIGH && aq->prio <= PRIO_LOW);
-}
-
-
-static bool pvid_decode (struct attr *at, unsigned char ports)
-{
-       struct attr_pvid *ap= at->data;
-       
-       if (ap->port < 1 || ap->port > ports)
-               return false;
-       
-       ap->vlan = ntohs(ap->vlan);
-       
-       return (ap->vlan >= VLAN_MIN && ap->vlan <= VLAN_MAX);
-}
-
-
-static bool pvid_encode (struct attr *at, unsigned char ports)
-{
-       struct attr_pvid *ap= at->data;
-       
-       if (ap->port < 1 || ap->port > ports)
-               return false;
-       
-       if (ap->vlan < VLAN_MIN || ap->vlan > VLAN_MAX)
-               return false;
-       
-       ap->vlan = htons(ap->vlan);
-       
-       return true;
-}
-
-
-static bool vlan_destroy_encode (struct attr *at, unsigned char ports UNUSED)
-{
-       unsigned short v = *(unsigned short*)at->data;
-       
-       if (v < VLAN_MIN || v > VLAN_MAX)
-               return false;
-       
-       *(unsigned short*)at->data = htons(v);
-       
-       return true;
-}
-
-
-static bool mirror_decode (struct attr *at, unsigned char ports)
-{
-       unsigned char *r = at->data, *p;
-       int port;
-       
-       
-       if (at->size != 3 + ((ports - 1) >> 3))
-               return false;
-       
-       /* r[0] == 0 is allowed and means mirroring is disabled */
-       if (r[0] > ports)
-               return false;
-       
-       p = malloc(1 + ports);
-       if (p == NULL)
-               return false;
-       
-       memset(p, 0, 1 + ports);
-       
-       if (r[0] == 0)
-               goto end;
-       
-       p[0] = r[0];
-       
-       for (port = 1; port <= ports; port++)
-               p[port] = (r[2] >> (8 - port)) & 1; /* FIXME: if ports > 8 */
-       
-end:
-       free(at->data);
-       at->data = p;
-       at->size = 1 + ports;
-       
-       
-       return true;
-}
-
-
-static bool mirror_encode (struct attr *at, unsigned char ports)
-{
-       unsigned char *p = at->data, *r;
-       int port;
-       
-       
-       if (at->size != 1 + ports)
-               return false;
-       
-       /* p[0] == 0 is allowed and means mirroring is disabled */
-       if (p[0] > ports)
-               return false;
-       
-       r = malloc(3 + ((ports - 1) >> 3));
-       if (r == NULL)
-               return false;
-       
-       memset(r, 0, 3 + ((ports - 1) >> 3));
-       
-       if (p[0] == 0)
-               goto end;
-       
-       r[0] = p[0];
-       
-       for (port = 1; port <= ports; port++) {
-               if (p[0] != port)
-                       r[2] |= (p[port] & 1) << (8 - port); /* FIXME: if ports > 8 */
-       }
-       
-end:
-       free(at->data);
-       at->data = r;
-       at->size = 3 + ((ports - 1) >> 3);
-       
-       
-       return true;
-}
-
-
-static bool igmp_vlan_decode (struct attr *at, unsigned char ports UNUSED)
-{
-       struct attr_igmp_vlan *aiv = at->data;
-       
-       aiv->enable = ntohs(aiv->enable);
-       if (aiv->enable != 0 && aiv->enable != 1)
-               return false;
-       
-       aiv->vlan = ntohs(aiv->vlan);
-       if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_MAX)
-               return false;
-       
-       return true;
-}
-
-
-static bool igmp_vlan_encode (struct attr *at, unsigned char ports UNUSED)
-{
-       struct attr_igmp_vlan *aiv = at->data;
-       
-       if (aiv->enable != 0 && aiv->enable != 1)
-               return false;
-       aiv->enable = htons(aiv->enable);
-       
-       if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_MAX)
-               return false;
-       aiv->vlan = htons(aiv->vlan);
-       
-       return true;
-}
-
-
-static bool cabletest_do_encode (struct attr *at, unsigned char ports)
-{
-       struct attr_cabletest_do *acd = at->data;
-       
-       if (acd->port < 1 || acd->port > ports)
-               return false;
-       
-       return (acd->action == 1);
-}
-
-
-static bool cabletest_result_encode (struct attr *at, unsigned char ports)
-{
-       unsigned char v = *(unsigned char*)at->data;
-       
-       return (v >= 1 && v <= ports);
-}
-
-
-static bool cabletest_result_decode (struct attr *at, unsigned char ports)
-{
-       struct attr_cabletest_result *acr = at->data;
-       
-       if (acr->port < 1 || acr->port > ports)
-               return false;
-       
-       acr->v1 = ntohl(acr->v1);
-       acr->v2 = ntohl(acr->v2);
-       
-       return true;
-}
-
-
-static bool cabletest_result_endecode (struct attr *at, unsigned char ports)
-{
-       switch (at->size) {
-       
-       case 1:
-               return cabletest_result_encode(at, ports);
-       
-       case sizeof(struct attr_cabletest_result):
-               return cabletest_result_decode(at, ports);
-       
-       default:
-               return false;
-       }
-}
-
-
-static bool vlan_type_endecode (struct attr *at, unsigned char ports UNUSED)
-{
-       char v = *(char*)at->data;
-       
-       return (v >= VLAN_DISABLED && v <= VLAN_DOT_ADV);
-}
-
-
-static bool vlan_dot_decode (struct attr *at, unsigned char ports)
-{
-       char *r = at->data;
-       struct attr_vlan_dot *avd;
-       int port;
-       
-       
-       if (at->size != (2 + 2 * (1 + ((ports - 1) >> 3))))
-               return false;
-       
-       avd = malloc(sizeof(struct attr_vlan_dot) + ports);
-       if (avd == NULL)
-               return false;
-       
-       avd->vlan = ntohs(*(unsigned short*)r);
-       r += 2;
-       
-       for (port = 0; port < ports; port++) {
-               /* FIXME: if ports > 8 */
-               if ((r[1] >> (7 - port)) & 1)
-                       avd->ports[port] = VLAN_TAGGED;
-               else if ((r[0] >> (7 - port)) & 1)
-                       avd->ports[port] = VLAN_UNTAGGED;
-               else
-                       avd->ports[port] = VLAN_NO;
-       }
-       
-       free(at->data);
-       at->data = avd;
-       at->size = sizeof(struct attr_vlan_dot) + ports;
-       
-       
-       return true;
-}
-
-
-static bool vlan_dot_encode (struct attr *at, unsigned char ports)
-{
-       struct attr_vlan_dot *avd = at->data;
-       char *r, fl;
-       unsigned int size, port;
-       
-       
-       if (avd->vlan < VLAN_MIN || avd->vlan > VLAN_MAX)
-               return false;
-       
-       /* just a header is valid */
-       if (at->size == sizeof(struct attr_vlan_dot))
-               size = 2;
-       else if (at->size == sizeof(struct attr_vlan_dot) + ports)
-               size = (2 + 2 * (1 + ((ports - 1) >> 3)));
-       else
-               return false;
-       
-       r = malloc(size);
-       if (r == NULL)
-               return false;
-       
-       memset(r, 0, size);
-       *(unsigned short*)r = htons(avd->vlan);
-       
-       if (size == 2)
-               goto end;
-       
-       r += 2;
-       
-       for (port = 0; port < ports; port++) {
-               /* FIXME: if ports > 8 */
-               fl = (1 << (7 - port));
-               switch (avd->ports[port]) {
-               case VLAN_TAGGED:
-                       r[1] |= fl;
-               case VLAN_UNTAGGED:
-                       r[0] |= fl;
-               }
-       }
-       
-       r -= 2;
-       
-end:
-       free(at->data);
-       at->data = r;
-       at->size = size;
-       
-       
-       return true;
-}
-
-
-
-/* WARNING: attributes codes MUST be in ascending order */
-static const struct attr_handler attrtab[] = {
-       ATTR_HANDLER_ENTRY(ATTR_MAC, 6, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_IP, 4, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_NETMASK, 4, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_GATEWAY, 4, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_DHCP, 2, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_RESTART, 1, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_DEFAULTS, 1, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_PORT_STATUS, sizeof(struct attr_port_status), NULL, ports_status_decode),
-       ATTR_HANDLER_ENTRY(ATTR_PORT_STATISTICS, sizeof(struct attr_port_stat), NULL, port_stat_decode),
-       ATTR_HANDLER_ENTRY(ATTR_STATS_RESET, 1, bool_endecode, bool_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_CABLETEST_DO, sizeof(struct attr_cabletest_do), cabletest_do_encode, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_CABLETEST_RESULT, 0, cabletest_result_endecode, cabletest_result_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_VLAN_TYPE, 1, vlan_type_endecode, vlan_type_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_VLAN_DOT_CONF, 0, vlan_dot_encode, vlan_dot_decode),
-       ATTR_HANDLER_ENTRY(ATTR_VLAN_DESTROY, 2, vlan_destroy_encode, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_VLAN_PVID, sizeof(struct attr_pvid), pvid_encode, pvid_decode),
-       ATTR_HANDLER_ENTRY(ATTR_QOS_TYPE, 1, qos_mode_endecode, qos_mode_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_QOS_CONFIG, sizeof(struct attr_qos), qos_endecode, qos_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_BITRATE_INPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
-       ATTR_HANDLER_ENTRY(ATTR_BITRATE_OUTPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
-       ATTR_HANDLER_ENTRY(ATTR_STORM_ENABLE, 1, bool_endecode, bool_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_STORM_BITRATE, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
-       ATTR_HANDLER_ENTRY(ATTR_MIRROR, 0, mirror_encode, mirror_decode),
-       ATTR_HANDLER_ENTRY(ATTR_PORTS_COUNT, 1, NULL, NULL),
-       ATTR_HANDLER_ENTRY(ATTR_IGMP_ENABLE_VLAN, sizeof(struct attr_igmp_vlan), igmp_vlan_encode, igmp_vlan_decode),
-       ATTR_HANDLER_ENTRY(ATTR_IGMP_BLOCK_UNK, 1, bool_endecode, bool_endecode),
-       ATTR_HANDLER_ENTRY(ATTR_IGMP_VALID_V3, 1, bool_endecode, bool_endecode)
-};
-
-
-
-const struct attr_handler* getAttrHandler (unsigned short attrcode)
-{
-       const struct attr_handler *ah;
-       const unsigned int tab_size = sizeof(attrtab) / sizeof(struct attr_handler);
-       unsigned int inf, sup, index;
-       
-       
-       inf = 0;
-       sup = tab_size;
-       index = tab_size >> 1;
-       while (index < sup) {
-               ah = &attrtab[index];
-               
-               if (ah->attr > attrcode) {
-                       sup = index;
-                       index -= ((index - inf) >> 1) + ((index - inf) & 1);
-               } else if (ah->attr < attrcode) {
-                       inf = index;
-                       index += ((sup - index) >> 1) + ((sup - index) & 1);
-               } else {
-                       return ah;
-               }
-       }
-       
-       
-       return NULL;
-}
-
-
diff --git a/lib/src/attr.h b/lib/src/attr.h
deleted file mode 100644 (file)
index e297b49..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-
-#ifndef DEF_ATTR
-#define DEF_ATTR
-
-
-#include <stdbool.h>
-
-#include "protocol.h"
-
-
-#define ATTR_PRODUCT           0x0001
-#define ATTR_UNK_0002          0x0002
-#define ATTR_NAME              0x0003
-#define ATTR_MAC               0x0004
-#define ATTR_UNK_0005          0x0005
-#define ATTR_IP                        0x0006
-#define ATTR_NETMASK           0x0007
-#define ATTR_GATEWAY           0x0008
-#define ATTR_NEW_PASSWORD      0x0009
-#define ATTR_PASSWORD          0x000A
-#define ATTR_DHCP              0x000B
-#define ATTR_UNK_000C          0x000C
-#define ATTR_FIRM_VER          0x000D
-#define ATTR_UNK_000E          0x000E
-#define ATTR_UNK_000F          0x000F
-#define ATTR_FIRM_UPGRADE      0x0010
-#define ATTR_RESTART           0x0013
-#define ATTR_DEFAULTS          0x0400
-#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
-#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
-#define ATTR_BITRATE_OUTPUT    0x5000
-#define ATTR_STORM_ENABLE      0x5400
-#define ATTR_STORM_BITRATE     0x5800
-#define ATTR_MIRROR            0x5C00
-#define ATTR_PORTS_COUNT       0x6000
-#define ATTR_MAX_VLAN          0x6400
-#define ATTR_IGMP_ENABLE_VLAN  0x6800
-#define ATTR_IGMP_BLOCK_UNK    0x6C00
-#define ATTR_IGMP_VALID_V3     0x7000
-#define ATTR_TLV_BITMAP                0x7400
-#define ATTR_END               0xFFFF
-
-#define UNUSED                 __attribute__((unused))
-
-
-struct attr_handler {
-       unsigned short attr;                                    /* attribute code */
-       unsigned int size;                                      /* expected data size */
-       bool (*encode)(struct attr *at, unsigned char ports);   /* encode function */
-       bool (*decode)(struct attr *at, unsigned char ports);   /* decode function */
-};
-
-
-const struct attr_handler* getAttrHandler (unsigned short attrcode);
-
-
-
-
-struct attr_port_status {
-       unsigned char port;
-       unsigned char status;
-       unsigned char unk;
-} __attribute__((packed));
-
-
-struct attr_port_stat {
-       unsigned char port;
-       unsigned long long recv;
-       unsigned long long sent;
-       unsigned long long unk1;
-       unsigned long long unk2;
-       unsigned long long unk3;
-       unsigned long long crc;
-} __attribute__((packed));
-
-
-struct attr_bitrate {
-       unsigned char port;
-       int bitrate;
-} __attribute__((packed));
-
-
-struct attr_qos {
-       unsigned char port;
-       unsigned char prio;
-} __attribute__((packed));
-
-
-struct attr_pvid {
-       unsigned char port;
-       unsigned short vlan;
-} __attribute__((packed));
-
-
-struct attr_igmp_vlan {
-       unsigned short enable;
-       unsigned short vlan;
-} __attribute__((packed));
-
-
-struct attr_cabletest_do {
-       unsigned char port;
-       unsigned char action;
-} __attribute__((packed));
-
-
-struct attr_cabletest_result {
-       unsigned char port;
-       unsigned int v1;
-       unsigned int v2;
-} __attribute__((packed));
-
-
-struct attr_vlan_dot {
-       unsigned short vlan;
-       unsigned char ports[0];
-};
-
-
-#endif
-
diff --git a/lib/src/list.c b/lib/src/list.c
deleted file mode 100644 (file)
index 88a222b..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-
-#include "list.h"
-
-
-
-
-// -------------------------
-List* createEmptyList (void) {
- List *l;
- l=malloc(sizeof(List));
- l->first=NULL;
- l->last=NULL;
- l->count=0;
- #ifdef MT_SAFE_LIST
- pthread_cond_init(&l->cond, NULL);
- pthread_mutex_init(&l->mutex, NULL);
- #endif
- return l;
-}
-
-
-
-// ------------------------------------------------
-void destroyList (List *l, void (*freefunc)(void*)) {
- ListNode *pr, *ln;
- if ( l==NULL ) {
-  return;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_destroy(&l->mutex);
- pthread_cond_destroy(&l->cond);
- #endif
- for (ln=l->first; ln!=NULL; ) {
-  
-  pr=ln;
-  
-  if ( freefunc!=NULL ) {
-   freefunc(pr->data);
-  }
-  
-  ln=pr->next;
-  free(pr);
-  
- }
- free(l);
-}
-
-
-
-// -------------------------------------
-void pushFrontList (List *l, void* data) {
- ListNode *ln;
- if ( l==NULL ) {
-  return;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- ln=malloc(sizeof(ListNode));
- ln->data=data;
- ln->prev=NULL;
- ln->next=l->first;
- if ( l->first==NULL ) {
-  l->last=ln;
- } else {
-  l->first->prev=ln;
- }
- l->first=ln;
- l->count++;
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- pthread_cond_broadcast(&l->cond);
- #endif
-}
-
-
-
-// ------------------------------------
-void pushBackList (List *l, void* data) {
- ListNode *ln;
- if ( l==NULL ) {
-  return;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- ln=malloc(sizeof(ListNode));
- ln->data=data;
- ln->prev=l->last;
- ln->next=NULL;
- if ( l->last==NULL ) {
-  l->first=ln;
- } else {
-  l->last->next=ln;
- }
- l->last=ln;
- l->count++;
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- pthread_cond_broadcast(&l->cond);
- #endif
-}
-
-
-
-// -------------------------
-void* popFrontList (List *l) {
- ListNode *ln;
- void* data;
- if ( l==NULL ) {
-  return NULL;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- if ( (ln=l->first)==NULL ) {
-  #ifdef MT_SAFE_LIST
-  pthread_mutex_unlock(&l->mutex);
-  #endif
-  return NULL;
- }
- data=ln->data;
- l->first=ln->next;
- if ( ln->next==NULL ) {
-  l->last=NULL;
- } else {
-  ln->next->prev=NULL;
- }
- l->count--;
- free(ln);
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- pthread_cond_broadcast(&l->cond);
- #endif
- return data;
-}
-
-
-
-// ------------------------
-void* popBackList (List *l) {
- ListNode *ln;
- void* data;
- if ( l==NULL ) {
-  return NULL;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- if ( (ln=l->last)==NULL ) {
-  #ifdef MT_SAFE_LIST
-  pthread_mutex_unlock(&l->mutex);
-  #endif
-  return NULL;
- }
- data=ln->data;
- l->last=ln->prev;
- if ( ln->prev==NULL ) {
-  l->first=NULL;
- } else {
-  ln->prev->next=NULL;
- }
- l->count--;
- free(ln);
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- pthread_cond_broadcast(&l->cond);
- #endif
- return data;
-}
-
-
-
-// ----------------------------------------------
-void clearList (List *l, void (*freefunc)(void*)) {
- ListNode *ln, *pr;
- if ( l==NULL ) {
-  return;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- for (ln=l->first; ln!=NULL; ) {
-  
-  pr=ln;
-  
-  if ( freefunc!=NULL ) {
-   freefunc(pr->data);
-  }
-  
-  ln=pr->next;
-  free(pr);
-  
- }
- l->first=NULL;
- l->last=NULL;
- l->count=0;
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- pthread_cond_broadcast(&l->cond);
- #endif
-}
-
-
-
-// ---------------------------------------------------------------
-bool findAndDestroy (List *l, void* data, void (*freefunc)(void*)) {
- ListNode *ln;
- if ( l==NULL ) {
-  return false;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- for (ln=l->first; ln!=NULL && ln->data!=data; ln=ln->next);
- if ( ln==NULL ) {
-  
-  #ifdef MT_SAFE_LIST
-  pthread_mutex_unlock(&l->mutex);
-  #endif
-  
- } 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--;
-  
-  #ifdef MT_SAFE_LIST
-  pthread_mutex_unlock(&l->mutex);
-  pthread_cond_broadcast(&l->cond);
-  #endif
-  
- }
- return true;
-}
-
-
-
-// -------------------------------------------------
-void browseList (List *l, void (*browsefunc)(void*)) {
- ListNode *ln;
- if ( l==NULL || browsefunc==NULL ) {
-  return;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- for (ln=l->first; ln!=NULL; ln=ln->next) {
-  browsefunc(ln->data);
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- #endif
-}
-
-
-// --------------------------------------
-void* convertToArray (List *l, size_t sz) {
- ListNode *ln;
- void *tab=NULL, *p;
- if ( l==NULL || sz==0 ) {
-  return NULL;
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_lock(&l->mutex);
- #endif
- if ( l->count>0 ) {
-  
-  tab=malloc(l->count*sz);
-  p=tab;
-  
-  for (ln=l->first; ln!=NULL; ln=ln->next) {
-   memcpy(p, ln->data, sz);
-   p+=sz;
-  }
-  
- }
- #ifdef MT_SAFE_LIST
- pthread_mutex_unlock(&l->mutex);
- #endif
- return tab;
-}
-
-
-
-
diff --git a/lib/src/list.h b/lib/src/list.h
deleted file mode 100644 (file)
index 3eaf2ba..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-
-#ifndef DEF_LIST
-#define DEF_LIST
-
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-
-#ifdef MT_SAFE_LIST
-#include <pthread.h>
-#endif
-
-
-
-typedef struct ListNode ListNode;
-
-struct ListNode {
- void* data;
- ListNode *prev, *next;
-};
-
-
-typedef struct {
- ListNode *first, *last;
- unsigned int count;
- #ifdef MT_SAFE_LIST
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- #endif
-} List;
-
-
-
-
-// Creates an empty list
-List* createEmptyList (void);
-
-// Destroys a list, and eventually frees the elements
-// NOT MT SAFE
-void destroyList (List *l, void (*freefunc)(void*));
-
-// Adds an element at front of the list
-void pushFrontList (List *l, void* data);
-
-// Adds an element at back of the list
-void pushBackList (List *l, void* data);
-
-// Pops an element from the front of the list and returns its value
-void* popFrontList (List *l);
-
-// Pops an element from the back of the list and returns its value
-void* popBackList (List *l);
-
-// Clears all the items of the list, and eventually frees them
-void clearList (List *l, 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*));
-
-// Browse all the items of the list through the callback function
-void browseList (List *l, void (*browsefunc)(void*));
-
-// 
-void* convertToArray (List *l, size_t sz);
-
-
-
-
-#endif
-
diff --git a/lib/src/protocol.c b/lib/src/protocol.c
deleted file mode 100644 (file)
index de2c451..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-
-#include "attr.h"
-#include "protocol.h"
-
-
-
-int trim (char *txt, int start)
-{
-       char *p;
-       
-       if (txt == NULL)
-               return 0;
-       
-       p = txt + start;
-       while (p >= txt && (*p == ' ' || *p == '\n')) {
-               *p = '\0';
-               p--;
-       }
-       
-       return p - txt + 1;
-}
-
-
-void initNgHeader (struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum)
-{
-       memset(nh, 0, sizeof(struct ng_header));
-       nh->version = 1;
-       nh->code = code;
-       
-       memcpy(nh->client_mac, client_mac, ETH_ALEN);
-       
-       if (switch_mac != NULL)
-               memcpy(nh->switch_mac, switch_mac, ETH_ALEN);
-       
-       nh->seqnum = htonl(seqnum);
-       memcpy(nh->proto_id, "NSDP", 4);
-}
-
-
-bool validateNgHeader (const struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum)
-{
-       if (nh->version != 1)
-               return false;
-       
-       if (code > 0 && nh->code != code)
-               return false;
-       
-       if (nh->unk1 != 0)
-               return false;
-       
-       if (*(unsigned short*)nh->unk2 != 0)
-               return false;
-       
-       if (client_mac != NULL && memcmp(nh->client_mac, client_mac, ETH_ALEN) != 0)
-               return false;
-       
-       if (switch_mac != NULL && memcmp(nh->switch_mac, switch_mac, ETH_ALEN) != 0)
-               return false;
-       
-       if (seqnum > 0 && ntohl(nh->seqnum) != seqnum)
-               return false;
-       
-       if (memcmp(nh->proto_id, "NSDP", 4) != 0)
-               return false;
-       
-       if (*(unsigned int*)nh->unk3 != 0)
-               return false;
-       
-       return true;
-}
-
-
-void addPacketAttr (struct ng_packet *np, struct attr *at)
-{
-       struct attr_header *ah = np->ah;
-       
-       
-       if ((int)(getPacketTotalSize(np) + sizeof(struct attr_header) + at->size) > np->maxlen)
-               return;
-       
-       ah->attr = htons(at->attr);
-       ah->size = htons(at->size);
-       
-       if (at->size > 0 && at->data != NULL)
-               memcpy(ah->data, at->data, at->size);
-       
-       np->ah = (struct attr_header*)(ah->data + at->size);
-}
-
-
-struct attr* newAttr (unsigned short attr, unsigned short size, void *data)
-{
-       struct attr *at;
-       
-       
-       at = malloc(sizeof(struct attr));
-       if (at == NULL)
-               return NULL;
-       
-       at->attr = attr;
-       at->size = size;
-       at->data = data;
-       
-       
-       return at;
-}
-
-
-void freeAttr (struct attr *at)
-{
-       if (at != NULL) {
-               free(at->data);
-               free(at);
-       }
-}
-
-
-int addPacketAttributes (struct ng_packet *np, const List* attr, unsigned char ports)
-{
-       ListNode *ln;
-       struct attr *at;
-       const struct attr_handler *ah;
-       
-       
-       if (attr == NULL)
-               return 0;
-       
-       for (ln = attr->first; ln != NULL; ln = ln->next) {
-               at = ln->data;
-               ah = getAttrHandler(at->attr);
-               if (ah != NULL) {
-                       if (ah->size > 0 && at->size > 0 && at->size != ah->size)
-                               return -EINVAL;
-                       if (at->size > 0 && ah->encode != NULL && !ah->encode(at, ports))
-                               return -EINVAL;
-               }
-               
-               addPacketAttr(np, at);
-       }
-       
-       
-       return 0;
-}
-
-
-int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr, unsigned short filter_attr, unsigned char ports)
-{
-       struct attr *at;
-       const struct attr_handler *ah;
-       int ret = 0;
-       unsigned short size;
-       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 */
-               if (getPacketTotalSize(np) + (int)sizeof(struct attr_header) > np->maxlen) {
-                       ret = -1;
-                       break;
-               }
-               
-               /* create new attribute */
-               size = ntohs(np->ah->size);
-               at = newAttr(ntohs(np->ah->attr), size, NULL);
-               if (at == NULL) {
-                       ret = -1;
-                       break;
-               }
-               
-               /* attribute data bigger than the remaining size: error */
-               if (getPacketTotalSize(np) + (int)sizeof(struct attr_header) + size > np->maxlen) {
-                       free(at);
-                       ret = -1;
-                       break;
-               }
-               
-               /* copy attribute raw data */
-               if (size == 0) {
-                       at->data = NULL;
-               } else {
-                       at->data = malloc(size * sizeof(char));
-                       memcpy(at->data, np->ah->data, size);
-               }
-               
-               /* 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;
-               
-               if (ah->size > 0 && size != ah->size) {
-                       valid = false;
-                       goto next;
-               }
-               
-               if (ah->decode != NULL)
-                       valid = ah->decode(at, ports);
-               
-next:
-               /* stop on an END attribute */
-               if (at->attr == ATTR_END) {
-                       free(at);
-                       break;
-               }
-               
-               /* move to next attribute */
-               np->ah = (struct attr_header*)(np->ah->data + size);
-               
-               if (valid)
-                       pushBackList(attr, at);
-               else
-                       free(at);
-       }
-       
-       
-       return ret;
-}
-
-
diff --git a/lib/src/protocol.h b/lib/src/protocol.h
deleted file mode 100644 (file)
index 3064fd4..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-
-#ifndef DEF_PROTOCOL
-#define DEF_PROTOCOL
-
-
-#include <stdlib.h>
-#include <arpa/inet.h>
-
-#include <netinet/ether.h>
-
-#include "list.h"
-
-
-#define CLIENT_PORT            63321
-#define SWITCH_PORT            63322
-
-#define CODE_READ_REQ          1
-#define CODE_READ_REP          2
-#define CODE_WRITE_REQ         3
-#define CODE_WRITE_REP         4
-
-#define ERROR_READONLY         3
-#define ERROR_INVALID_VALUE    5
-#define ERROR_DENIED           7
-
-
-struct ng_header {
-       char version;                   /* always 1, maybe version */
-       char code;                      /* request code: read request, read reply, write request, write reply */
-       unsigned char error;            /* error code, 0 when no error */
-       unsigned char unk1;             /* always 0, unknown */
-       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));
-
-
-struct attr_header {
-       unsigned short attr;
-       unsigned short size;
-       char data[0];
-} __attribute__((packed));
-
-
-struct ng_packet {
-       union {
-               char *buffer;
-               struct ng_header *nh;
-       };
-       int maxlen;
-       struct attr_header *ah;
-};
-
-
-struct attr {
-       unsigned short attr;
-       unsigned short size;
-       void *data;
-};
-
-
-
-int trim (char *txt, int start);
-
-
-static inline int min (int a, int b)
-{
-       return a < b ? a : b;
-}
-
-
-void initNgHeader (struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum);
-
-
-bool validateNgHeader (const struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum);
-
-
-static inline void initNgPacket (struct ng_packet *np)
-{
-       np->ah = (struct attr_header*)np->nh->data;
-}
-
-
-void addPacketAttr (struct ng_packet *np, struct attr *at);
-
-
-static inline int getPacketTotalSize (const struct ng_packet *np)
-{
-       return ((char*)np->ah) - np->buffer;
-}
-
-
-struct attr* newAttr (unsigned short attr, unsigned short size, void *data);
-
-
-static inline struct attr* newEmptyAttr (unsigned short attr)
-{
-       return newAttr(attr, 0, NULL);
-}
-
-
-static inline struct attr* newByteAttr (unsigned short attr, unsigned char value)
-{
-       char *v = malloc(sizeof(char));
-       
-       *v = value;
-       
-       return newAttr(attr, sizeof(char), v);
-}
-
-
-static inline struct attr* newShortAttr (unsigned short attr, short value)
-{
-       short *v = malloc(sizeof(short));
-       
-       *v = value;
-       
-       return newAttr(attr, sizeof(short), v);
-}
-
-
-static inline struct attr* newIntAttr (unsigned short attr, int value)
-{
-       int *v = malloc(sizeof(int));
-       
-       *v = value;
-       
-       return newAttr(attr, sizeof(int), v);
-}
-
-
-static inline 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);
-
-
-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);
-
-
-#endif
-
diff --git a/raw/Makefile b/raw/Makefile
new file mode 100644 (file)
index 0000000..9776fb3
--- /dev/null
@@ -0,0 +1,21 @@
+
+
+
+all: lib libdoc
+       
+
+
+lib: 
+       @+$(MAKE) -C src
+
+libdoc: 
+       doxygen rawnsdp
+
+
+clean: 
+       @rm -rf doc
+       @+$(MAKE) -C src clean
+
+mrproper: clean
+       @+$(MAKE) -C src mrproper
+
diff --git a/raw/include/attr.h b/raw/include/attr.h
new file mode 100644 (file)
index 0000000..e297b49
--- /dev/null
@@ -0,0 +1,132 @@
+
+#ifndef DEF_ATTR
+#define DEF_ATTR
+
+
+#include <stdbool.h>
+
+#include "protocol.h"
+
+
+#define ATTR_PRODUCT           0x0001
+#define ATTR_UNK_0002          0x0002
+#define ATTR_NAME              0x0003
+#define ATTR_MAC               0x0004
+#define ATTR_UNK_0005          0x0005
+#define ATTR_IP                        0x0006
+#define ATTR_NETMASK           0x0007
+#define ATTR_GATEWAY           0x0008
+#define ATTR_NEW_PASSWORD      0x0009
+#define ATTR_PASSWORD          0x000A
+#define ATTR_DHCP              0x000B
+#define ATTR_UNK_000C          0x000C
+#define ATTR_FIRM_VER          0x000D
+#define ATTR_UNK_000E          0x000E
+#define ATTR_UNK_000F          0x000F
+#define ATTR_FIRM_UPGRADE      0x0010
+#define ATTR_RESTART           0x0013
+#define ATTR_DEFAULTS          0x0400
+#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
+#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
+#define ATTR_BITRATE_OUTPUT    0x5000
+#define ATTR_STORM_ENABLE      0x5400
+#define ATTR_STORM_BITRATE     0x5800
+#define ATTR_MIRROR            0x5C00
+#define ATTR_PORTS_COUNT       0x6000
+#define ATTR_MAX_VLAN          0x6400
+#define ATTR_IGMP_ENABLE_VLAN  0x6800
+#define ATTR_IGMP_BLOCK_UNK    0x6C00
+#define ATTR_IGMP_VALID_V3     0x7000
+#define ATTR_TLV_BITMAP                0x7400
+#define ATTR_END               0xFFFF
+
+#define UNUSED                 __attribute__((unused))
+
+
+struct attr_handler {
+       unsigned short attr;                                    /* attribute code */
+       unsigned int size;                                      /* expected data size */
+       bool (*encode)(struct attr *at, unsigned char ports);   /* encode function */
+       bool (*decode)(struct attr *at, unsigned char ports);   /* decode function */
+};
+
+
+const struct attr_handler* getAttrHandler (unsigned short attrcode);
+
+
+
+
+struct attr_port_status {
+       unsigned char port;
+       unsigned char status;
+       unsigned char unk;
+} __attribute__((packed));
+
+
+struct attr_port_stat {
+       unsigned char port;
+       unsigned long long recv;
+       unsigned long long sent;
+       unsigned long long unk1;
+       unsigned long long unk2;
+       unsigned long long unk3;
+       unsigned long long crc;
+} __attribute__((packed));
+
+
+struct attr_bitrate {
+       unsigned char port;
+       int bitrate;
+} __attribute__((packed));
+
+
+struct attr_qos {
+       unsigned char port;
+       unsigned char prio;
+} __attribute__((packed));
+
+
+struct attr_pvid {
+       unsigned char port;
+       unsigned short vlan;
+} __attribute__((packed));
+
+
+struct attr_igmp_vlan {
+       unsigned short enable;
+       unsigned short vlan;
+} __attribute__((packed));
+
+
+struct attr_cabletest_do {
+       unsigned char port;
+       unsigned char action;
+} __attribute__((packed));
+
+
+struct attr_cabletest_result {
+       unsigned char port;
+       unsigned int v1;
+       unsigned int v2;
+} __attribute__((packed));
+
+
+struct attr_vlan_dot {
+       unsigned short vlan;
+       unsigned char ports[0];
+};
+
+
+#endif
+
diff --git a/raw/include/list.h b/raw/include/list.h
new file mode 100644 (file)
index 0000000..3eaf2ba
--- /dev/null
@@ -0,0 +1,71 @@
+
+#ifndef DEF_LIST
+#define DEF_LIST
+
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#ifdef MT_SAFE_LIST
+#include <pthread.h>
+#endif
+
+
+
+typedef struct ListNode ListNode;
+
+struct ListNode {
+ void* data;
+ ListNode *prev, *next;
+};
+
+
+typedef struct {
+ ListNode *first, *last;
+ unsigned int count;
+ #ifdef MT_SAFE_LIST
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ #endif
+} List;
+
+
+
+
+// Creates an empty list
+List* createEmptyList (void);
+
+// Destroys a list, and eventually frees the elements
+// NOT MT SAFE
+void destroyList (List *l, void (*freefunc)(void*));
+
+// Adds an element at front of the list
+void pushFrontList (List *l, void* data);
+
+// Adds an element at back of the list
+void pushBackList (List *l, void* data);
+
+// Pops an element from the front of the list and returns its value
+void* popFrontList (List *l);
+
+// Pops an element from the back of the list and returns its value
+void* popBackList (List *l);
+
+// Clears all the items of the list, and eventually frees them
+void clearList (List *l, 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*));
+
+// Browse all the items of the list through the callback function
+void browseList (List *l, void (*browsefunc)(void*));
+
+// 
+void* convertToArray (List *l, size_t sz);
+
+
+
+
+#endif
+
diff --git a/raw/include/protocol.h b/raw/include/protocol.h
new file mode 100644 (file)
index 0000000..3064fd4
--- /dev/null
@@ -0,0 +1,157 @@
+
+#ifndef DEF_PROTOCOL
+#define DEF_PROTOCOL
+
+
+#include <stdlib.h>
+#include <arpa/inet.h>
+
+#include <netinet/ether.h>
+
+#include "list.h"
+
+
+#define CLIENT_PORT            63321
+#define SWITCH_PORT            63322
+
+#define CODE_READ_REQ          1
+#define CODE_READ_REP          2
+#define CODE_WRITE_REQ         3
+#define CODE_WRITE_REP         4
+
+#define ERROR_READONLY         3
+#define ERROR_INVALID_VALUE    5
+#define ERROR_DENIED           7
+
+
+struct ng_header {
+       char version;                   /* always 1, maybe version */
+       char code;                      /* request code: read request, read reply, write request, write reply */
+       unsigned char error;            /* error code, 0 when no error */
+       unsigned char unk1;             /* always 0, unknown */
+       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));
+
+
+struct attr_header {
+       unsigned short attr;
+       unsigned short size;
+       char data[0];
+} __attribute__((packed));
+
+
+struct ng_packet {
+       union {
+               char *buffer;
+               struct ng_header *nh;
+       };
+       int maxlen;
+       struct attr_header *ah;
+};
+
+
+struct attr {
+       unsigned short attr;
+       unsigned short size;
+       void *data;
+};
+
+
+
+int trim (char *txt, int start);
+
+
+static inline int min (int a, int b)
+{
+       return a < b ? a : b;
+}
+
+
+void initNgHeader (struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum);
+
+
+bool validateNgHeader (const struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum);
+
+
+static inline void initNgPacket (struct ng_packet *np)
+{
+       np->ah = (struct attr_header*)np->nh->data;
+}
+
+
+void addPacketAttr (struct ng_packet *np, struct attr *at);
+
+
+static inline int getPacketTotalSize (const struct ng_packet *np)
+{
+       return ((char*)np->ah) - np->buffer;
+}
+
+
+struct attr* newAttr (unsigned short attr, unsigned short size, void *data);
+
+
+static inline struct attr* newEmptyAttr (unsigned short attr)
+{
+       return newAttr(attr, 0, NULL);
+}
+
+
+static inline struct attr* newByteAttr (unsigned short attr, unsigned char value)
+{
+       char *v = malloc(sizeof(char));
+       
+       *v = value;
+       
+       return newAttr(attr, sizeof(char), v);
+}
+
+
+static inline struct attr* newShortAttr (unsigned short attr, short value)
+{
+       short *v = malloc(sizeof(short));
+       
+       *v = value;
+       
+       return newAttr(attr, sizeof(short), v);
+}
+
+
+static inline struct attr* newIntAttr (unsigned short attr, int value)
+{
+       int *v = malloc(sizeof(int));
+       
+       *v = value;
+       
+       return newAttr(attr, sizeof(int), v);
+}
+
+
+static inline 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);
+
+
+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);
+
+
+#endif
+
diff --git a/raw/src/Makefile b/raw/src/Makefile
new file mode 100644 (file)
index 0000000..f9c2c6e
--- /dev/null
@@ -0,0 +1,31 @@
+
+CC=gcc
+AR=ar
+CFLAGS=-I../include/ -I../../lib/include/ -W -Wall -Wextra -Os -fno-strict-aliasing -fvisibility=hidden -fPIC
+EXEC=../librawnsdp.a
+
+SRC=$(wildcard *.c)
+OBJ=$(SRC:.c=.o)
+
+
+ifeq ($(DEBUG), yes)
+CFLAGS+=-g
+else
+CFLAGS+=-fomit-frame-pointer
+endif
+
+
+$(EXEC): $(OBJ)
+       $(AR) rcs $@ $^
+
+%.o: %.c
+       $(CC) -c $^ -o $@ $(CFLAGS)
+
+
+clean:
+       @rm -f *.o
+
+mrproper: clean
+       @rm -f $(EXEC)
+
+
diff --git a/raw/src/attr.c b/raw/src/attr.c
new file mode 100644 (file)
index 0000000..39f8f25
--- /dev/null
@@ -0,0 +1,464 @@
+
+#include <ngadmin.h>
+
+#include "attr.h"
+#include "protocol.h"
+
+
+#define ATTR_HANDLER_ENTRY(at, sz, enc, dec)   {.attr = at, .size = sz, .encode = enc, .decode = dec}
+
+
+
+static bool bool_endecode (struct attr *at, unsigned char ports UNUSED)
+{
+       *(char*)at->data = (*(char*)at->data != 0);
+       
+       return true;
+}
+
+
+static bool ports_status_decode (struct attr *at, unsigned char ports)
+{
+       struct attr_port_status *ps = at->data;
+       
+       if (ps->port < 1 || ps->port > ports)
+               return false;
+       
+       switch (ps->status) {
+       case SPEED_DOWN:
+       case SPEED_10:
+       case SPEED_100:
+       case SPEED_1000:
+               break;
+       default:
+               return false;
+       }
+       
+       return true;
+}
+
+
+static bool port_stat_decode (struct attr *at, unsigned char ports)
+{
+       struct attr_port_stat *ps = at->data;
+       unsigned long long *v;
+       
+       if (ps->port < 1 || ps->port > ports)
+               return false;
+       
+       for (v = &ps->recv; ((char*)v) - ((char*)ps) < (int)sizeof(struct attr_port_stat); v++)
+               *v = be64toh(*v);
+       
+       
+       return true;
+}
+
+
+static bool bitrate_decode (struct attr *at, unsigned char ports)
+{
+       struct attr_bitrate *sb = at->data;
+       
+       if (sb->port < 1 || sb->port > ports)
+               return false;
+       
+       sb->bitrate = ntohl(sb->bitrate);
+       if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
+               return false;
+       
+       return true;
+}
+
+
+static bool bitrate_encode (struct attr *at, unsigned char ports)
+{
+       struct attr_bitrate *sb = at->data;
+       
+       if (sb->port < 1 || sb->port > ports)
+               return false;
+       
+       if (sb->bitrate < BITRATE_UNSPEC || sb->bitrate > BITRATE_512M)
+               return false;
+       sb->bitrate = htonl(sb->bitrate);
+       
+       return true;
+}
+
+
+static bool qos_mode_endecode (struct attr *at, unsigned char ports UNUSED)
+{
+       unsigned char v = *(char*)at->data;
+       
+       return (v == QOS_PORT || v == QOS_DOT);
+}
+
+
+static bool qos_endecode (struct attr *at, unsigned char ports)
+{
+       struct attr_qos *aq = at->data;
+       
+       if (aq->port < 1 || aq->port > ports)
+               return false;
+       
+       return (aq->prio >= PRIO_HIGH && aq->prio <= PRIO_LOW);
+}
+
+
+static bool pvid_decode (struct attr *at, unsigned char ports)
+{
+       struct attr_pvid *ap= at->data;
+       
+       if (ap->port < 1 || ap->port > ports)
+               return false;
+       
+       ap->vlan = ntohs(ap->vlan);
+       
+       return (ap->vlan >= VLAN_MIN && ap->vlan <= VLAN_MAX);
+}
+
+
+static bool pvid_encode (struct attr *at, unsigned char ports)
+{
+       struct attr_pvid *ap= at->data;
+       
+       if (ap->port < 1 || ap->port > ports)
+               return false;
+       
+       if (ap->vlan < VLAN_MIN || ap->vlan > VLAN_MAX)
+               return false;
+       
+       ap->vlan = htons(ap->vlan);
+       
+       return true;
+}
+
+
+static bool vlan_destroy_encode (struct attr *at, unsigned char ports UNUSED)
+{
+       unsigned short v = *(unsigned short*)at->data;
+       
+       if (v < VLAN_MIN || v > VLAN_MAX)
+               return false;
+       
+       *(unsigned short*)at->data = htons(v);
+       
+       return true;
+}
+
+
+static bool mirror_decode (struct attr *at, unsigned char ports)
+{
+       unsigned char *r = at->data, *p;
+       int port;
+       
+       
+       if (at->size != 3 + ((ports - 1) >> 3))
+               return false;
+       
+       /* r[0] == 0 is allowed and means mirroring is disabled */
+       if (r[0] > ports)
+               return false;
+       
+       p = malloc(1 + ports);
+       if (p == NULL)
+               return false;
+       
+       memset(p, 0, 1 + ports);
+       
+       if (r[0] == 0)
+               goto end;
+       
+       p[0] = r[0];
+       
+       for (port = 1; port <= ports; port++)
+               p[port] = (r[2] >> (8 - port)) & 1; /* FIXME: if ports > 8 */
+       
+end:
+       free(at->data);
+       at->data = p;
+       at->size = 1 + ports;
+       
+       
+       return true;
+}
+
+
+static bool mirror_encode (struct attr *at, unsigned char ports)
+{
+       unsigned char *p = at->data, *r;
+       int port;
+       
+       
+       if (at->size != 1 + ports)
+               return false;
+       
+       /* p[0] == 0 is allowed and means mirroring is disabled */
+       if (p[0] > ports)
+               return false;
+       
+       r = malloc(3 + ((ports - 1) >> 3));
+       if (r == NULL)
+               return false;
+       
+       memset(r, 0, 3 + ((ports - 1) >> 3));
+       
+       if (p[0] == 0)
+               goto end;
+       
+       r[0] = p[0];
+       
+       for (port = 1; port <= ports; port++) {
+               if (p[0] != port)
+                       r[2] |= (p[port] & 1) << (8 - port); /* FIXME: if ports > 8 */
+       }
+       
+end:
+       free(at->data);
+       at->data = r;
+       at->size = 3 + ((ports - 1) >> 3);
+       
+       
+       return true;
+}
+
+
+static bool igmp_vlan_decode (struct attr *at, unsigned char ports UNUSED)
+{
+       struct attr_igmp_vlan *aiv = at->data;
+       
+       aiv->enable = ntohs(aiv->enable);
+       if (aiv->enable != 0 && aiv->enable != 1)
+               return false;
+       
+       aiv->vlan = ntohs(aiv->vlan);
+       if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_MAX)
+               return false;
+       
+       return true;
+}
+
+
+static bool igmp_vlan_encode (struct attr *at, unsigned char ports UNUSED)
+{
+       struct attr_igmp_vlan *aiv = at->data;
+       
+       if (aiv->enable != 0 && aiv->enable != 1)
+               return false;
+       aiv->enable = htons(aiv->enable);
+       
+       if (aiv->vlan < VLAN_MIN || aiv->vlan > VLAN_MAX)
+               return false;
+       aiv->vlan = htons(aiv->vlan);
+       
+       return true;
+}
+
+
+static bool cabletest_do_encode (struct attr *at, unsigned char ports)
+{
+       struct attr_cabletest_do *acd = at->data;
+       
+       if (acd->port < 1 || acd->port > ports)
+               return false;
+       
+       return (acd->action == 1);
+}
+
+
+static bool cabletest_result_encode (struct attr *at, unsigned char ports)
+{
+       unsigned char v = *(unsigned char*)at->data;
+       
+       return (v >= 1 && v <= ports);
+}
+
+
+static bool cabletest_result_decode (struct attr *at, unsigned char ports)
+{
+       struct attr_cabletest_result *acr = at->data;
+       
+       if (acr->port < 1 || acr->port > ports)
+               return false;
+       
+       acr->v1 = ntohl(acr->v1);
+       acr->v2 = ntohl(acr->v2);
+       
+       return true;
+}
+
+
+static bool cabletest_result_endecode (struct attr *at, unsigned char ports)
+{
+       switch (at->size) {
+       
+       case 1:
+               return cabletest_result_encode(at, ports);
+       
+       case sizeof(struct attr_cabletest_result):
+               return cabletest_result_decode(at, ports);
+       
+       default:
+               return false;
+       }
+}
+
+
+static bool vlan_type_endecode (struct attr *at, unsigned char ports UNUSED)
+{
+       char v = *(char*)at->data;
+       
+       return (v >= VLAN_DISABLED && v <= VLAN_DOT_ADV);
+}
+
+
+static bool vlan_dot_decode (struct attr *at, unsigned char ports)
+{
+       char *r = at->data;
+       struct attr_vlan_dot *avd;
+       int port;
+       
+       
+       if (at->size != (2 + 2 * (1 + ((ports - 1) >> 3))))
+               return false;
+       
+       avd = malloc(sizeof(struct attr_vlan_dot) + ports);
+       if (avd == NULL)
+               return false;
+       
+       avd->vlan = ntohs(*(unsigned short*)r);
+       r += 2;
+       
+       for (port = 0; port < ports; port++) {
+               /* FIXME: if ports > 8 */
+               if ((r[1] >> (7 - port)) & 1)
+                       avd->ports[port] = VLAN_TAGGED;
+               else if ((r[0] >> (7 - port)) & 1)
+                       avd->ports[port] = VLAN_UNTAGGED;
+               else
+                       avd->ports[port] = VLAN_NO;
+       }
+       
+       free(at->data);
+       at->data = avd;
+       at->size = sizeof(struct attr_vlan_dot) + ports;
+       
+       
+       return true;
+}
+
+
+static bool vlan_dot_encode (struct attr *at, unsigned char ports)
+{
+       struct attr_vlan_dot *avd = at->data;
+       char *r, fl;
+       unsigned int size, port;
+       
+       
+       if (avd->vlan < VLAN_MIN || avd->vlan > VLAN_MAX)
+               return false;
+       
+       /* just a header is valid */
+       if (at->size == sizeof(struct attr_vlan_dot))
+               size = 2;
+       else if (at->size == sizeof(struct attr_vlan_dot) + ports)
+               size = (2 + 2 * (1 + ((ports - 1) >> 3)));
+       else
+               return false;
+       
+       r = malloc(size);
+       if (r == NULL)
+               return false;
+       
+       memset(r, 0, size);
+       *(unsigned short*)r = htons(avd->vlan);
+       
+       if (size == 2)
+               goto end;
+       
+       r += 2;
+       
+       for (port = 0; port < ports; port++) {
+               /* FIXME: if ports > 8 */
+               fl = (1 << (7 - port));
+               switch (avd->ports[port]) {
+               case VLAN_TAGGED:
+                       r[1] |= fl;
+               case VLAN_UNTAGGED:
+                       r[0] |= fl;
+               }
+       }
+       
+       r -= 2;
+       
+end:
+       free(at->data);
+       at->data = r;
+       at->size = size;
+       
+       
+       return true;
+}
+
+
+
+/* WARNING: attributes codes MUST be in ascending order */
+static const struct attr_handler attrtab[] = {
+       ATTR_HANDLER_ENTRY(ATTR_MAC, 6, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_IP, 4, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_NETMASK, 4, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_GATEWAY, 4, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_DHCP, 2, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_RESTART, 1, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_DEFAULTS, 1, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_PORT_STATUS, sizeof(struct attr_port_status), NULL, ports_status_decode),
+       ATTR_HANDLER_ENTRY(ATTR_PORT_STATISTICS, sizeof(struct attr_port_stat), NULL, port_stat_decode),
+       ATTR_HANDLER_ENTRY(ATTR_STATS_RESET, 1, bool_endecode, bool_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_CABLETEST_DO, sizeof(struct attr_cabletest_do), cabletest_do_encode, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_CABLETEST_RESULT, 0, cabletest_result_endecode, cabletest_result_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_VLAN_TYPE, 1, vlan_type_endecode, vlan_type_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_VLAN_DOT_CONF, 0, vlan_dot_encode, vlan_dot_decode),
+       ATTR_HANDLER_ENTRY(ATTR_VLAN_DESTROY, 2, vlan_destroy_encode, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_VLAN_PVID, sizeof(struct attr_pvid), pvid_encode, pvid_decode),
+       ATTR_HANDLER_ENTRY(ATTR_QOS_TYPE, 1, qos_mode_endecode, qos_mode_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_QOS_CONFIG, sizeof(struct attr_qos), qos_endecode, qos_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_BITRATE_INPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
+       ATTR_HANDLER_ENTRY(ATTR_BITRATE_OUTPUT, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
+       ATTR_HANDLER_ENTRY(ATTR_STORM_ENABLE, 1, bool_endecode, bool_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_STORM_BITRATE, sizeof(struct attr_bitrate), bitrate_encode, bitrate_decode),
+       ATTR_HANDLER_ENTRY(ATTR_MIRROR, 0, mirror_encode, mirror_decode),
+       ATTR_HANDLER_ENTRY(ATTR_PORTS_COUNT, 1, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_IGMP_ENABLE_VLAN, sizeof(struct attr_igmp_vlan), igmp_vlan_encode, igmp_vlan_decode),
+       ATTR_HANDLER_ENTRY(ATTR_IGMP_BLOCK_UNK, 1, bool_endecode, bool_endecode),
+       ATTR_HANDLER_ENTRY(ATTR_IGMP_VALID_V3, 1, bool_endecode, bool_endecode)
+};
+
+
+
+const struct attr_handler* getAttrHandler (unsigned short attrcode)
+{
+       const struct attr_handler *ah;
+       const unsigned int tab_size = sizeof(attrtab) / sizeof(struct attr_handler);
+       unsigned int inf, sup, index;
+       
+       
+       inf = 0;
+       sup = tab_size;
+       index = tab_size >> 1;
+       while (index < sup) {
+               ah = &attrtab[index];
+               
+               if (ah->attr > attrcode) {
+                       sup = index;
+                       index -= ((index - inf) >> 1) + ((index - inf) & 1);
+               } else if (ah->attr < attrcode) {
+                       inf = index;
+                       index += ((sup - index) >> 1) + ((sup - index) & 1);
+               } else {
+                       return ah;
+               }
+       }
+       
+       
+       return NULL;
+}
+
+
diff --git a/raw/src/list.c b/raw/src/list.c
new file mode 100644 (file)
index 0000000..88a222b
--- /dev/null
@@ -0,0 +1,406 @@
+
+#include "list.h"
+
+
+
+
+// -------------------------
+List* createEmptyList (void) {
+ List *l;
+ l=malloc(sizeof(List));
+ l->first=NULL;
+ l->last=NULL;
+ l->count=0;
+ #ifdef MT_SAFE_LIST
+ pthread_cond_init(&l->cond, NULL);
+ pthread_mutex_init(&l->mutex, NULL);
+ #endif
+ return l;
+}
+
+
+
+// ------------------------------------------------
+void destroyList (List *l, void (*freefunc)(void*)) {
+ ListNode *pr, *ln;
+ if ( l==NULL ) {
+  return;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_destroy(&l->mutex);
+ pthread_cond_destroy(&l->cond);
+ #endif
+ for (ln=l->first; ln!=NULL; ) {
+  
+  pr=ln;
+  
+  if ( freefunc!=NULL ) {
+   freefunc(pr->data);
+  }
+  
+  ln=pr->next;
+  free(pr);
+  
+ }
+ free(l);
+}
+
+
+
+// -------------------------------------
+void pushFrontList (List *l, void* data) {
+ ListNode *ln;
+ if ( l==NULL ) {
+  return;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ ln=malloc(sizeof(ListNode));
+ ln->data=data;
+ ln->prev=NULL;
+ ln->next=l->first;
+ if ( l->first==NULL ) {
+  l->last=ln;
+ } else {
+  l->first->prev=ln;
+ }
+ l->first=ln;
+ l->count++;
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ pthread_cond_broadcast(&l->cond);
+ #endif
+}
+
+
+
+// ------------------------------------
+void pushBackList (List *l, void* data) {
+ ListNode *ln;
+ if ( l==NULL ) {
+  return;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ ln=malloc(sizeof(ListNode));
+ ln->data=data;
+ ln->prev=l->last;
+ ln->next=NULL;
+ if ( l->last==NULL ) {
+  l->first=ln;
+ } else {
+  l->last->next=ln;
+ }
+ l->last=ln;
+ l->count++;
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ pthread_cond_broadcast(&l->cond);
+ #endif
+}
+
+
+
+// -------------------------
+void* popFrontList (List *l) {
+ ListNode *ln;
+ void* data;
+ if ( l==NULL ) {
+  return NULL;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ if ( (ln=l->first)==NULL ) {
+  #ifdef MT_SAFE_LIST
+  pthread_mutex_unlock(&l->mutex);
+  #endif
+  return NULL;
+ }
+ data=ln->data;
+ l->first=ln->next;
+ if ( ln->next==NULL ) {
+  l->last=NULL;
+ } else {
+  ln->next->prev=NULL;
+ }
+ l->count--;
+ free(ln);
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ pthread_cond_broadcast(&l->cond);
+ #endif
+ return data;
+}
+
+
+
+// ------------------------
+void* popBackList (List *l) {
+ ListNode *ln;
+ void* data;
+ if ( l==NULL ) {
+  return NULL;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ if ( (ln=l->last)==NULL ) {
+  #ifdef MT_SAFE_LIST
+  pthread_mutex_unlock(&l->mutex);
+  #endif
+  return NULL;
+ }
+ data=ln->data;
+ l->last=ln->prev;
+ if ( ln->prev==NULL ) {
+  l->first=NULL;
+ } else {
+  ln->prev->next=NULL;
+ }
+ l->count--;
+ free(ln);
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ pthread_cond_broadcast(&l->cond);
+ #endif
+ return data;
+}
+
+
+
+// ----------------------------------------------
+void clearList (List *l, void (*freefunc)(void*)) {
+ ListNode *ln, *pr;
+ if ( l==NULL ) {
+  return;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ for (ln=l->first; ln!=NULL; ) {
+  
+  pr=ln;
+  
+  if ( freefunc!=NULL ) {
+   freefunc(pr->data);
+  }
+  
+  ln=pr->next;
+  free(pr);
+  
+ }
+ l->first=NULL;
+ l->last=NULL;
+ l->count=0;
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ pthread_cond_broadcast(&l->cond);
+ #endif
+}
+
+
+
+// ---------------------------------------------------------------
+bool findAndDestroy (List *l, void* data, void (*freefunc)(void*)) {
+ ListNode *ln;
+ if ( l==NULL ) {
+  return false;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ for (ln=l->first; ln!=NULL && ln->data!=data; ln=ln->next);
+ if ( ln==NULL ) {
+  
+  #ifdef MT_SAFE_LIST
+  pthread_mutex_unlock(&l->mutex);
+  #endif
+  
+ } 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--;
+  
+  #ifdef MT_SAFE_LIST
+  pthread_mutex_unlock(&l->mutex);
+  pthread_cond_broadcast(&l->cond);
+  #endif
+  
+ }
+ return true;
+}
+
+
+
+// -------------------------------------------------
+void browseList (List *l, void (*browsefunc)(void*)) {
+ ListNode *ln;
+ if ( l==NULL || browsefunc==NULL ) {
+  return;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ for (ln=l->first; ln!=NULL; ln=ln->next) {
+  browsefunc(ln->data);
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ #endif
+}
+
+
+// --------------------------------------
+void* convertToArray (List *l, size_t sz) {
+ ListNode *ln;
+ void *tab=NULL, *p;
+ if ( l==NULL || sz==0 ) {
+  return NULL;
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_lock(&l->mutex);
+ #endif
+ if ( l->count>0 ) {
+  
+  tab=malloc(l->count*sz);
+  p=tab;
+  
+  for (ln=l->first; ln!=NULL; ln=ln->next) {
+   memcpy(p, ln->data, sz);
+   p+=sz;
+  }
+  
+ }
+ #ifdef MT_SAFE_LIST
+ pthread_mutex_unlock(&l->mutex);
+ #endif
+ return tab;
+}
+
+
+
+
diff --git a/raw/src/protocol.c b/raw/src/protocol.c
new file mode 100644 (file)
index 0000000..de2c451
--- /dev/null
@@ -0,0 +1,237 @@
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+
+#include "attr.h"
+#include "protocol.h"
+
+
+
+int trim (char *txt, int start)
+{
+       char *p;
+       
+       if (txt == NULL)
+               return 0;
+       
+       p = txt + start;
+       while (p >= txt && (*p == ' ' || *p == '\n')) {
+               *p = '\0';
+               p--;
+       }
+       
+       return p - txt + 1;
+}
+
+
+void initNgHeader (struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum)
+{
+       memset(nh, 0, sizeof(struct ng_header));
+       nh->version = 1;
+       nh->code = code;
+       
+       memcpy(nh->client_mac, client_mac, ETH_ALEN);
+       
+       if (switch_mac != NULL)
+               memcpy(nh->switch_mac, switch_mac, ETH_ALEN);
+       
+       nh->seqnum = htonl(seqnum);
+       memcpy(nh->proto_id, "NSDP", 4);
+}
+
+
+bool validateNgHeader (const struct ng_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum)
+{
+       if (nh->version != 1)
+               return false;
+       
+       if (code > 0 && nh->code != code)
+               return false;
+       
+       if (nh->unk1 != 0)
+               return false;
+       
+       if (*(unsigned short*)nh->unk2 != 0)
+               return false;
+       
+       if (client_mac != NULL && memcmp(nh->client_mac, client_mac, ETH_ALEN) != 0)
+               return false;
+       
+       if (switch_mac != NULL && memcmp(nh->switch_mac, switch_mac, ETH_ALEN) != 0)
+               return false;
+       
+       if (seqnum > 0 && ntohl(nh->seqnum) != seqnum)
+               return false;
+       
+       if (memcmp(nh->proto_id, "NSDP", 4) != 0)
+               return false;
+       
+       if (*(unsigned int*)nh->unk3 != 0)
+               return false;
+       
+       return true;
+}
+
+
+void addPacketAttr (struct ng_packet *np, struct attr *at)
+{
+       struct attr_header *ah = np->ah;
+       
+       
+       if ((int)(getPacketTotalSize(np) + sizeof(struct attr_header) + at->size) > np->maxlen)
+               return;
+       
+       ah->attr = htons(at->attr);
+       ah->size = htons(at->size);
+       
+       if (at->size > 0 && at->data != NULL)
+               memcpy(ah->data, at->data, at->size);
+       
+       np->ah = (struct attr_header*)(ah->data + at->size);
+}
+
+
+struct attr* newAttr (unsigned short attr, unsigned short size, void *data)
+{
+       struct attr *at;
+       
+       
+       at = malloc(sizeof(struct attr));
+       if (at == NULL)
+               return NULL;
+       
+       at->attr = attr;
+       at->size = size;
+       at->data = data;
+       
+       
+       return at;
+}
+
+
+void freeAttr (struct attr *at)
+{
+       if (at != NULL) {
+               free(at->data);
+               free(at);
+       }
+}
+
+
+int addPacketAttributes (struct ng_packet *np, const List* attr, unsigned char ports)
+{
+       ListNode *ln;
+       struct attr *at;
+       const struct attr_handler *ah;
+       
+       
+       if (attr == NULL)
+               return 0;
+       
+       for (ln = attr->first; ln != NULL; ln = ln->next) {
+               at = ln->data;
+               ah = getAttrHandler(at->attr);
+               if (ah != NULL) {
+                       if (ah->size > 0 && at->size > 0 && at->size != ah->size)
+                               return -EINVAL;
+                       if (at->size > 0 && ah->encode != NULL && !ah->encode(at, ports))
+                               return -EINVAL;
+               }
+               
+               addPacketAttr(np, at);
+       }
+       
+       
+       return 0;
+}
+
+
+int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr, unsigned short filter_attr, unsigned char ports)
+{
+       struct attr *at;
+       const struct attr_handler *ah;
+       int ret = 0;
+       unsigned short size;
+       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 */
+               if (getPacketTotalSize(np) + (int)sizeof(struct attr_header) > np->maxlen) {
+                       ret = -1;
+                       break;
+               }
+               
+               /* create new attribute */
+               size = ntohs(np->ah->size);
+               at = newAttr(ntohs(np->ah->attr), size, NULL);
+               if (at == NULL) {
+                       ret = -1;
+                       break;
+               }
+               
+               /* attribute data bigger than the remaining size: error */
+               if (getPacketTotalSize(np) + (int)sizeof(struct attr_header) + size > np->maxlen) {
+                       free(at);
+                       ret = -1;
+                       break;
+               }
+               
+               /* copy attribute raw data */
+               if (size == 0) {
+                       at->data = NULL;
+               } else {
+                       at->data = malloc(size * sizeof(char));
+                       memcpy(at->data, np->ah->data, size);
+               }
+               
+               /* 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;
+               
+               if (ah->size > 0 && size != ah->size) {
+                       valid = false;
+                       goto next;
+               }
+               
+               if (ah->decode != NULL)
+                       valid = ah->decode(at, ports);
+               
+next:
+               /* stop on an END attribute */
+               if (at->attr == ATTR_END) {
+                       free(at);
+                       break;
+               }
+               
+               /* move to next attribute */
+               np->ah = (struct attr_header*)(np->ah->data + size);
+               
+               if (valid)
+                       pushBackList(attr, at);
+               else
+                       free(at);
+       }
+       
+       
+       return ret;
+}
+
+