diff --git a/cli/man/ngcli.1 b/cli/man/ngcli.1 index 66101c2..71c02a6 100644 --- a/cli/man/ngcli.1 +++ b/cli/man/ngcli.1 @@ -1,4 +1,4 @@ -.TH NGCLI "1" "October 2013" "NgAdmin 0.1" "User Commands" +.TH NGCLI "1" "September 2014" "NgAdmin 0.1" "User Commands" .SH NAME ngcli \- command line interface tool for GS10[58]E administration . @@ -154,6 +154,18 @@ switches. This command delogs from the current switch, whether the login attempt is successful or not. . .TP +\fBloop disable +Disable loop detection. +. +.TP +\fBloop enable +Enable loop detection. +. +.TP +\fBloop show +Show loop detection configuration. +. +.TP \fBmirror disable Disable port mirroring. . diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index c756408..b23cedd 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -3,9 +3,10 @@ bin_PROGRAMS = ngcli noinst_HEADERS = commands.h common.h ngcli_SOURCES = admin.c com_bitrate.c com_cabletest.c com_defaults.c com_firmware.c \ - com_help.c com_igmp.c com_list.c com_login.c commands.c com_mirror.c \ - common.c com_name.c com_netconf.c com_password.c com_ports.c com_qos.c \ - com_quit.c com_restart.c com_scan.c com_stormfilter.c com_tree.c com_vlan.c + com_help.c com_igmp.c com_list.c com_login.c com_loop.c commands.c \ + com_mirror.c common.c com_name.c com_netconf.c com_password.c \ + com_ports.c com_qos.c com_quit.c com_restart.c com_scan.c \ + com_stormfilter.c com_tree.c com_vlan.c ngcli_CPPFLAGS = -I$(top_srcdir)/raw/include/ -I$(top_srcdir)/lib/include/ ngcli_LDADD = $(top_builddir)/raw/src/librawnsdp.la $(top_builddir)/lib/src/libngadmin.la $(READLINE_LIBS) diff --git a/cli/src/com_loop.c b/cli/src/com_loop.c new file mode 100644 index 0000000..45c4acd --- /dev/null +++ b/cli/src/com_loop.c @@ -0,0 +1,69 @@ + +#include "commands.h" + + +int do_loop_enable (int argc, const char **argv UNUSED, struct ngadmin *nga) +{ + int i; + + + if (argc > 0) { + printf("this command takes no argument\n"); + return 1; + } + + i = ngadmin_setLoopDetectionState(nga, 1); + printErrCode(i); + + + return 0; +} + + +int do_loop_disable (int argc, const char **argv UNUSED, struct ngadmin *nga) +{ + int i; + + + if (argc > 0) { + printf("this command takes no argument\n"); + return 1; + } + + i = ngadmin_setLoopDetectionState(nga, 0); + printErrCode(i); + + + return 0; +} + + +int do_loop_show (int argc, const char **argv UNUSED, struct ngadmin *nga) +{ + int i, s; + const struct swi_attr *sa; + + + if (argc > 0) { + printf("this command takes no argument\n"); + return 1; + } + + sa = ngadmin_getCurrentSwitch(nga); + if (sa == NULL) { + printf("must be logged\n"); + return 1; + } + + i = ngadmin_getLoopDetectionState(nga, &s); + if (i != ERR_OK) { + printErrCode(i); + return 1; + } + + printf("loop detection is %s\n", s ? "enabled" : "disabled"); + + return 0; +} + + diff --git a/cli/src/commands.c b/cli/src/commands.c index 7662c72..df4c93d 100644 --- a/cli/src/commands.c +++ b/cli/src/commands.c @@ -37,6 +37,12 @@ int do_list (int argc, const char **argv, struct ngadmin *nga); int do_login (int argc, const char **argv, struct ngadmin *nga); +/* loop */ +int do_loop_enable (int argc, const char **argv, struct ngadmin *nga); +int do_loop_disable (int argc, const char **argv, struct ngadmin *nga); +int do_loop_show (int argc, const char **argv, struct ngadmin *nga); + + /* mirror */ int do_mirror_disable (int argc, const char **argv, struct ngadmin *nga); int do_mirror_set (int argc, const char **argv, struct ngadmin *nga); @@ -133,6 +139,12 @@ COM_ROOT_START(commands) COM_TERM(login, do_login) + COM_START(loop) + COM_TERM(disable, do_loop_disable) + COM_TERM(enable, do_loop_enable) + COM_TERM(show, do_loop_show) + COM_END + COM_START(mirror) COM_TERM(disable, do_mirror_disable) COM_TERM(set, do_mirror_set) diff --git a/lib/include/ngadmin.h b/lib/include/ngadmin.h index 50fffa9..a7e17de 100644 --- a/lib/include/ngadmin.h +++ b/lib/include/ngadmin.h @@ -807,6 +807,28 @@ int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports); int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vlan); +/** + * Get the loop detection state. + * Retrieves the loop detection state. + * @note You must be logged on a switch. + * @param nga A pointer to the ngadmin structure. + * @param s A pointer to an integer which will receive 0 or 1. + * @return ERR_OK when everything is well or an error code otherwise. + **/ +int ngadmin_getLoopDetectionState (struct ngadmin *nga, int *s); + + +/** + * Set the loop detection state. + * Changes the loop detection state. + * @note You must be logged on a switch. + * @param nga A pointer to the ngadmin structure. + * @param s An integer with value 0 or 1. + * @return ERR_OK when everything is well or an error code otherwise. + **/ +int ngadmin_setLoopDetectionState (struct ngadmin *nga, int s); + + #ifdef __cplusplus } #endif diff --git a/lib/src/ports.c b/lib/src/ports.c index 8804e4b..99f8b48 100644 --- a/lib/src/ports.c +++ b/lib/src/ports.c @@ -184,3 +184,59 @@ int ngadmin_cabletest (struct ngadmin *nga, struct cabletest *ct, int nb) } +int ngadmin_getLoopDetectionState (struct ngadmin *nga, int *s) +{ + List *attr; + ListNode *ln; + struct attr *at; + int ret = ERR_OK; + + + if (nga == NULL || s == NULL) + return ERR_INVARG; + else if (nga->current == NULL) + return ERR_NOTLOG; + + attr = createEmptyList(); + pushBackList(attr, newEmptyAttr(ATTR_LOOP_DETECT)); + ret = readRequest(nga, attr); + if (ret != ERR_OK) + goto end; + + filterAttributes(attr, ATTR_LOOP_DETECT, ATTR_END); + + *s = 0; + + if (attr->first == NULL) { + ret = ERR_BADREPLY; + goto end; + } + at = attr->first->data; + if (at->size != 1) { + ret = ERR_BADREPLY; + goto end; + } + *s = *(char *)at->data; + + +end: + destroyList(attr, (void(*)(void*))freeAttr); + + + return ret; +} + + +int ngadmin_setLoopDetectionState (struct ngadmin *nga, int s) +{ + List *attr; + + + attr = createEmptyList(); + pushBackList(attr, newByteAttr(ATTR_LOOP_DETECT, s != 0)); + + + return writeRequest(nga, attr); +} + + diff --git a/raw/include/nsdp/protocol.h b/raw/include/nsdp/protocol.h index def40c4..70d111e 100644 --- a/raw/include/nsdp/protocol.h +++ b/raw/include/nsdp/protocol.h @@ -66,6 +66,7 @@ #define ATTR_IGMP_BLOCK_UNK 0x6C00 #define ATTR_IGMP_VALID_V3 0x7000 #define ATTR_TLV_BITMAP 0x7400 +#define ATTR_LOOP_DETECT 0x9000 #define ATTR_END 0xFFFF diff --git a/raw/src/attr.c b/raw/src/attr.c index fca3c32..3d0e4c9 100644 --- a/raw/src/attr.c +++ b/raw/src/attr.c @@ -549,6 +549,7 @@ static int processAttr (struct attr *at, bool encode) case ATTR_STORM_ENABLE: case ATTR_IGMP_BLOCK_UNK: case ATTR_IGMP_VALID_V3: + case ATTR_LOOP_DETECT: if (at->size != 1) return -EMSGSIZE; diff --git a/spy/src/spy.c b/spy/src/spy.c index 7c842cc..69c89fa 100644 --- a/spy/src/spy.c +++ b/spy/src/spy.c @@ -267,6 +267,10 @@ static void print_attr (const struct attr *at) printf("\tvalidate IGMPv3 = %s\n", *byte ? "yes" : "no"); break; + case ATTR_LOOP_DETECT: + printf("\tloop detection = %s\n", *byte ? "yes" : "no"); + break; + default: printf("\tunknown\n"); } diff --git a/wireshark/nsdp.lua b/wireshark/nsdp.lua index 6703a21..08caca8 100644 --- a/wireshark/nsdp.lua +++ b/wireshark/nsdp.lua @@ -225,6 +225,7 @@ local attributes = { [0x6C00] = {name = "Block Unknown IGMP Addresses", dissect = "uint"}, [0x7000] = {name = "Validate IGMPv3 Headers", dissect = "uint"}, [0x7400] = {name = "TLV Bitmap", dissect = nill}, + [0x9000] = {name = "Loop Detection", dissect = "uint"}, [0xFFFF] = {name = "End", dissect = nill} }