From 16cbdbc11750bc2f42fe44ee750228db657afbeb Mon Sep 17 00:00:00 2001 From: darkcoven Date: Fri, 11 Oct 2013 23:01:41 +0200 Subject: [PATCH 1/1] Move basic networking code to raw library --- .gitignore | 1 + configure.ac | 1 + lib/src/bitrate.c | 4 +- lib/src/firmware.c | 4 +- lib/src/libconf.c | 4 +- lib/src/mirror.c | 4 +- lib/src/misc.c | 5 +- lib/src/netconf.c | 4 +- lib/src/network.c | 166 ++++++++++++------------------ lib/src/network.h | 7 +- lib/src/ports.c | 4 +- lib/src/qos.c | 4 +- lib/src/session.c | 15 ++- lib/src/vlan.c | 4 +- raw/include/Makefile.am | 2 +- raw/include/nsdp/Makefile.am | 3 + raw/include/{ => nsdp}/attr.h | 3 +- raw/include/{ => nsdp}/list.h | 0 raw/include/{ => nsdp}/misc.h | 0 raw/include/nsdp/net.h | 33 ++++++ raw/include/{ => nsdp}/protocol.h | 28 ++--- raw/src/Makefile.am | 2 +- raw/src/attr.c | 4 +- raw/src/encoding.c | 33 +++--- raw/{include => src}/encoding.h | 9 +- raw/src/encoding_attr.c | 2 +- raw/src/encoding_attr.h | 2 +- raw/src/list.c | 2 +- raw/src/misc.c | 2 +- raw/src/net.c | 92 +++++++++++++++++ spy/src/spy.c | 42 +++----- 31 files changed, 291 insertions(+), 195 deletions(-) create mode 100644 raw/include/nsdp/Makefile.am rename raw/include/{ => nsdp}/attr.h (98%) rename raw/include/{ => nsdp}/list.h (100%) rename raw/include/{ => nsdp}/misc.h (100%) create mode 100644 raw/include/nsdp/net.h rename raw/include/{ => nsdp}/protocol.h (80%) rename raw/{include => src}/encoding.h (64%) create mode 100644 raw/src/net.c 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/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/attr.h b/raw/include/nsdp/attr.h similarity index 98% rename from raw/include/attr.h rename to raw/include/nsdp/attr.h index 24fa023..75ce384 100644 --- a/raw/include/attr.h +++ b/raw/include/nsdp/attr.h @@ -4,10 +4,9 @@ #include - #include -#include +#include diff --git a/raw/include/list.h b/raw/include/nsdp/list.h similarity index 100% rename from raw/include/list.h rename to raw/include/nsdp/list.h diff --git a/raw/include/misc.h b/raw/include/nsdp/misc.h similarity index 100% rename from raw/include/misc.h rename to raw/include/nsdp/misc.h 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/protocol.h b/raw/include/nsdp/protocol.h similarity index 80% rename from raw/include/protocol.h rename to raw/include/nsdp/protocol.h index 297a663..a785e2c 100644 --- a/raw/include/protocol.h +++ b/raw/include/nsdp/protocol.h @@ -69,25 +69,25 @@ 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 */ + 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 */ - char data[0]; /* attribute data */ + unsigned char data[0]; /* attribute data */ } __attribute__((packed)); @@ -150,7 +150,7 @@ struct attr_cabletest_result { /** * 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. + * trivial bitmap) and this simpler format. See encoding_attr.c for more details. */ struct attr_vlan_conf { unsigned short vlan; /* port number */ 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/include/encoding.h b/raw/src/encoding.h similarity index 64% rename from raw/include/encoding.h rename to raw/src/encoding.h index 1c21939..5c42e60 100644 --- a/raw/include/encoding.h +++ b/raw/src/encoding.h @@ -7,8 +7,9 @@ #include -#include -#include +#include +#include +#include struct nsdp_packet { @@ -22,10 +23,10 @@ struct nsdp_packet { -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); -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); static inline void initNsdpPacket (struct nsdp_packet *np) 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); -- 2.39.2