diff --git a/libcw.project b/libcw.project
index e928bb53..7595c1e3 100644
--- a/libcw.project
+++ b/libcw.project
@@ -276,6 +276,8 @@
+
+
diff --git a/src/ac/conf.c b/src/ac/conf.c
index fb4827ea..291e37b2 100644
--- a/src/ac/conf.c
+++ b/src/ac/conf.c
@@ -27,6 +27,7 @@
#include "cw/log.h"
#include "cw/dbg.h"
#include "cw/cw_util.h"
+#include "cw/dtls.h"
#include "conf.h"
diff --git a/src/ac/config.ktv b/src/ac/config.ktv
index 85bb0021..0eccc6d0 100644
--- a/src/ac/config.ktv
+++ b/src/ac/config.ktv
@@ -1,9 +1,7 @@
-capwap/ac-descriptor/hardware/version:Bstr16: "ACTube 1.0"
-capwap/ac-descriptor/hardware/vendor:Bastr16: 12346
-capwap/ssl-cert:Str: "/usr/local/etc/ssl/tube.ssl"
-capwap/ssl-key:Str: "/usr/local/etc/key"
-capwap/ssl-dhbits:Word: 2048
+#
+capwap/ac-descriptor/hardware/version:Bstr16: "ACTube 1.0"
+capwap/ac-descriptor/hardware/vendor:Bstr16: 12346
ac-descriptor/stations:Word:05
ac-descriptor/station-limit:Word:6
ac-descriptor/active-wtps:Word:7
@@ -23,11 +21,21 @@ capwap-control-ip-address/wtps.0:Word:0
#capwap-control-ip-address/wtps.1:Word:11
-capwap/ssl-keyfile:Str:"../../ssl/certs/ac-cisco.key"
-capwap/ssl-certfile:Str:"../../ssl/certs/ac-cisco.pem"
-capwap/ssl-cipher:Str:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1
-#capwap/ssl-psk:Str:"HalloWelt"
+#capwap/ssl-keyfile:Str:"../../ssl/certs/ac-cisco.key"
+#capwap/ssl-certfile:Str:"../../ssl/certs/ac-cisco.pem"
+
+capwap/ssl-cipher:Str:+DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
+capwap/ssl-psk-enable:Bool:true
+capwap/ssl-psk:Bstr16:"HalloWelt"
+capwap/ssl-dhbits:Word: 64
-actube/listen::192.168.0.1
+psk:Bstr16:1234
+psk/ap1:Bstr16:hallo
+
+#capwap/ssl-psk:Str:HalloWelt1
+
+
+
+actube/listen:Bstr16:192.168.0.1
diff --git a/src/cw/bstr.h b/src/cw/bstr.h
index 2feff0ca..70f61142 100644
--- a/src/cw/bstr.h
+++ b/src/cw/bstr.h
@@ -139,7 +139,7 @@ static inline int bstr16_ncpy(uint8_t *dst,uint8_t*src,uint16_t len)
*/
-extern uint8_t * bstr16_create(const uint8_t *data, uint16_t len);
+bstr16_t bstr16_create(const uint8_t *data, uint16_t len);
uint8_t * bstr16_create_from_str(const char *s);
extern uint8_t * bstr16_create_from_cfgstr(const char * s);
diff --git a/src/cw/bstr16_create.c b/src/cw/bstr16_create.c
index 4738e1b1..2631570d 100644
--- a/src/cw/bstr16_create.c
+++ b/src/cw/bstr16_create.c
@@ -1,6 +1,6 @@
#include "bstr.h"
-uint8_t * bstr16_create(const uint8_t *data, uint16_t len)
+bstr16_t bstr16_create(const uint8_t *data, uint16_t len)
{
uint8_t * str = malloc(2+len*sizeof(uint8_t));
if (!str)
@@ -10,4 +10,3 @@ uint8_t * bstr16_create(const uint8_t *data, uint16_t len)
return str;
}
-
diff --git a/src/cw/conn.h b/src/cw/conn.h
index d5f42fa5..d55291eb 100644
--- a/src/cw/conn.h
+++ b/src/cw/conn.h
@@ -175,9 +175,11 @@ struct conn {
int (*dtls_start) (struct conn *);
int (*dtls_accept) (struct conn *);
- char *dtls_psk;
- int dtls_psk_len;
+ bstr16_t dtls_psk;
+ int dtls_psk_enable;
+
int dtls_dhbits;
+ int (*dtls_get_psk)(struct conn *,const char *user,uint8_t**psk, int *len);
struct cw_Mod *cmod, *bmod;
diff --git a/src/cw/cw.h b/src/cw/cw.h
index 2bee16c9..f5b0078e 100644
--- a/src/cw/cw.h
+++ b/src/cw/cw.h
@@ -502,7 +502,7 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout);
char *cw_strdup(const char *s);
-int cw_strcicmp(char const *a, char const *b);
+int cw_stricmp(char const *a, char const *b);
/**
diff --git a/src/cw/cw_setup_dtls.c b/src/cw/cw_setup_dtls.c
index 8968da64..7a34725c 100644
--- a/src/cw/cw_setup_dtls.c
+++ b/src/cw/cw_setup_dtls.c
@@ -1,4 +1,30 @@
#include "cw.h"
+
+
+
+static int get_psk(struct conn * conn,const char * username, uint8_t **psk, unsigned int *len)
+{
+ char key[CW_KTV_MAX_KEY_LEN];
+ cw_KTV_t * result;
+ sprintf(key,"%s/%s","psk",username);
+ result = cw_ktv_get(conn->local_cfg,key,CW_TYPE_BSTR16);
+ if (result == NULL){
+ if (conn->dtls_psk != NULL){
+ *psk = bstr16_data(conn->dtls_psk);
+ *len = bstr16_len(conn->dtls_psk);
+ return 1;
+ }
+ return 0;
+ }
+
+ if (result == NULL)
+ return 0;
+ *psk = result->type->data(result);
+ *len = result->type->len(result);
+ return 1;
+}
+
+
/**
* @brief Setup DTLS parameters from config
* @param conn
@@ -10,7 +36,7 @@
int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * default_cipher)
{
char key[CW_KTV_MAX_KEY_LEN];
- char *ssl_psk,*ssl_cert,*ssl_key;
+ char *ssl_cert,*ssl_key;
uint8_t security;
security = 0;
@@ -18,13 +44,18 @@ int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * de
sprintf(key,"%s/%s",prefix,"ssl-cipher");
conn->dtls_cipher = cw_ktv_get_str(cfg,key, default_cipher);
+
sprintf(key,"%s/%s",prefix,"ssl-psk");
- ssl_psk = cw_ktv_get_str(cfg,key,NULL);
- if (ssl_psk != NULL){
- conn->dtls_psk=ssl_psk;
- conn->dtls_psk_len=strlen(ssl_psk);
+ conn->dtls_psk = cw_ktv_get_bstr16(cfg,key,NULL);
+
+ sprintf(key,"%s/%s",prefix,"ssl-psk-enable");
+ conn->dtls_psk_enable = cw_ktv_get_bool(cfg,key,0);
+
+ if (conn->dtls_psk_enable ){
security |= CAPWAP_FLAG_AC_SECURITY_S;
}
+
+
sprintf(key,"%s/%s",prefix,"ssl-certfile");
ssl_cert = cw_ktv_get_str(conn->local_cfg,key,NULL);
@@ -41,6 +72,8 @@ int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * de
sprintf(key,"%s/%s",prefix,"ssl-dhbits");
conn->dtls_dhbits = cw_ktv_get_word(cfg,key,1024);
+
+ conn->dtls_get_psk = get_psk;
return security;
}
\ No newline at end of file
diff --git a/src/cw/cw_stricmp.c b/src/cw/cw_stricmp.c
index 58549aba..a49e33a9 100644
--- a/src/cw/cw_stricmp.c
+++ b/src/cw/cw_stricmp.c
@@ -2,7 +2,7 @@
#include "cw.h"
-int cw_strcicmp(char const *a, char const *b)
+int cw_stricmp(char const *a, char const *b)
{
for (;; a++, b++) {
int d = tolower(*a) - tolower(*b);
diff --git a/src/cw/cw_type_bstr16.c b/src/cw/cw_type_bstr16.c
index e7bcad37..ae37a621 100644
--- a/src/cw/cw_type_bstr16.c
+++ b/src/cw/cw_type_bstr16.c
@@ -77,13 +77,13 @@ static struct cw_KTV *from_str ( struct cw_KTV * data, const char *src )
}
-static int len ( struct cw_KTV * data ){
+static int len (cw_KTV_t * data ){
return bstr16_len(data->val.ptr);
}
-static void * data(struct cw_KTV_t * data)
+static void * data(cw_KTV_t * data)
{
- return bstr16_data(data);
+ return bstr16_data(data->val.ptr);
}
const struct cw_Type cw_type_bstr16 = {
diff --git a/src/cw/dtls_gnutls.c b/src/cw/dtls_gnutls.c
index 964dc569..b331c7a2 100644
--- a/src/cw/dtls_gnutls.c
+++ b/src/cw/dtls_gnutls.c
@@ -128,6 +128,7 @@ struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config)
{
const char *errpos;
int rc;
+ gnutls_datum_t key;
int bits;
struct dtls_gnutls_data *d = malloc(sizeof(struct dtls_gnutls_data));
if (!d)
@@ -204,16 +205,18 @@ struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config)
return 0;
}
+
+
rc = gnutls_credentials_set(d->session, GNUTLS_CRD_CERTIFICATE, d->x509_cred);
if (rc < 0) {
- cw_log(LOG_ERR, "DTLS - Can't set credentials: %s", gnutls_strerror(rc));
+ cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
return 0;
}
gnutls_certificate_set_verify_function(d->x509_cred,verify_cert);
-
+ gnutls_session_set_ptr(d->session, conn);
gnutls_transport_set_ptr(d->session, conn);
gnutls_transport_set_pull_function(d->session, dtls_gnutls_bio_read);
gnutls_transport_set_push_function(d->session, dtls_gnutls_bio_write);
diff --git a/src/cw/dtls_gnutls.h b/src/cw/dtls_gnutls.h
index 44a16d74..ec17565c 100644
--- a/src/cw/dtls_gnutls.h
+++ b/src/cw/dtls_gnutls.h
@@ -35,7 +35,7 @@ const char * dtls_gnutls_get_cipher(struct conn * conn, char * dst);
struct dtls_ssl_cert dtls_gnutls_get_peers_cert(struct conn * conn,unsigned int n);
extern int dtls_gnutls_shutdown(struct conn *conn);
-#define CAPWAP_CIPHER "+DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1"
+#define CAPWAP_CIPHER "+RSA:+AES-128-CBC:+SHA1"
/* functions used only by capwap libray */
diff --git a/src/cw/dtls_gnutls_accept.c b/src/cw/dtls_gnutls_accept.c
index cfca75d0..4bff8228 100644
--- a/src/cw/dtls_gnutls_accept.c
+++ b/src/cw/dtls_gnutls_accept.c
@@ -35,6 +35,29 @@
#include "timer.h"
+int psk_creds(gnutls_session_t session, const char *user, gnutls_datum_t *key)
+{
+ struct conn *conn;
+
+ int rc;
+ uint8_t * psk;
+ int psk_len;
+
+ conn = gnutls_session_get_ptr(session);
+
+ rc = conn->dtls_get_psk(conn,user, &psk,&psk_len);
+ if (!rc)
+ return -1;
+ key->size=psk_len;
+ key->data = gnutls_malloc(key->size);
+ if (key->data == NULL) {
+ return -1;
+ }
+ memcpy(key->data, psk, psk_len);
+ return 0;
+}
+
+
int dtls_gnutls_accept(struct conn *conn)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
@@ -47,15 +70,15 @@ int dtls_gnutls_accept(struct conn *conn)
gnutls_datum_t cookie_key;
gnutls_dtls_prestate_st prestate;
-
-
-
+
+
+
gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s",
- sock_addr2str(&conn->addr,sock_buf),
+ sock_addr2str(&conn->addr, sock_buf),
sock_hwaddrtostr((uint8_t *) (&cookie_key),
- sizeof(cookie_key),cookie_buf,""));
+ sizeof(cookie_key), cookie_buf, ""));
memset(&prestate, 0, sizeof(prestate));
@@ -63,31 +86,34 @@ int dtls_gnutls_accept(struct conn *conn)
tlen = dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
gnutls_dtls_cookie_send(&cookie_key, &conn->addr, sizeof(conn->addr),
- &prestate, (gnutls_transport_ptr_t) conn, dtls_gnutls_bio_write);
+ &prestate, (gnutls_transport_ptr_t) conn,
+ dtls_gnutls_bio_write);
- rc=-1;
+ rc = -1;
c_timer = cw_timer_start(10);
- while(!cw_timer_timeout(c_timer)){
+ while (!cw_timer_timeout(c_timer)) {
- tlen = conn_q_recv_packet_peek(conn,buffer,sizeof(buffer));
+ tlen = conn_q_recv_packet_peek(conn, buffer, sizeof(buffer));
- if (tlen <0 && errno == EAGAIN)
+ if (tlen < 0 && errno == EAGAIN)
continue;
- if (tlen < 0 ){
+ if (tlen < 0) {
/* something went wrong, iwe should log a message */
continue;
}
-
+
rc = gnutls_dtls_cookie_verify(&cookie_key,
&conn->addr,
- sizeof(conn->addr), buffer+4, tlen-4, &prestate);
+ sizeof(conn->addr), buffer + 4, tlen - 4,
+ &prestate);
- if (rc<0){
- cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
+ if (rc < 0) {
+ cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s",
+ gnutls_strerror(rc));
dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
continue;
}
@@ -96,61 +122,81 @@ int dtls_gnutls_accept(struct conn *conn)
}
- if (rc <0 ){
+ if (rc < 0) {
cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
return 0;
}
- cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",sock_addr2str(&conn->addr,sock_buf));
+ cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",
+ sock_addr2str(&conn->addr, sock_buf));
- d = dtls_gnutls_data_create(conn,GNUTLS_SERVER | GNUTLS_DATAGRAM);
+ d = dtls_gnutls_data_create(conn, GNUTLS_SERVER | GNUTLS_DATAGRAM);
if (!d)
return 0;
+ if (conn->dtls_psk_enable) {
+ gnutls_psk_server_credentials_t cred;
+ rc = gnutls_psk_allocate_server_credentials(&cred);
+ if (rc != 0) {
+ cw_log(LOG_ERR,"gnutls_psk_allocate_server_credentials() failed.");
+ }
+ /* GnuTLS will call psk_creds to ask for the key associated with the
+ client's username.*/
+ gnutls_psk_set_server_credentials_function(cred, psk_creds);
+ /* // Pass the "credentials" to the GnuTLS session. GnuTLS does NOT make an
+ // internal copy of the information, so we have to keep the 'cred' structure
+ // in memory (and not modify it) until we're done with this session.*/
+ rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
+ if (rc != 0) {
+ cw_log(LOG_ERR,"gnutls_credentials_set() failed.\n");
+ }
+
+ }
+
+
+
+
/* Generate Diffie-Hellman parameters - for use with DHE
- * kx algorithms. When short bit length is used, it might
- * be wise to regenerate parameters often.
- */
- /*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);*/
+ * kx algorithms. When short bit length is used, it might
+ * be wise to regenerate parameters often.
+ */
+ /*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); */
bits = conn->dtls_dhbits;
-
+
gnutls_dh_params_init(&d->dh_params);
- cw_dbg(DBG_DTLS,"Generating DH params, %d",bits);
- gnutls_dh_params_generate2(d->dh_params, bits);
- cw_dbg(DBG_DTLS,"DH params generated, %d",bits);
+ cw_dbg(DBG_DTLS, "Generating DH params, %d", bits);
+ gnutls_dh_params_generate2(d->dh_params, bits);
+ cw_dbg(DBG_DTLS, "DH params generated, %d", bits);
+ gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);
- gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);
-
-
-
- gnutls_certificate_server_set_request(d->session,GNUTLS_CERT_REQUEST);
+ gnutls_certificate_server_set_request(d->session, GNUTLS_CERT_REQUEST);
gnutls_dtls_prestate_set(d->session, &prestate);
c_timer = cw_timer_start(10);
- do{
+ do {
rc = gnutls_handshake(d->session);
- }while(!cw_timer_timeout(c_timer) && rc==GNUTLS_E_AGAIN);
-
+ } while (!cw_timer_timeout(c_timer) && rc == GNUTLS_E_AGAIN);
- if ( rc < 0 ) {
- cw_log(LOG_ERR, "Error in handshake with %s: %s",sock_addr2str(&conn->addr,sock_buf), gnutls_strerror(rc));
+
+ if (rc < 0) {
+ cw_log(LOG_ERR, "Error in handshake with %s: %s",
+ sock_addr2str(&conn->addr, sock_buf), gnutls_strerror(rc));
return 0;
}
- cw_dbg(DBG_DTLS,"Handshake with %s successful.",sock_addr2str(&conn->addr,sock_buf));
+ cw_dbg(DBG_DTLS, "Handshake with %s successful.",
+ sock_addr2str(&conn->addr, sock_buf));
- conn->dtls_data=d;
+ conn->dtls_data = d;
conn->read = dtls_gnutls_read;
conn->write = dtls_gnutls_write;
return 1;
}
-
-
diff --git a/src/cw/dtls_gnutls_connect.c b/src/cw/dtls_gnutls_connect.c
index 9b046f3c..d7d82c4e 100644
--- a/src/cw/dtls_gnutls_connect.c
+++ b/src/cw/dtls_gnutls_connect.c
@@ -34,13 +34,14 @@
#include "sock.h"
/**
* Establish a DTLS connection using gnutls library
- * @see #dtls_connect
+ * @see #dtls_connec
*/
int dtls_gnutls_connect(struct conn *conn)
{
int rc;
char sock_buf[SOCK_ADDR_BUFSIZE];
struct dtls_gnutls_data *d;
+ gnutls_datum_t key;
d = dtls_gnutls_data_create(conn,
GNUTLS_CLIENT | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK);
@@ -56,6 +57,50 @@ int dtls_gnutls_connect(struct conn *conn)
gnutls_dtls_set_mtu(d->session, 1500);
*/
+/*
+ if (conn->dtls_psk != NULL){
+ key.data=(unsigned char*)conn->dtls_psk;
+ key.size=strlen(conn->dtls_psk);
+
+ rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, &key);
+ if (rc<0) {
+ cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc));
+ dtls_gnutls_data_destroy(d);
+ return 0;
+
+ }
+ }
+
+*/
+
+
+ if (conn->dtls_psk_enable){
+ gnutls_psk_client_credentials_t cred;
+ rc = gnutls_psk_allocate_client_credentials(&cred);
+ if (rc != 0) {
+ cw_dbg(DBG_DTLS,"gnutls_psk_allocate_client_credentials() failed.\n");
+ return 0;
+ }
+
+
+ key.size = bstr16_len(conn->dtls_psk);
+ key.data = bstr16_data(conn->dtls_psk);
+
+
+ /* Put the username and key into the structure we use to tell GnuTLs what
+ // the credentials are. The example server doesn't care about usernames, so
+ // we use "Alice" here.*/
+ rc = gnutls_psk_set_client_credentials(cred, "Alice", &key, GNUTLS_PSK_KEY_RAW);
+ rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
+ if (rc != 0) {
+ cw_log(LOG_ERR,"gnutls_credentials_set() failed.");
+ }
+
+
+
+ }
+
+
cw_dbg(DBG_DTLS,"Starting handshake");
do {
diff --git a/src/cw/dtls_openssl.c b/src/cw/dtls_openssl.c
index 6fb3af87..c1f5839a 100644
--- a/src/cw/dtls_openssl.c
+++ b/src/cw/dtls_openssl.c
@@ -294,7 +294,8 @@ static unsigned int psk_server_cb(SSL *ssl,const char *identity, unsigned char *
{
BIO * b = SSL_get_rbio(ssl);
struct conn * conn = b->ptr;
- int l = conn->dtls_psk_len < max_psk_len ? conn->dtls_psk_len : max_psk_len;
+
+ int l = bstr16_len(conn->dtls_psk) < max_psk_len ? bstr16_len(conn->dtls_psk) : max_psk_len;
memcpy(psk,conn->dtls_psk,l);
return l;
}
diff --git a/src/cw/dtls_openssl_connect.c b/src/cw/dtls_openssl_connect.c
index 4ad10827..e7bb2183 100644
--- a/src/cw/dtls_openssl_connect.c
+++ b/src/cw/dtls_openssl_connect.c
@@ -34,8 +34,8 @@ static BIO_METHOD bio_methods = {
snprintf(identity, max_identity_len, "CLient_identity");
- l = conn->dtls_psk_len < max_psk_len ? conn->dtls_psk_len : max_psk_len;
- memcpy(psk, conn->dtls_psk, l);
+ l = bstr16_len(conn->dtls_psk) < max_psk_len ? bstr16_len(conn->dtls_psk) : max_psk_len;
+ memcpy(psk, bstr16_data(conn->dtls_psk), l);
return l;
}
diff --git a/src/wtp/config.ktv b/src/wtp/config.ktv
index 6666528a..2ad03929 100644
--- a/src/wtp/config.ktv
+++ b/src/wtp/config.ktv
@@ -2,14 +2,15 @@
-capwap/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
-capwap/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
+#capwap/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
+#capwap/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
#capwap/ssl-cipher:Str: +RSA:+AES-128-CBC:+SHA1
-#capwap/ssl-cipher:Str: +DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1
-#capwap/ssl-psk:Str:"HalloWelt"
+capwap/ssl-cipher:Str: +DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
+capwap/ssl-psk:Bstr16:"HalloWelt"
+capwap/ssl-psk-enable:Bool:true
-cisco/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
-cisco/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
+#cisco/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
+#cisco/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
discovery-type:Byte:0
wtp-frame-tunnel-mode:Byte:1
@@ -48,7 +49,6 @@ capwap-timers/echo-interval:Byte:3
"discovery-interval":Byte:1
-
location-data:Bstr16:Entangeled