From: darkcoven Date: Fri, 11 Oct 2013 21:01:41 +0000 (+0200) Subject: Move basic networking code to raw library X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=16cbdbc11750bc2f42fe44ee750228db657afbeb;p=ngadmin Move basic networking code to raw library --- diff --git a/.gitignore b/.gitignore index 0c133cb..e4c652d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.so *.a *.la +*.orig *.pc ngcli ngspy diff --git a/configure.ac b/configure.ac index 3dce523..8a06021 100644 --- a/configure.ac +++ b/configure.ac @@ -93,6 +93,7 @@ AC_CONFIG_FILES([ Makefile raw/Makefile raw/include/Makefile + raw/include/nsdp/Makefile raw/src/Makefile lib/Makefile lib/include/Makefile diff --git a/lib/src/bitrate.c b/lib/src/bitrate.c index f9fa11d..50dfb76 100644 --- a/lib/src/bitrate.c +++ b/lib/src/bitrate.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/firmware.c b/lib/src/firmware.c index 351678b..efe9ad8 100644 --- a/lib/src/firmware.c +++ b/lib/src/firmware.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/libconf.c b/lib/src/libconf.c index 62cb6ff..f94fcca 100644 --- a/lib/src/libconf.c +++ b/lib/src/libconf.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/mirror.c b/lib/src/mirror.c index 7fe51cb..daa7f47 100644 --- a/lib/src/mirror.c +++ b/lib/src/mirror.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/misc.c b/lib/src/misc.c index 4da6812..39abde3 100644 --- a/lib/src/misc.c +++ b/lib/src/misc.c @@ -1,8 +1,9 @@ #include -#include -#include +#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/netconf.c b/lib/src/netconf.c index 0a804b7..9349772 100644 --- a/lib/src/netconf.c +++ b/lib/src/netconf.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/network.c b/lib/src/network.c index ee40862..09dcd60 100644 --- a/lib/src/network.c +++ b/lib/src/network.c @@ -9,9 +9,10 @@ #include #include -#include -#include -#include +#include +#include +#include +#include #include "network.h" @@ -160,114 +161,78 @@ int updateTimeout (struct ngadmin *nga) } -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) { @@ -278,25 +243,28 @@ int readRequest (struct ngadmin *nga, List *attr) /* 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: @@ -307,9 +275,8 @@ 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) { @@ -333,25 +300,28 @@ int writeRequest (struct ngadmin *nga, List *attr) /* 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: diff --git a/lib/src/network.h b/lib/src/network.h index 5295a52..58b643d 100644 --- a/lib/src/network.h +++ b/lib/src/network.h @@ -3,7 +3,8 @@ #define DEF_NETWORK -#include "list.h" +#include +#include #include "lib.h" @@ -22,10 +23,10 @@ int forceInterface (struct ngadmin *nga); 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); diff --git a/lib/src/ports.c b/lib/src/ports.c index 25ce18d..0b4afc2 100644 --- a/lib/src/ports.c +++ b/lib/src/ports.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/qos.c b/lib/src/qos.c index cecfaf0..553c878 100644 --- a/lib/src/qos.c +++ b/lib/src/qos.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/lib/src/session.c b/lib/src/session.c index c36c772..43da030 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -3,8 +3,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" @@ -15,6 +15,7 @@ int ngadmin_scan (struct ngadmin *nga) int i; List *attr, *swiList; struct swi_attr *sa; + struct nsdp_cmd nc; /* sent by official win client: ATTR_PRODUCT, @@ -64,7 +65,8 @@ int ngadmin_scan (struct ngadmin *nga) } /* 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; @@ -74,10 +76,15 @@ int ngadmin_scan (struct ngadmin *nga) /* try to receive any packets until timeout */ swiList = createEmptyList(); /* FIXME: end after timeout whatever received packet is good or not */ - while (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); diff --git a/lib/src/vlan.c b/lib/src/vlan.c index 2e6b2f6..2d3d536 100644 --- a/lib/src/vlan.c +++ b/lib/src/vlan.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" diff --git a/raw/include/Makefile.am b/raw/include/Makefile.am index 307afdf..42d467e 100644 --- a/raw/include/Makefile.am +++ b/raw/include/Makefile.am @@ -1,3 +1,3 @@ -noinst_HEADERS = attr.h encoding.h list.h misc.h protocol.h +SUBDIRS = nsdp diff --git a/raw/include/attr.h b/raw/include/attr.h deleted file mode 100644 index 24fa023..0000000 --- a/raw/include/attr.h +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef DEF_ATTR -#define DEF_ATTR - - -#include - -#include - -#include - - - -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 - diff --git a/raw/include/encoding.h b/raw/include/encoding.h deleted file mode 100644 index 1c21939..0000000 --- a/raw/include/encoding.h +++ /dev/null @@ -1,50 +0,0 @@ - -#ifndef DEF_ENCODING -#define DEF_ENCODING - - -#include - -#include - -#include -#include - - -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 - diff --git a/raw/include/list.h b/raw/include/list.h deleted file mode 100644 index 9dc9d34..0000000 --- a/raw/include/list.h +++ /dev/null @@ -1,74 +0,0 @@ - -#ifndef DEF_LIST -#define DEF_LIST - - -#include -#include -#include - -#ifdef MT_SAFE_LIST -#include -#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 - diff --git a/raw/include/misc.h b/raw/include/misc.h deleted file mode 100644 index 6aaa412..0000000 --- a/raw/include/misc.h +++ /dev/null @@ -1,19 +0,0 @@ - -#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 - diff --git a/raw/include/nsdp/Makefile.am b/raw/include/nsdp/Makefile.am new file mode 100644 index 0000000..c2c9d40 --- /dev/null +++ b/raw/include/nsdp/Makefile.am @@ -0,0 +1,3 @@ + +noinst_HEADERS = attr.h list.h misc.h net.h protocol.h + diff --git a/raw/include/nsdp/attr.h b/raw/include/nsdp/attr.h new file mode 100644 index 0000000..75ce384 --- /dev/null +++ b/raw/include/nsdp/attr.h @@ -0,0 +1,77 @@ + +#ifndef DEF_ATTR +#define DEF_ATTR + + +#include +#include + +#include + + + +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 + diff --git a/raw/include/nsdp/list.h b/raw/include/nsdp/list.h new file mode 100644 index 0000000..9dc9d34 --- /dev/null +++ b/raw/include/nsdp/list.h @@ -0,0 +1,74 @@ + +#ifndef DEF_LIST +#define DEF_LIST + + +#include +#include +#include + +#ifdef MT_SAFE_LIST +#include +#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 + diff --git a/raw/include/nsdp/misc.h b/raw/include/nsdp/misc.h new file mode 100644 index 0000000..6aaa412 --- /dev/null +++ b/raw/include/nsdp/misc.h @@ -0,0 +1,19 @@ + +#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 + diff --git a/raw/include/nsdp/net.h b/raw/include/nsdp/net.h new file mode 100644 index 0000000..4e2dbb5 --- /dev/null +++ b/raw/include/nsdp/net.h @@ -0,0 +1,33 @@ + +#ifndef DEF_NET +#define DEF_NET + + +#include +#include +#include + +#include + + +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 + diff --git a/raw/include/nsdp/protocol.h b/raw/include/nsdp/protocol.h new file mode 100644 index 0000000..a785e2c --- /dev/null +++ b/raw/include/nsdp/protocol.h @@ -0,0 +1,162 @@ + +#ifndef DEF_PROTOCOL +#define DEF_PROTOCOL + + +#include + + +#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 + diff --git a/raw/include/protocol.h b/raw/include/protocol.h deleted file mode 100644 index 297a663..0000000 --- a/raw/include/protocol.h +++ /dev/null @@ -1,162 +0,0 @@ - -#ifndef DEF_PROTOCOL -#define DEF_PROTOCOL - - -#include - - -#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 - diff --git a/raw/src/Makefile.am b/raw/src/Makefile.am index df23edf..f7f9b1f 100644 --- a/raw/src/Makefile.am +++ b/raw/src/Makefile.am @@ -1,7 +1,7 @@ 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 diff --git a/raw/src/attr.c b/raw/src/attr.c index b83598a..c8f2fcc 100644 --- a/raw/src/attr.c +++ b/raw/src/attr.c @@ -1,8 +1,8 @@ #include -#include -#include +#include +#include diff --git a/raw/src/encoding.c b/raw/src/encoding.c index 9fe4b70..5ac97d8 100644 --- a/raw/src/encoding.c +++ b/raw/src/encoding.c @@ -2,34 +2,37 @@ #include #include -#include -#include +#include +#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) @@ -38,13 +41,15 @@ bool validateNsdpHeader (const struct nsdp_header *nh, char code, const struct e 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) diff --git a/raw/src/encoding.h b/raw/src/encoding.h new file mode 100644 index 0000000..5c42e60 --- /dev/null +++ b/raw/src/encoding.h @@ -0,0 +1,51 @@ + +#ifndef DEF_ENCODING +#define DEF_ENCODING + + +#include + +#include + +#include +#include +#include + + +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 + diff --git a/raw/src/encoding_attr.c b/raw/src/encoding_attr.c index 19f7208..acb706f 100644 --- a/raw/src/encoding_attr.c +++ b/raw/src/encoding_attr.c @@ -1,6 +1,6 @@ #include /* FIXME */ -#include +#include #include "encoding_attr.h" diff --git a/raw/src/encoding_attr.h b/raw/src/encoding_attr.h index a3cb18b..ba6146c 100644 --- a/raw/src/encoding_attr.h +++ b/raw/src/encoding_attr.h @@ -5,7 +5,7 @@ #include -#include +#include diff --git a/raw/src/list.c b/raw/src/list.c index 52b6d45..56cde4a 100644 --- a/raw/src/list.c +++ b/raw/src/list.c @@ -1,5 +1,5 @@ -#include "list.h" +#include diff --git a/raw/src/misc.c b/raw/src/misc.c index 58db4aa..2ccec49 100644 --- a/raw/src/misc.c +++ b/raw/src/misc.c @@ -1,7 +1,7 @@ #include -#include +#include static const char passwordKey[] = "NtgrSmartSwitchRock"; diff --git a/raw/src/net.c b/raw/src/net.c new file mode 100644 index 0000000..cc619ef --- /dev/null +++ b/raw/src/net.c @@ -0,0 +1,92 @@ + +#include +#include + +#include +#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; +} + + diff --git a/spy/src/spy.c b/spy/src/spy.c index 074f919..a2c686e 100644 --- a/spy/src/spy.c +++ b/spy/src/spy.c @@ -3,22 +3,19 @@ #include #include -#include -#include +#include +#include +#include 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); @@ -29,6 +26,10 @@ int main (void) }; + 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); @@ -41,29 +42,10 @@ int main (void) } 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);