*.so
*.a
*.la
+*.orig
*.pc
ngcli
ngspy
Makefile
raw/Makefile
raw/include/Makefile
+ raw/include/nsdp/Makefile
raw/src/Makefile
lib/Makefile
lib/include/Makefile
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
+#include <nsdp/misc.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <netinet/ether.h>
#include <sys/ioctl.h>
-#include <attr.h>
-#include <encoding.h>
-#include <misc.h>
+#include <nsdp/attr.h>
+#include <nsdp/misc.h>
+#include <nsdp/net.h>
+#include <nsdp/protocol.h>
#include "network.h"
}
-int sendNsdpPacket (struct ngadmin *nga, char code, const List *attr)
+static int checkErrorCode (const struct nsdp_cmd *nc)
{
- unsigned char buffer[1500];
- struct nsdp_packet np;
- struct sockaddr_in remote;
- const struct swi_attr *sa = nga->current;
- int ret;
+ switch (nc->error) {
+ case ERROR_DENIED:
+ return (nc->attr_error == ATTR_PASSWORD) ? ERR_BADPASS : ERR_DENIED;
- np.buffer = buffer;
- np.maxlen = sizeof(buffer);
- initNsdpPacket(&np);
- initNsdpHeader(np.nh, code, &nga->localmac, sa == NULL ? NULL : &sa->mac, ++nga->seq);
+ case ERROR_INVALID_VALUE:
+ return ERR_INVARG;
- ret = addPacketAttributes(&np, attr, sa == NULL ? 0 : sa->ports);
- if (ret < 0)
- return ret;
+ default:
+ return ERR_OK;
+ }
+}
+
+
+void prepareSend (struct ngadmin *nga, struct nsdp_cmd *nc, unsigned char code)
+{
+ struct swi_attr *sa = nga->current;
- memset(&remote, 0, sizeof(struct sockaddr_in));
- remote.sin_family = AF_INET;
- remote.sin_port = htons(SWITCH_PORT);
+
+ memset(nc, 0, sizeof(struct nsdp_cmd));
+ memcpy(&nc->client_mac, &nga->localmac, ETH_ALEN);
+ nc->remote_addr.sin_family = AF_INET;
+ nc->remote_addr.sin_port = htons(SWITCH_PORT);
+ if (sa != NULL) {
+ memcpy(&nc->switch_mac, &sa->mac, ETH_ALEN);
+ nc->ports = sa->ports;
+ }
/* destination address selection */
if (sa != NULL && !nga->keepbroad)
- remote.sin_addr = sa->nc.ip;
+ nc->remote_addr.sin_addr = sa->nc.ip;
else if (nga->globalbroad)
- remote.sin_addr.s_addr = htonl(INADDR_BROADCAST);
+ nc->remote_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
else
- remote.sin_addr = nga->brd;
-
- ret = sendto(nga->sock, buffer, getPacketTotalSize(&np), 0, (struct sockaddr*)&remote, sizeof(struct sockaddr_in));
- if (ret < 0)
- perror("sendto");
+ nc->remote_addr.sin_addr = nga->brd;
-
- return ret;
+ nc->seqnum = ++nga->seq;
+ nc->code = code;
}
-int recvNsdpPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr)
+void prepareRecv (struct ngadmin *nga, struct nsdp_cmd *nc, unsigned char code)
{
- unsigned char buffer[1500];
- struct nsdp_packet np;
- struct sockaddr_in remote;
- socklen_t slen = sizeof(struct sockaddr_in);
- const struct swi_attr *sa = nga->current;
- struct timeval rem;
- fd_set fs;
- int len = -1;
-
-
- np.buffer = buffer;
-
- memset(&remote, 0, sizeof(struct sockaddr_in));
- remote.sin_family = AF_INET;
+ struct swi_attr *sa = nga->current;
- rem = nga->timeout;
- while (1) {
- FD_ZERO(&fs);
- FD_SET(nga->sock, &fs);
- select(nga->sock + 1, &fs, NULL, NULL, &rem); /* FIXME: non portable */
-
- len = recvfrom(nga->sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
- if (len < 0)
- break;
-
- np.maxlen = len;
- initNsdpPacket(&np);
-
- if (ntohs(remote.sin_port) != SWITCH_PORT ||
- len < (int)sizeof(struct nsdp_header) ||
- !validateNsdpHeader(np.nh, code, &nga->localmac, sa == NULL ? NULL : &sa->mac, nga->seq) ||
- 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;
+ memset(nc, 0, sizeof(struct nsdp_cmd));
+ memcpy(&nc->client_mac, &nga->localmac, ETH_ALEN);
+ nc->remote_addr.sin_family = AF_INET;
+ nc->remote_addr.sin_port = htons(SWITCH_PORT);
+ if (sa != NULL) {
+ memcpy(&nc->switch_mac, &sa->mac, ETH_ALEN);
+ nc->ports = sa->ports;
}
+ /* set filter on switch IP */
+ if (sa == NULL)
+ nc->remote_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ else
+ nc->remote_addr.sin_addr = sa->nc.ip;
- return len;
-}
-
-
-static int checkErrorCode (unsigned char err, unsigned short attr_error)
-{
- switch (err) {
- case ERROR_DENIED:
- return attr_error == ATTR_PASSWORD ? ERR_BADPASS : ERR_DENIED;
- case ERROR_INVALID_VALUE:
- return ERR_INVARG;
- default:
- return ERR_OK;
- }
+ nc->seqnum = nga->seq;
+ nc->code = code;
}
int readRequest (struct ngadmin *nga, List *attr)
{
int i, ret = ERR_OK;
- unsigned char err;
- unsigned short attr_error;
+ struct nsdp_cmd nc;
if (nga == NULL) {
/* add end attribute to end */
pushBackList(attr, newEmptyAttr(ATTR_END));
- i = sendNsdpPacket(nga, CODE_READ_REQ, attr);
+ prepareSend(nga, &nc, CODE_READ_REQ);
+ i = sendNsdpPacket(nga->sock, &nc, attr);
- /* the list will be filled again by recvNgPacket */
+ /* do not destroy the list, it will be filled again later by recvNsdpPacket */
clearList(attr, (void(*)(void*))freeAttr);
- if (i >= 0)
- i = recvNsdpPacket(nga, CODE_READ_REP, &err, &attr_error, attr);
+ if (i >= 0) {
+ prepareRecv(nga, &nc, CODE_READ_REP);
+ i = recvNsdpPacket(nga->sock, &nc, attr, &nga->timeout);
+ }
if (i == -EINVAL) {
ret = ERR_INVARG;
goto end;
} else if (i < 0) {
- ret = ( errno == EAGAIN || errno == EWOULDBLOCK ) ? ERR_TIMEOUT : ERR_NET;
+ ret = (errno == EAGAIN || errno == EWOULDBLOCK) ? ERR_TIMEOUT : ERR_NET;
goto end;
}
/* check the switch error code */
- ret = checkErrorCode(err, attr_error);
+ ret = checkErrorCode(&nc);
end:
int writeRequest (struct ngadmin *nga, List *attr)
{
int i, ret = ERR_OK;
- unsigned char err;
- unsigned short attr_error;
struct attr *at;
+ struct nsdp_cmd nc;
if (nga == NULL) {
/* add end attribute to end */
pushBackList(attr, newEmptyAttr(ATTR_END));
- i = sendNsdpPacket(nga, CODE_WRITE_REQ, attr);
+ prepareSend(nga, &nc, CODE_WRITE_REQ);
+ i = sendNsdpPacket(nga->sock, &nc, 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 = recvNsdpPacket(nga, CODE_WRITE_REP, &err, &attr_error, attr);
+ if (i >= 0) {
+ prepareRecv(nga, &nc, CODE_WRITE_REP);
+ i = recvNsdpPacket(nga->sock, &nc, attr, &nga->timeout);
+ }
if (i == -EINVAL) {
ret = ERR_INVARG;
goto end;
} else if (i < 0) {
- ret = (errno == EAGAIN || errno == EWOULDBLOCK) ? ERR_TIMEOUT : ERR_NET ;
+ ret = (errno == EAGAIN || errno == EWOULDBLOCK) ? ERR_TIMEOUT : ERR_NET;
goto end;
}
/* check the switch error code */
- ret = checkErrorCode(err, attr_error);
+ ret = checkErrorCode(&nc);
end:
#define DEF_NETWORK
-#include "list.h"
+#include <nsdp/list.h>
+#include <nsdp/net.h>
#include "lib.h"
int updateTimeout (struct ngadmin *nga);
-int sendNsdpPacket (struct ngadmin *nga, char code, const List *attr);
+void prepareSend (struct ngadmin *nga, struct nsdp_cmd *nc, unsigned char code);
-int recvNsdpPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr);
+void prepareRecv (struct ngadmin *nga, struct nsdp_cmd *nc, unsigned char code);
int readRequest (struct ngadmin *nga, List *attr);
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
int i;
List *attr, *swiList;
struct swi_attr *sa;
+ struct nsdp_cmd nc;
/*
sent by official win client:
ATTR_PRODUCT,
}
/* send request to all potential switches */
- i = sendNsdpPacket(nga, CODE_READ_REQ, attr);
+ prepareSend(nga, &nc, CODE_READ_REQ);
+ i = sendNsdpPacket(nga->sock, &nc, attr);
clearList(attr, (void(*)(void*))freeAttr);
if (i == -EINVAL)
return ERR_INVARG;
/* try to receive any packets until timeout */
swiList = createEmptyList();
/* FIXME: end after timeout whatever received packet is good or not */
- while (recvNsdpPacket(nga, CODE_READ_REP, NULL, NULL, attr) >= 0) {
+ while (1) {
+ prepareRecv(nga, &nc, CODE_READ_REP);
+ if (recvNsdpPacket(nga->sock, &nc, attr, &nga->timeout) < 0)
+ break;
+
sa = malloc(sizeof(struct swi_attr));
if (sa == NULL)
return ERR_MEM;
+
extractSwitchAttributes(sa, attr);
clearList(attr, (void(*)(void*))freeAttr);
pushBackList(swiList, sa);
#include <ngadmin.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include "lib.h"
#include "network.h"
-noinst_HEADERS = attr.h encoding.h list.h misc.h protocol.h
+SUBDIRS = nsdp
+++ /dev/null
-
-#ifndef DEF_ATTR
-#define DEF_ATTR
-
-
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-
-#include <list.h>
-
-
-
-struct attr {
- unsigned short attr; /* attribute code */
- unsigned short size; /* attribute size */
- void *data; /* attribute data */
-};
-
-
-
-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);
-
-
-void filterAttributes (List *attr, ...);
-
-
-#endif
-
+++ /dev/null
-
-#ifndef DEF_ENCODING
-#define DEF_ENCODING
-
-
-#include <stdbool.h>
-
-#include <netinet/ether.h>
-
-#include <protocol.h>
-#include <list.h>
-
-
-struct nsdp_packet {
- union {
- unsigned char *buffer;
- struct nsdp_header *nh;
- };
- int maxlen;
- struct attr_header *ah;
-};
-
-
-
-void initNsdpHeader (struct nsdp_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum);
-
-
-bool validateNsdpHeader (const struct nsdp_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum);
-
-
-static inline void initNsdpPacket (struct nsdp_packet *np)
-{
- np->ah = (struct attr_header*)np->nh->data;
-}
-
-
-static inline int getPacketTotalSize (const struct nsdp_packet *np)
-{
- return ((unsigned char*)np->ah) - np->buffer;
-}
-
-
-int addPacketAttributes (struct nsdp_packet *np, const List* attr, unsigned char ports);
-
-
-int extractPacketAttributes (struct nsdp_packet *np, List *attr, unsigned char ports);
-
-
-#endif
-
+++ /dev/null
-
-#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*));
-
-//
-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*));
-
-// 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
-
+++ /dev/null
-
-#ifndef DEF_MISC
-#define DEF_MISC
-
-
-void passwordEndecode (char *buf, unsigned int len);
-
-
-int trim (char *txt, int start);
-
-
-static inline int min (int a, int b)
-{
- return a < b ? a : b;
-}
-
-
-#endif
-
--- /dev/null
+
+noinst_HEADERS = attr.h list.h misc.h net.h protocol.h
+
--- /dev/null
+
+#ifndef DEF_ATTR
+#define DEF_ATTR
+
+
+#include <stdlib.h>
+#include <arpa/inet.h>
+
+#include <nsdp/list.h>
+
+
+
+struct attr {
+ unsigned short attr; /* attribute code */
+ unsigned short size; /* attribute size */
+ void *data; /* attribute data */
+};
+
+
+
+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);
+
+
+void filterAttributes (List *attr, ...);
+
+
+#endif
+
--- /dev/null
+
+#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*));
+
+//
+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*));
+
+// 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
+
--- /dev/null
+
+#ifndef DEF_MISC
+#define DEF_MISC
+
+
+void passwordEndecode (char *buf, unsigned int len);
+
+
+int trim (char *txt, int start);
+
+
+static inline int min (int a, int b)
+{
+ return a < b ? a : b;
+}
+
+
+#endif
+
--- /dev/null
+
+#ifndef DEF_NET
+#define DEF_NET
+
+
+#include <time.h>
+#include <arpa/inet.h>
+#include <netinet/ether.h>
+
+#include <nsdp/list.h>
+
+
+struct nsdp_cmd {
+ struct ether_addr client_mac;
+ struct ether_addr switch_mac;
+ struct sockaddr_in remote_addr;
+ unsigned int seqnum;
+ unsigned int ports;
+ unsigned char code;
+ unsigned char error;
+ unsigned short attr_error;
+};
+
+
+
+int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr);
+
+
+int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timeval *timeout);
+
+
+#endif
+
--- /dev/null
+
+#ifndef DEF_PROTOCOL
+#define DEF_PROTOCOL
+
+
+#include <netinet/ether.h>
+
+
+#define CLIENT_PORT 63321
+#define SWITCH_PORT 63322
+
+#define NSDP_VERSION 1
+#define NSDP_PROTOID "NSDP"
+
+#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
+
+
+#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_ENCPASS 0x0014
+#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
+
+
+
+struct nsdp_header {
+ unsigned char version; /* always 1, maybe version */
+ unsigned 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 */
+ unsigned char unk2[2]; /* always 0, unknown */
+ unsigned char client_mac[ETH_ALEN]; /* client MAC address */
+ unsigned char switch_mac[ETH_ALEN]; /* switch MAC address */
+ unsigned int seqnum; /* sequence number */
+ unsigned char proto_id[4]; /* always "NSDP", maybe short for "Netgear Switch Description Protocol" */
+ unsigned char unk3[4]; /* always 0, unknown */
+ unsigned char data[0]; /* attributes data */
+} __attribute__((packed));
+
+
+struct attr_header {
+ unsigned short attr; /* attribute code */
+ unsigned short size; /* attribute data size */
+ unsigned char data[0]; /* attribute data */
+} __attribute__((packed));
+
+
+
+struct attr_port_status {
+ unsigned char port; /* port number */
+ unsigned char status; /* port status (speed index) */
+ unsigned char unk; /* unknown */
+} __attribute__((packed));
+
+
+struct attr_port_stat {
+ unsigned char port; /* port number */
+ unsigned long long recv; /* received bytes */
+ unsigned long long sent; /* sent bytes */
+ unsigned long long unk1; /* unknown */
+ unsigned long long unk2; /* unknown */
+ unsigned long long unk3; /* unknown */
+ unsigned long long crc; /* CRC errors */
+} __attribute__((packed));
+
+
+struct attr_bitrate {
+ unsigned char port; /* port number */
+ int bitrate; /* bitrate index */
+} __attribute__((packed));
+
+
+struct attr_qos {
+ unsigned char port; /* port number */
+ unsigned char prio; /* prio index */
+} __attribute__((packed));
+
+
+struct attr_pvid {
+ unsigned char port; /* port number */
+ unsigned short vlan; /* VLAN */
+} __attribute__((packed));
+
+
+struct attr_igmp_vlan {
+ unsigned short enable; /* IGMP filtering enabled */
+ unsigned short vlan; /* VLAN where IGMP packets are filtered */
+} __attribute__((packed));
+
+
+struct attr_cabletest_do {
+ unsigned char port; /* port number */
+ unsigned char action; /* action index */
+} __attribute__((packed));
+
+
+struct attr_cabletest_result {
+ unsigned char port; /* port number */
+ unsigned int v1; /* raw value 1 (values unknown yet) */
+ unsigned int v2; /* raw value 2 (values unknown yet) */
+} __attribute__((packed));
+
+
+/**
+ * Note: this structure is not sent "as-is" on the wire.
+ * A translation is done between the wire format (which uses somewhat not
+ * trivial bitmap) and this simpler format. See encoding_attr.c for more details.
+ */
+struct attr_vlan_conf {
+ unsigned short vlan; /* port number */
+ unsigned char ports[0]; /* array, maps each port to a VLAN */
+};
+
+
+#endif
+
+++ /dev/null
-
-#ifndef DEF_PROTOCOL
-#define DEF_PROTOCOL
-
-
-#include <netinet/ether.h>
-
-
-#define CLIENT_PORT 63321
-#define SWITCH_PORT 63322
-
-#define NSDP_VERSION 1
-#define NSDP_PROTOID "NSDP"
-
-#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
-
-
-#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_ENCPASS 0x0014
-#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
-
-
-
-struct nsdp_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]; /* attributes data */
-} __attribute__((packed));
-
-
-struct attr_header {
- unsigned short attr; /* attribute code */
- unsigned short size; /* attribute data size */
- char data[0]; /* attribute data */
-} __attribute__((packed));
-
-
-
-struct attr_port_status {
- unsigned char port; /* port number */
- unsigned char status; /* port status (speed index) */
- unsigned char unk; /* unknown */
-} __attribute__((packed));
-
-
-struct attr_port_stat {
- unsigned char port; /* port number */
- unsigned long long recv; /* received bytes */
- unsigned long long sent; /* sent bytes */
- unsigned long long unk1; /* unknown */
- unsigned long long unk2; /* unknown */
- unsigned long long unk3; /* unknown */
- unsigned long long crc; /* CRC errors */
-} __attribute__((packed));
-
-
-struct attr_bitrate {
- unsigned char port; /* port number */
- int bitrate; /* bitrate index */
-} __attribute__((packed));
-
-
-struct attr_qos {
- unsigned char port; /* port number */
- unsigned char prio; /* prio index */
-} __attribute__((packed));
-
-
-struct attr_pvid {
- unsigned char port; /* port number */
- unsigned short vlan; /* VLAN */
-} __attribute__((packed));
-
-
-struct attr_igmp_vlan {
- unsigned short enable; /* IGMP filtering enabled */
- unsigned short vlan; /* VLAN where IGMP packets are filtered */
-} __attribute__((packed));
-
-
-struct attr_cabletest_do {
- unsigned char port; /* port number */
- unsigned char action; /* action index */
-} __attribute__((packed));
-
-
-struct attr_cabletest_result {
- unsigned char port; /* port number */
- unsigned int v1; /* raw value 1 (values unknown yet) */
- unsigned int v2; /* raw value 2 (values unknown yet) */
-} __attribute__((packed));
-
-
-/**
- * Note: this structure is not sent "as-is" on the wire.
- * A translation is done between the wire format (which uses somewhat not
- * trivial bitmap) and this simpler format. See encoding.c for more details.
- */
-struct attr_vlan_conf {
- unsigned short vlan; /* port number */
- unsigned char ports[0]; /* array, maps each port to a VLAN */
-};
-
-
-#endif
-
noinst_LTLIBRARIES = librawnsdp.la
-librawnsdp_la_SOURCES = attr.c encoding.c encoding_attr.c list.c misc.c
+librawnsdp_la_SOURCES = attr.c encoding.c encoding_attr.c list.c misc.c net.c
librawnsdp_la_CPPFLAGS = -I$(top_srcdir)/raw/include/ -I$(top_srcdir)/lib/include/
librawnsdp_la_CFLAGS = -fno-strict-aliasing
#include <stdarg.h>
-#include <attr.h>
-#include <protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/protocol.h>
#include <string.h>
#include <errno.h>
-#include <attr.h>
-#include <encoding.h>
+#include <nsdp/attr.h>
+#include "encoding.h"
#include "encoding_attr.h"
-void initNsdpHeader (struct nsdp_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum)
+void initNsdpHeader (struct nsdp_header *nh, const struct nsdp_cmd *nc)
{
memset(nh, 0, sizeof(struct nsdp_header));
nh->version = NSDP_VERSION;
- nh->code = code;
+ nh->code = nc->code;
+ nh->error = nc->error;
+ nh->attr = htons(nc->attr_error);
- memcpy(nh->client_mac, client_mac, ETH_ALEN);
+ memcpy(nh->client_mac, &nc->client_mac, ETH_ALEN);
+ memcpy(nh->switch_mac, &nc->switch_mac, ETH_ALEN);
- if (switch_mac != NULL)
- memcpy(nh->switch_mac, switch_mac, ETH_ALEN);
-
- nh->seqnum = htonl(seqnum);
+ nh->seqnum = htonl(nc->seqnum);
memcpy(nh->proto_id, NSDP_PROTOID, 4);
}
-bool validateNsdpHeader (const struct nsdp_header *nh, char code, const struct ether_addr *client_mac, const struct ether_addr *switch_mac, unsigned int seqnum)
+bool validateNsdpHeader (const struct nsdp_header *nh, const struct nsdp_cmd *nc)
{
+ unsigned int i;
+
+
if (nh->version != NSDP_VERSION)
return false;
- if (code > 0 && nh->code != code)
+ if (nc->code > 0 && nh->code != nc->code)
return false;
if (nh->unk1 != 0)
if (*(unsigned short*)nh->unk2 != 0)
return false;
- if (client_mac != NULL && memcmp(nh->client_mac, client_mac, ETH_ALEN) != 0)
+ for (i = 0; i < ETH_ALEN && nc->client_mac.ether_addr_octet[i] == 0; i++);
+ if (i < ETH_ALEN && memcmp(nh->client_mac, &nc->client_mac, ETH_ALEN) != 0)
return false;
- if (switch_mac != NULL && memcmp(nh->switch_mac, switch_mac, ETH_ALEN) != 0)
+ for (i = 0; i < ETH_ALEN && nc->switch_mac.ether_addr_octet[i] == 0; i++);
+ if (i < ETH_ALEN && memcmp(nh->switch_mac, &nc->switch_mac, ETH_ALEN) != 0)
return false;
- if (seqnum > 0 && ntohl(nh->seqnum) != seqnum)
+ if (nc->seqnum > 0 && ntohl(nh->seqnum) != nc->seqnum)
return false;
if (memcmp(nh->proto_id, NSDP_PROTOID, 4) != 0)
--- /dev/null
+
+#ifndef DEF_ENCODING
+#define DEF_ENCODING
+
+
+#include <stdbool.h>
+
+#include <netinet/ether.h>
+
+#include <nsdp/protocol.h>
+#include <nsdp/net.h>
+#include <nsdp/list.h>
+
+
+struct nsdp_packet {
+ union {
+ unsigned char *buffer;
+ struct nsdp_header *nh;
+ };
+ int maxlen;
+ struct attr_header *ah;
+};
+
+
+
+void initNsdpHeader (struct nsdp_header *nh, const struct nsdp_cmd *nc);
+
+
+bool validateNsdpHeader (const struct nsdp_header *nh, const struct nsdp_cmd *nc);
+
+
+static inline void initNsdpPacket (struct nsdp_packet *np)
+{
+ np->ah = (struct attr_header*)np->nh->data;
+}
+
+
+static inline int getPacketTotalSize (const struct nsdp_packet *np)
+{
+ return ((unsigned char*)np->ah) - np->buffer;
+}
+
+
+int addPacketAttributes (struct nsdp_packet *np, const List* attr, unsigned char ports);
+
+
+int extractPacketAttributes (struct nsdp_packet *np, List *attr, unsigned char ports);
+
+
+#endif
+
#include <ngadmin.h> /* FIXME */
-#include <protocol.h>
+#include <nsdp/protocol.h>
#include "encoding_attr.h"
#include <stdbool.h>
-#include <attr.h>
+#include <nsdp/attr.h>
-#include "list.h"
+#include <nsdp/list.h>
#include <stdlib.h>
-#include <misc.h>
+#include <nsdp/misc.h>
static const char passwordKey[] = "NtgrSmartSwitchRock";
--- /dev/null
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <nsdp/net.h>
+#include "encoding.h"
+
+
+int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr)
+{
+ unsigned char buffer[1500];
+ struct nsdp_packet np;
+ int ret;
+
+
+ if (sock < 0 || nc == NULL)
+ return -EINVAL;
+
+ np.buffer = buffer;
+ np.maxlen = sizeof(buffer);
+ initNsdpPacket(&np);
+ initNsdpHeader(np.nh, nc);
+
+ ret = addPacketAttributes(&np, attr, nc->ports);
+ if (ret < 0)
+ return ret;
+
+ ret = sendto(sock, buffer, getPacketTotalSize(&np), 0, (struct sockaddr*)&nc->remote_addr, sizeof(struct sockaddr_in));
+ if (ret < 0)
+ perror("sendto");
+
+
+ return ret;
+}
+
+
+int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timeval *timeout)
+{
+ unsigned char buffer[1500];
+ struct nsdp_packet np;
+ socklen_t slen = sizeof(struct sockaddr_in);
+ struct timeval rem;
+ fd_set fs;
+ int len = -1;
+ struct sockaddr_in remote;
+
+
+ if (sock < 0 || nc == NULL || attr == NULL)
+ return -EINVAL;
+
+ np.buffer = buffer;
+
+ if (timeout != NULL)
+ rem = *timeout;
+
+ memset(&remote, 0, sizeof(struct sockaddr_in));
+ remote.sin_family = AF_INET;
+
+ while (1) {
+ FD_ZERO(&fs);
+ FD_SET(sock, &fs);
+ select(sock + 1, &fs, NULL, NULL, timeout == NULL ? NULL : &rem); /* FIXME: non portable */
+
+ len = recvfrom(sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
+ if (len < 0)
+ break;
+
+ np.maxlen = len;
+ initNsdpPacket(&np);
+
+ if ((nc->remote_addr.sin_addr.s_addr != 0 && remote.sin_addr.s_addr != nc->remote_addr.sin_addr.s_addr) ||
+ (nc->remote_addr.sin_port != 0 && remote.sin_port != nc->remote_addr.sin_port) ||
+ len < (int)sizeof(struct nsdp_header) ||
+ !validateNsdpHeader(np.nh, nc) ||
+ extractPacketAttributes(&np, attr, nc->ports) < 0)
+ continue;
+
+ nc->remote_addr = remote;
+
+ nc->code = np.nh->code;
+ nc->error = np.nh->error;
+ nc->attr_error = ntohs(np.nh->attr);
+
+ len = 0;
+ break;
+ }
+
+
+ return len;
+}
+
+
#include <unistd.h>
#include <arpa/inet.h>
-#include <attr.h>
-#include <encoding.h>
+#include <nsdp/protocol.h>
+#include <nsdp/attr.h>
+#include <nsdp/net.h>
int main (void)
{
- unsigned char buffer[1500];
- struct nsdp_packet np;
- int err = 0, s, len;
- struct sockaddr_in local, remote;
- socklen_t slen = sizeof(struct sockaddr_in);
- unsigned char error;
- unsigned short attr_error;
+ int err = 0, s;
List *attr;
ListNode *ln;
struct attr *at;
+ struct nsdp_cmd nc;
+ struct sockaddr_in local;
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
};
+ memset(&nc, 0, sizeof(struct nsdp_cmd));
+ nc.remote_addr.sin_family = AF_INET;
+ nc.remote_addr.sin_port = htons(CLIENT_PORT);
+
memset(&local, 0, sizeof(struct sockaddr_in));
local.sin_family = AF_INET;
local.sin_addr.s_addr = htonl(INADDR_ANY);
}
while (1) {
-
- len = recvfrom(s, buffer, sizeof(buffer), 0, (struct sockaddr*)&remote, &slen);
- if (len < 0) {
- perror("recvfrom");
- err = 3;
- goto end;
- }
-
- printf("---------------------------------\n");
-
- np.buffer = buffer;
- np.maxlen = len;
- initNsdpPacket(&np);
-
attr = createEmptyList();
+ recvNsdpPacket(s, &nc, attr, NULL);
- if (ntohs(remote.sin_port) != CLIENT_PORT ||
- len < (int)sizeof(struct nsdp_header) ||
- !validateNsdpHeader(np.nh, 0, NULL, NULL, 0) ||
- extractPacketAttributes(&np, attr, 0) < 0) {
- printf("wrong packet\n");
- goto end;
- }
+ printf("---------------------------------\n");
printf("received %d attribute(s)\n", attr->count);