diff --git a/src/1905_tlvs.h b/src/1905_tlvs.h
index 7c3a4cc9576b8e86be7018aa1a5d192c6c903a9e..616815854e4b6442f1ad3a2dcf74f38db923f3c7 100644
--- a/src/1905_tlvs.h
+++ b/src/1905_tlvs.h
@@ -46,7 +46,7 @@
 #define TLV_TYPE_LAST                                (30)
 
 
-// Media types as detailed in "Table 6-12"
+/* Media types */
 #define MEDIA_TYPE_IEEE_802_3U_FAST_ETHERNET       (0x0000)
 #define MEDIA_TYPE_IEEE_802_3AB_GIGABIT_ETHERNET   (0x0001)
 #define MEDIA_TYPE_IEEE_802_11B_2_4_GHZ            (0x0100)
@@ -63,359 +63,249 @@
 #define MEDIA_TYPE_UNKNOWN                         (0xFFFF)
 
 
-// IEEE802.11 frequency bands used in "Tables 6-22 and 6-24"
-#define IEEE80211_ROLE_REGISTRAR                   (0x00)
 
-// IEEE802.11 frequency bands used in "Tables 6-23 and 6-25"
+/* IEEE802.11 frequency bands */
 #define IEEE80211_FREQUENCY_BAND_2_4_GHZ           (0x00)
 #define IEEE80211_FREQUENCY_BAND_5_GHZ             (0x01)
 #define IEEE80211_FREQUENCY_BAND_60_GHZ            (0x02)
 
 
-// Media type structures detailed in "Tables 6-12 and 6-13"
-struct _ieee80211SpecificInformation {
-	uint8_t network_membership[6];	// BSSID
-
-#define IEEE80211_SPECIFIC_INFO_ROLE_AP                   (0x0)
-#define IEEE80211_SPECIFIC_INFO_ROLE_NON_AP_NON_PCP_STA   (0x4)
-#define IEEE80211_SPECIFIC_INFO_ROLE_WIFI_P2P_CLIENT      (0x8)
-#define IEEE80211_SPECIFIC_INFO_ROLE_WIFI_P2P_GROUP_OWNER (0x9)
-#define IEEE80211_SPECIFIC_INFO_ROLE_AD_PCP               (0xa)
-	uint8_t role;		// One of the values from above
+/* IEEE80211 roles */
+#define IEEE80211_ROLE_REGISTRAR                   (0x00)
 
-	uint8_t ap_channel_band;	// Hex value of dot11CurrentChannelBandwidth
-	// (see "IEEE P802.11ac/D3.0" for description)
+#define IEEE80211_ROLE_AP                          (0x0)
+#define IEEE80211_ROLE_STA                         (0x4)
+#define IEEE80211_ROLE_P2P_CLIENT                  (0x8)
+#define IEEE80211_ROLE_P2P_GO                      (0x9)
+#define IEEE80211_ROLE_AD_PCP                      (0xa)
 
-	uint8_t ap_channel_center_frequency_index_1;
-	// Hex value of
-	// dot11CurrentChannelCenterFrequencyIndex1
-	// (see "IEEE P802.11ac/D3.0" for description)
 
-	uint8_t ap_channel_center_frequency_index_2;
-	// Hex value of
-	// dot11CurrentChannelCenterFrequencyIndex2
-	// (see "IEEE P802.11ac/D3.0" for description)
-};
+typedef uint8_t macaddr_t[6];
 
-struct _ieee1901SpecificInformation {
-	uint8_t network_identifier[7];	// Network membership
-};
 
-union _mediaSpecificData {
-	uint8_t dummy;		// Empty placeholder
-	struct _ieee80211SpecificInformation ieee80211;
-	struct _ieee1901SpecificInformation ieee1901;
 
+/* TLV: End of message */
+struct tlv_eom {
 };
 
-/* Generic phy common structure used in "Tables 6.29, 6.36 and 6.38" */
-struct _genericPhyCommonData {
+/* TLV: Vendor specific info */
+struct tlv_vendor_specific {
 	uint8_t oui[3];
-	uint8_t variant_index;
-	uint8_t media_specific_bytes_nr;
-	uint8_t *media_specific_bytes;
-};
-
-/* End of message TLV ("Section 6.4.1") */
-struct endOfMessageTLV {
-};
-
-/* Vendor specific TLV ("Section 6.4.2") */
-struct vendorSpecificTLV {
-	uint8_t vendorOUI[3];
-	uint16_t m_nr;
-	uint8_t *m;
-};
+	uint16_t num_bytes;
+	uint8_t bytes[];
+} __attribute__((packed));
 
-/* AL MAC address type TLV ("Section 6.4.3") */
-struct alMacAddressTypeTLV {
-	uint8_t al_mac_address[6];
-};
 
+/* TLV: AL mac-address */
+struct tlv_aladdr {
+	uint8_t macaddr[6];
+} __attribute__ ((packed));
 
-/* MAC address type TLV ("Section 6.4.4") */
-struct macAddressTypeTLV {
-	uint8_t mac_address[6];
-};
 
+/* TLV: mac-address */
+struct tlv_macaddr {
+	uint8_t macaddr[6];
+} __attribute__((packed));
 
-/* Device information type TLV ("Section 6.4.5") */
-struct _localInterfaceEntries {
-	uint8_t mac_address[6];
-	uint16_t media_type;	/* One of the MEDIA_TYPE_* values */
-	uint8_t media_specific_data_size;
-	// Number of bytes in ensuing field
-	// Its value is '10' when 'media_type' is one
-	// of the valid MEDIA_TYPE_IEEE_802_11*
-	// values.
-	// Its value is '7' when 'media_type' is one
-	// of the valid MEDIA_TYPE_IEEE_1901* values.
-
-	union _mediaSpecificData media_specific_data;
-	// Media specific data
-	// It will contain a IEEE80211 structure
-	// when 'media_type' is one of the valid
-	// MEDIA_TYPE_IEEE_802_11* values
-	// It will contain a IEE1905 structure
-	// when 'media_type' is one of the valid
-	// MEDIA_TYPE_IEEE_1901* values
-	// It will be empty in the rest of cases
-};
 
-struct deviceInformationTypeTLV {
-	uint8_t al_mac_address[6];
-	uint8_t local_interfaces_nr;
-	struct _localInterfaceEntries *local_interfaces;
-};
+/* IEEE 802.11 media specific info */
+struct ieee80211_info {
+	uint8_t bssid[6];
+	uint8_t role;
+	uint8_t ap_bandwidth;
+	uint8_t ap_channel_seg0_idx;
+	uint8_t ap_channel_seg1_idx;
+} __attribute__ ((packed));
 
+/* IEEE 1901 media specific info */
+struct ieee1901_info {
+	uint8_t netid[7];
+} __attribute__((packed));
 
+struct local_interface {
+	uint8_t macaddr[6];
+	uint16_t mediatype;	/* One of the MEDIA_TYPE_* values */
+	uint8_t sizeof_mediainfo;
+	uint8_t mediainfo[];	/* ieee80211_info, ieee1901_info etc. */
+}__attribute__((packed));
 
-/* Device bridging capability TLV associated structures ("Section 6.4.6") */
-struct _bridgingTupleMacEntries {
-	uint8_t mac_address[6];	// MAC address of a 1905 device's network
-	// interface that belongs to a bridging tuple
-};
+/* TLV: device information */
+struct tlv_device_info {
+	uint8_t aladdr[6];
+	uint8_t num_interface;
+	struct local_interface interface[];
+} __attribute__((packed));
 
-struct _bridgingTupleEntries {
-	uint8_t bridging_tuple_macs_nr;	// Number of MAC addresses in this bridging
-	struct _bridgingTupleMacEntries *bridging_tuple_macs;
-	// List of 'mac_nr' elements, each one
-	// representing a MAC. All these MACs are
-	// bridged together.
-};
 
-struct deviceBridgingCapabilityTLV {
-	uint8_t bridging_tuples_nr;
-	struct _bridgingTupleEntries *bridging_tuples;
+struct device_bridge_tuple_macaddr {
+	uint8_t macaddr[6];
+} __attribute__ ((packed));
 
-};
+struct device_bridge_tuple {
+	uint8_t num_macaddrs;
+	struct device_bridge_tuple_macaddr addr[];
+} __attribute__ ((packed));
 
-/* Non-1905 neighbor device list TLV ("Section 6.4.8") */
-struct _non1905neighborEntries {
-	uint8_t mac_address[6];
-};
-
-struct non1905NeighborDeviceListTLV {
-	uint8_t local_mac_address[6];
-	uint8_t non_1905_neighbors_nr;
-	struct _non1905neighborEntries *non_1905_neighbors;
-};
+/* TLV: Device bridging capability */
+struct tlv_device_bridge_caps {
+	uint8_t num_tuples;
+	struct device_bridge_tuple tuple[];
+} __attribute__((packed));
 
 
-/* Neighbor device TLV ("Section 6.4.9") */
-struct _neighborEntries {
-	uint8_t mac_address[6];	// AL MAC address of the 1905 neighbor
-	uint8_t bridge_flag;	// "0" --> no IEEE 802.1 bridge exists
-	// "1" --> at least one IEEE 802.1 bridge
-	//         exists between this device and the
-	//         neighbor
-};
 
-struct neighborDeviceListTLV {
-	uint8_t local_mac_address[6];
-	uint8_t neighbors_nr;
-	struct _neighborEntries *neighbors;
+struct non1905_neighbor {
+	uint8_t macaddr[6];
 };
 
+/* TLV: non-1905 neighbor devices */
+struct tlv_non1905_neighbor {
+	uint8_t local_macaddr[6];
+	uint8_t num_non1905_nbrs;
+	struct non1905_neighbor non1905_nbr[];
+} __attribute__((packed));
 
-/* Link metric query TLV ("Section 6.4.10") */
-struct linkMetricQueryTLV {
-#define LINK_METRIC_QUERY_TLV_ALL_NEIGHBORS      (0x00)
-#define LINK_METRIC_QUERY_TLV_SPECIFIC_NEIGHBOR  (0x01)
-	uint8_t destination;	// One of the values from above
-	uint8_t specific_neighbor[6];
-
-#define LINK_METRIC_QUERY_TLV_TX_LINK_METRICS_ONLY         (0x00)
-#define LINK_METRIC_QUERY_TLV_RX_LINK_METRICS_ONLY         (0x01)
-#define LINK_METRIC_QUERY_TLV_BOTH_TX_AND_RX_LINK_METRICS  (0x02)
-	uint8_t link_metrics_type;
-};
-
-/* Transmitter link metric TLV ("Section 6.4.11") */
-struct _transmitterLinkMetricEntries {
-	uint8_t local_interface_address[6];	// MAC address of an interface in
-	// the receiving AL, which connects
-	// to an interface in the neighbor
-	// AL
 
-	uint8_t neighbor_interface_address[6];	// MAC addres of an interface in a
-	// neighbor AL, which connects to
-	// an interface in the receiving
-	// AL
+struct i1905_neighbor {
+	uint8_t aladdr[6];
+	uint8_t has_bridge;
+} __attribute__((packed));
 
-	uint16_t intf_type;	// Underlaying network technology
-	// One of the MEDIA_TYPE_* values.
+/* TLV: 1905 neighbor devices */
+struct tlv_1905neighbor {
+	uint8_t local_macaddr[6];
+	uint8_t num_1905nbrs;
+	struct i1905_neighbor nbr[];
+} __attribute__((packed));
 
-	uint8_t bridge_flag;	// Indicates whether or not the 1905 link
-	// includes one or more IEEE 802.11
-	// bridges
 
-	uint32_t packet_errors;	// Estimated number of lost packets on the
-	// transmitting side of the link during
-	// the measurement period (5 seconds??)
 
-	uint32_t transmitted_packets;	// Estimated number of packets transmitted
-	// on the same measurement period used to
-	// estimate 'packet_errors'
+#define LINKMETRIC_QUERY_NEIGHBOR_ALL		(0x00)
+#define LINKMETRIC_QUERY_NEIGHBOR_SPECIFIC	(0x01)
 
-	uint16_t mac_throughput_capacity;	// The maximum MAC throughput of the link
-	// estimated at the transmitter and
-	// expressed in Mb/s
+#define LINKMETRIC_QUERY_TYPE_TX		(0x00)
+#define LINKMETRIC_QUERY_TYPE_RX		(0x01)
+#define LINKMETRIC_QUERY_TYPE_BOTH		(0x02)
 
-	uint16_t link_availability;	// The estimated average percentage of
-	// time that the link is available for
-	// data transmissions
-
-	uint16_t phy_rate;	// This value is the PHY rate estimated at
-	// the transmitter of the link expressed
-	// in Mb/s
+/* TLV: link metric query */
+struct tlv_linkmetric_query {
+	uint8_t nbr_type;
+	uint8_t nbr_macaddr[6];
+	uint8_t query_type;
 };
 
-struct transmitterLinkMetricTLV {
-	uint8_t tlv_type;		// Must always be set to
-	// TLV_TYPE_TRANSMITTER_LINK_METRIC
+struct tx_link_info {
+	uint8_t local_macaddr[6];
+	uint8_t neighbor_macaddr[6];
+	uint16_t mediatype;		/* one of MEDIA_TYPE_* */
+	uint8_t has_bridge;
+	uint32_t errors;
+	uint32_t packets;
+	uint16_t max_throughput;	/* estimated mac thput in Mbps */
+	uint16_t availability;		/* in %age */
+	uint16_t phyrate;		/* estimated phy rate in Mbps */
+} __attribute__((packed));
 
-	uint8_t local_al_address[6];	// AL MAC address of the device that
-	// transmits the response message that
-	// contains this TLV
+/* TLV: transmitter link metric */
+struct tlv_tx_linkmetric {
+	uint8_t aladdr[6];
+	uint8_t neighbor_aladdr[6];
+
+	uint8_t num_tx_links;
+	struct tx_link_info link[];
+} __attribute__((packed));
 
-	uint8_t neighbor_al_address[6];	// AL MAC address of the neighbor whose
-	// link metric is reported in this TLV
 
-	uint8_t transmitter_link_metrics_nr;
-	struct _transmitterLinkMetricEntries *transmitter_link_metrics;
-	// Link metric information for the above
-	// interface pair between the receiving AL
-	// and the neighbor AL
-};
 
-////////////////////////////////////////////////////////////////////////////////
-// Receiver link metric TLV associated structures ("Section 6.4.12")
-////////////////////////////////////////////////////////////////////////////////
-struct _receiverLinkMetricEntries {
-	uint8_t local_interface_address[6];	// MAC address of an interface in
-	// the receiving AL, which connects
-	// to an interface in the neighbor
-	// AL
-
-	uint8_t neighbor_interface_address[6];	// MAC addres of an interface in a
-	// neighbor AL, which connects to
-	// an interface in the receiving
-	// AL
-
-	uint16_t intf_type;	// Underlaying network technology
-
-	uint32_t packet_errors;	// Estimated number of lost packets on the
-	// receiving side of the link during
-	// the measurement period (5 seconds??)
-
-	uint32_t packets_received;	// Estimated number of packets received on
-	// the same measurement period used to
-	// estimate 'packet_errors'
-
-	uint8_t rssi;		// This value is the estimated RSSI at the
-	// receive side of the link expressed in
-	// dB
-};
+struct rx_link_info {
+	uint8_t local_macaddr[6];
+	uint8_t neighbor_macaddr[6];
+	uint16_t mediatype;
+	uint32_t errors;
+	uint32_t packets;
+	int8_t rssi;			/* in dBm */
+} __attribute__((packed));
 
+/* TLV: receiver link metric */
 struct receiverLinkMetricTLV {
-	uint8_t tlv_type;		// Must always be set to
-	// TLV_TYPE_RECEIVER_LINK_METRIC
+	uint8_t aladdr[6];
+	uint8_t neighbor_aladdr[6];
+	uint8_t num_rx_links;
+	struct rx_link_info link[];
+} __attribute__((packed));
 
-	uint8_t local_al_address[6];	// AL MAC address of the device that
-	// transmits the response message that
-	// contains this TLV
 
-	uint8_t neighbor_al_address[6];	// AL MAC address of the neighbor whose
-	// link metric is reported in this TLV
+#define LINKMETRIC_RESULT_INVALID_NEIGHBOR  (0x00)
 
-	uint8_t receiver_link_metrics_nr;
-	struct _receiverLinkMetricEntries *receiver_link_metrics;
-	// Link metric information for the above
-	// interface pair between the receiving AL
-	// and the neighbor AL
-};
+/* TLV: link metric result code */
+struct tlv_linkmetric_result {
+	uint8_t code;
+} __attribute__((packed));
 
-////////////////////////////////////////////////////////////////////////////////
-// Link metric result code TLV associated structures ("Section 6.4.13")
-////////////////////////////////////////////////////////////////////////////////
-struct linkMetricResultCodeTLV {
-	uint8_t tlv_type;		// Must always be set to
-	// TLV_TYPE_LINK_METRIC_RESULT_CODE
+/* TLV: searched role */
+struct tlv_searched_role {
+	uint8_t role;		/* one of IEEE80211_ROLE_* */
+} __attribute__((packed));
 
-#define LINK_METRIC_RESULT_CODE_TLV_INVALID_NEIGHBOR  (0x00)
-	uint8_t result_code;	// One of the values from above
-};
+/* TLV: autoconfig frequency band */
+struct tlv_autoconfig_band {
+	uint8_t band;		/* one of IEEE80211_FREQUENCY_BAND_* */
+} __attribute__((packed));
 
-// Searched role TLV ("Section 6.4.14")
-struct searchedRoleTLV {
-	uint8_t role;		// One of IEEE80211_ROLE_*
-};
+/* TLV: supported role */
+struct tlv_supported_role {
+	uint8_t role;		/* one of IEEE80211_ROLE_* */
+} __attribute__((packed));
 
-// Autoconfig frequency band TLV ("Section 6.4.15")
-struct autoconfigFreqBandTLV {
-	uint8_t freq_band;	// one of IEEE80211_FREQUENCY_BAND_*
-};
+/* TLV: supported frequency band */
+struct tlv_supported_band {
+	uint8_t band;		/* one of IEEE80211_FREQUENCY_BAND_* */
+} __attribute__((packed));
 
-// Supported role TLV ("Section 6.4.16")
-struct supportedRoleTLV {
-	uint8_t role;		// One of IEEE80211_ROLE_*
-};
 
-// Supported frequency band TLV ("Section 6.4.17")
-struct supportedFreqBandTLV {
-	uint8_t freq_band;	// one of IEEE80211_FREQUENCY_BAND_*
-};
+/* TLV: wsc */
+struct tlv_wsc {
+	uint16_t framelen;
+	uint8_t frame[];
+} __attribute__((packed));
 
 
-// Supported frequency band TLV ("Section 6.4.18")
-struct wscTLV {
-	uint16_t wsc_frame_size;
-	uint8_t *wsc_frame;
-};
+struct media_info {
+	uint16_t type;
+	uint8_t sizeof_info;
+	uint8_t info[];		/* ieee80211_info, ieee1901_info etc. */
+} __attribute__((packed));
 
-// Push button event notification TLV ("Section 6.4.19")
-struct _mediaTypeEntries {
-	uint16_t media_type;	// One of the MEDIA_TYPE_* values
-
-	uint8_t media_specific_data_size;
-	union _mediaSpecificData media_specific_data;
-	// Media specific data
-	// It will contain a IEEE80211 structure
-	// when 'media_type' is one of the valid
-	// MEDIA_TYPE_IEEE_802_11* values
-	// It will contain a IEE1905 structure
-	// when 'media_type' is one of the valid
-	// MEDIA_TYPE_IEEE_1901* values
-	// It will be empty in the rest of cases
-};
+/* TLV: push button event notification */
+struct tlv_pbc_notification {
+	uint8_t num_media;
+	struct media_info media[];
+} __attribute__((packed));
 
-struct pushButtonEventNotificationTLV {
-	uint8_t media_types_nr;
-	struct _mediaTypeEntries *media_types;
-};
 
+/* TLV: push button join notification */
+struct tlv_pbc_join_notification {
+	uint8_t aladdr[6];
+	uint16_t mid;
+	uint8_t macaddr[6];
+	uint8_t new_macaddr[6];
+} __attribute__((packed));
 
-// Push button join notification TLV ("Section 6.4.20")
-struct pushButtonJoinNotificationTLV {
-	uint8_t al_mac_address[6];
-	uint16_t message_identifier;	// The message identifier (MID) of the push
-	// button event notification message
 
-	uint8_t mac_address[6];	// Interface specific MAC address of the
-	// interface of the transmitting device
-	// belonging to the medium on which a new
-	// device joined
 
-	uint8_t new_mac_address[6];	// Interface specific MAC address of the
-	// interface of the new device that was joined
-	// to the network as a result of the push
-	// button configuration sequence
-};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Generic PHY device information TLV associated structures ("Section 6.4.21")
 ////////////////////////////////////////////////////////////////////////////////
+//
+/* Generic phy common structure used in "Tables 6.29, 6.36 and 6.38" */
+struct _genericPhyCommonData {
+	uint8_t oui[3];
+	uint8_t variant_index;
+	uint8_t media_specific_bytes_nr;
+	uint8_t *media_specific_bytes;
+};
+
 struct _genericPhyDeviceEntries {
 	uint8_t local_interface_address[6];
 	// MAC address of the local interface
diff --git a/src/cmdu_input.c b/src/cmdu_input.c
index 208d39553f07da1debf224c6d9da795948e0b4b9..58d17f407161e63755202871dc602250aecfd424 100644
--- a/src/cmdu_input.c
+++ b/src/cmdu_input.c
@@ -41,7 +41,7 @@
 
 // TODO: combine 3 following headers into one
 #include "1905_defs.h"
-#include "i1905_tlvs.h"
+#include "1905_tlvs.h"
 #include "lldp_tlvs.h"
 
 
@@ -72,16 +72,18 @@ int i1905_handle_topology_discovery(struct i1905_interface_private *pif,
 
 
 	if (hwaddr_is_zero(macaddr_origin)) {
-		fprintf(stderr, "%s: Discard topo discovery from src = 0!\n",
+		fprintf(stderr,
+			"%s: Discard topo discovery from src = 0!\n",
 			__func__);
 
 		return -1;
 	}
 
-	ret = i1905_dm_neighour_update(i1905_interface_priv(pif),
+	ret = i1905_dm_neighbor_discovered(i1905_interface_priv(pif),
 					   aladdr_origin, macaddr_origin);
 	if (ret) {
-		fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
+		fprintf(stderr,
+			"%s: Error updating DM for discovered neighbor " MACFMT"\n",
 			__func__, MAC2STR(macaddr_origin));
 
 		return -1;
@@ -108,16 +110,18 @@ int i1905_handle_topology_notification(struct i1905_interface_private *pif,
 
 
 	if (hwaddr_is_zero(aladdr_origin)) {
-		fprintf(stderr, "%s: Discard topo notification from aladdr = 0!\n",
+		fprintf(stderr,
+			"%s: Discard topo notification from aladdr = 0!\n",
 			__func__);
 
 		return -1;
 	}
 
-	ret = i1905_dm_neighour_update(i1905_interface_priv(pif),
-					   aladdr_origin, NULL);
+	ret = i1905_dm_neighbor_changed(i1905_interface_priv(pif),
+					aladdr_origin);
 	if (ret) {
-		fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
+		fprintf(stderr,
+			"%s: Error handling neighbor " MACFMT" change notification\n",
 			__func__, MAC2STR(aladdr_origin));
 
 		return -1;
@@ -146,31 +150,61 @@ int i1905_handle_topology_response(struct i1905_interface_private *pif,
 	};
 	struct tlv *tv[6][16];
 	uint8_t aladdr_origin[6] = {0};
-	uint8_t macaddr_origin[6] = {0};
 	int ret;
 
 
 	cmdu_parse_tlvs(rxf, tv, a_policy, 6);
 
 
-#if 0
-	if (hwaddr_is_zero(macaddr_origin)) {
-		fprintf(stderr, "%s: Discard topo discovery from src = 0!\n",
-			__func__);
+	if (tv[0][0]) {
+		struct tlv_device_info *devinfo =
+				(struct tlv_device_info *)tv[0][0]->data;
 
-		return -1;
+		if (hwaddr_is_zero(devinfo->aladdr)) {
+			fprintf(stderr, "%s: Discard topo response from aladdr = 0!\n",
+				__func__);
+
+			return -1;
+		}
 	}
 
-	ret = i1905_dm_neighour_update(i1905_interface_priv(pif),
-					   aladdr_origin, macaddr_origin);
-	if (ret) {
-		fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
-			__func__, MAC2STR(macaddr_origin));
+	if (tv[1][0]) {
+		int num = 0;
 
-		return -1;
+		while (tv[1][num]) {
+			struct tlv_device_bridge_caps *brcaps =
+				(struct tlv_device_bridge_caps *)tv[1][num]->data;
+
+			//i1905_dm_neighbor_update(pif, );	//TODO
+			num++;
+		}
+	}
+
+	if (tv[2][0]) {
+		int num = 0;
+
+		while (tv[2][num]) {
+			struct tlv_non1905_neighbor *non1905 =
+				(struct tlv_non1905_neighbor *)tv[2][num]->data;
+
+			//i1905_dm_neighbor_update(pif, );	//TODO
+			num++;
+		}
+	}
+
+	if (tv[3][0]) {
+		int num = 0;
+
+		while (tv[3][num]) {
+			struct tlv_1905neighbor *nbrs =
+				(struct tlv_1905neighbor *)tv[3][num]->data;
+
+			//i1905_dm_neighbor_update(pif, );	//TODO
+			num++;
+		}
 	}
-#endif
 
+	//TODO: tv[4], tv[5]
 
 	return 0;
 }
@@ -317,7 +351,7 @@ int i1905_process_cmdu(struct i1905_interface_private *pif, struct cmdu_buff *rx
 
 	// TODO: discard duplicates
 
-	type = buf_get_be16(rxf->cdata->hdr.type);
+	type = buf_get_be16((uint8_t *)&rxf->cdata->hdr.type);
 
 	if (i1905ftable[type]) {
 		ret = i1905ftable[type](pif, rxf);
diff --git a/src/i1905.c b/src/i1905.c
index 2407270434e903cece8c4fd81fadca87e46547d1..c1b3f5b2541341b41c0e0a5f3835f6975cf38a7a 100644
--- a/src/i1905.c
+++ b/src/i1905.c
@@ -567,21 +567,27 @@ static int i1905_init_interfaces(struct i1905_private *p)
 				sizeof(struct i1905_interface_private));
 		if (iface) {
 			i1905_init_interface(iface, i1905_setup_interface_priv);
+			iface->device = &p->dm.self;
 			memcpy(iface->aladdr, cfg->macaddr, 6);
 			fprintf(stderr, "%s: aladdr = " MACFMT "\n",
 				__func__, MAC2STR(cfg->macaddr));
 
-			list_add_tail(&iface->list, &p->iflist);
+			list_add_tail(&iface->list, &p->dm.self.iflist);
 		}
 	}
 
 	return 0;
 }
 
-
-static int i1905_init_al()
+static int i1905_init_al(struct i1905_private *p)
 {
-	return 0;
+	int ret;
+
+	i1905_dm_init(&p->dm);
+
+	ret = i1905_init_interfaces(p);
+
+	return ret;
 }
 
 void heartbeat_timer_cb(atimer_t *t)
@@ -595,7 +601,8 @@ int i1905_run_bridge_discovery(struct i1905_private *p)
 {
 	struct i1905_interface *iface;
 
-	list_for_each_entry(iface, &p->iflist, list) {
+
+	list_for_each_entry(iface, &p->dm.self.iflist, list) {
 		struct cmdu_buff *frm = NULL;
 		uint8_t *lldpbuf;
 		int ret = 0;
@@ -685,7 +692,8 @@ int i1905_run_topology_discovery(struct i1905_private *p)
 {
 	struct i1905_interface *iface;
 
-	list_for_each_entry(iface, &p->iflist, list) {
+
+	list_for_each_entry(iface, &p->dm.self.iflist, list) {
 		struct cmdu_buff *frm = NULL;
 		struct tlv *t;
 		int ret = 0;
@@ -781,7 +789,6 @@ int i1905_init(void **priv, void *cfg)
 		return -1;
 
 
-	INIT_LIST_HEAD(&p->iflist);
 	INIT_LIST_HEAD(&p->extlist);
 
 	p->ctx = ubus_connect(NULL);
@@ -800,7 +807,7 @@ int i1905_init(void **priv, void *cfg)
 		__func__, p, p->cfg.registrar_2g, p->cfg.registrar_5g);
 
 
-	ret = i1905_init_interfaces(p);
+	ret = i1905_init_al(p);
 	if (ret)
 		goto out_err;
 
diff --git a/src/i1905.h b/src/i1905.h
index d12e372fbf608a12053a7cc934c73a675ffb8eb0..e73c2de760a86baac0c5c0e1e9c82ff6edf3b8e4 100644
--- a/src/i1905.h
+++ b/src/i1905.h
@@ -14,6 +14,7 @@ struct i1905_private {
 	atimer_t topotimer;
 	struct list_head extlist;
 	struct list_head iflist;
+	struct i1905_dm dm;
 
 	struct ubus_context *ctx;
 	struct ubus_object obj;
@@ -29,7 +30,7 @@ struct i1905_interface_private {
 	struct cmdu_queue rxqueue;
 	struct worker rxwork;
 
-	void *iface;
+	void *iface;	/* points to i1905_interface */
 	struct ubus_object obj;
 	struct ubus_object_type obj_type;
 };
@@ -71,7 +72,14 @@ extern struct i1905_dm *i1905_dm_get();
 extern int i1905_dm_init(struct i1905_dm *dm);
 extern int i1905_dm_free(struct i1905_dm *dm);
 
+extern int i1905_dm_neighour_discovered(struct i1905_interface *iface,
+					uint8_t *aladdr, uint8_t *macaddr);
+
+
+extern int i1905_dm_neighour_changed(struct i1905_interface *iface,
+				     uint8_t *aladdr);
+
 extern int i1905_dm_neighour_update(struct i1905_interface *iface,
-				    uint8_t *aladdr, uint8_t *macaddr);
+				    uint8_t *aladdr, struct tlv *t);
 
 #endif /* I1905_H */
diff --git a/src/i1905_dm.c b/src/i1905_dm.c
index b8951e7c06d6a6f52adcb9be60977ad17f039e51..02c782ecf19f8fc5b78e950b45c7fe8e4f45bd60 100644
--- a/src/i1905_dm.c
+++ b/src/i1905_dm.c
@@ -23,36 +23,220 @@
 #include <libubox/utils.h>
 #include <libubus.h>
 
+#include <easy/easy.h>
 
 
 #include "cmdu.h"
 #include "i1905_dm.h"
 
+#include "1905_defs.h"
+#include "i1905_tlvs.h"
+#include "lldp_tlvs.h"
 
 
-int i1905_dm_neighour_update(struct i1905_interface *iface, uint8_t *aladdr,
-			     uint8_t *macaddr)
+struct i1905_interface *i1905_dm_neighbor_interface_create(void)
 {
+	struct i1905_interface *rif;
 
-	//TODO: lookup aladdr/macaddr in DM
-	//	if not available, add to DM
-	//	if available, update tsp
-	//
-	//	if tsp_lastupdated = 0 or > 10 secs, send topo query
+	rif = calloc(1, sizeof(*rif));
+	if (!rif) {
+		fprintf(stderr, "-ENOMEM\n");
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&rif->vendorlist);
+	INIT_LIST_HEAD(&rif->nbrlist);
+	INIT_LIST_HEAD(&rif->iflinklist);
+
+	return rif;
+}
+
+struct i1905_device *i1905_dm_neighbor_create(void)
+{
+	struct i1905_device *rdev;
+
+	rdev = calloc(1, sizeof(*rdev));
+	if (!rdev) {
+		fprintf(stderr, "-ENOMEM\n");
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&rdev->ipv4list);
+	INIT_LIST_HEAD(&rdev->ipv6list);
+	INIT_LIST_HEAD(&rdev->vendorlist);
+	INIT_LIST_HEAD(&rdev->iflist);
+	INIT_LIST_HEAD(&rdev->non1905_nbrlist);
+	INIT_LIST_HEAD(&rdev->nbrlist);
+	INIT_LIST_HEAD(&rdev->l2_nbrlist);
+	INIT_LIST_HEAD(&rdev->brlist);
+	INIT_LIST_HEAD(&rdev->reglist);
+
+	return rdev;
+}
+
+
+struct i1905_device *i1905_dm_neighbor_lookup(struct i1905_interface *iface,
+					      uint8_t *aladdr)
+{
+	struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device;
+	struct i1905_device *rdev = NULL;
+
+	//TODO: improve lookup
+
+	list_for_each_entry(rdev, &self->topology.devlist, list) {
+		if (hwaddr_equal(rdev->aladdr, aladdr))
+			break;
+	}
+
+	return rdev;
+}
+
+int i1905_dm_neighbor_update(struct i1905_interface *iface, uint8_t *aladdr,
+			     struct tlv *t)
+{
+	struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device;
+	struct i1905_interface *rif = NULL;
+	struct i1905_device *rdev = NULL;
+	int origin = 0;
+	int found = 0;
+	int ret;
+
+	rdev = i1905_dm_neighbor_lookup(iface, aladdr);
+	if (!rdev) {
+		fprintf(stderr, "ALERT! received topo response without request!\n");
+		return -1;
+	}
+
+	switch (t->type) {
+	case TLV_TYPE_DEVICE_INFORMATION_TYPE:
+		break;
+	case TLV_TYPE_DEVICE_BRIDGING_CAPABILITIES:
+		break;
+	case TLV_TYPE_NON_1905_NEIGHBOR_DEVICE_LIST:
+		break;
+	case TLV_TYPE_NEIGHBOR_DEVICE_LIST:
+		break;
+	case TLV_TYPE_POWER_OFF_INTERFACE:
+		break;
+	case TLV_TYPE_L2_NEIGHBOR_DEVICE:
+		break;
+	default:
+		fprintf(stderr, "%s: Unhandled TLV %d\n", __func__, t->type);
+		break;
+	}
+
+	return 0;
+}
+
+int i1905_dm_neighbor_discovered(struct i1905_interface *iface, uint8_t *aladdr,
+				 uint8_t *macaddr)
+{
+	struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device;
+	struct i1905_interface *rif = NULL;
+	struct i1905_device *rdev = NULL;
+
+
+
+	/* This function looksup neighbor device in DM.
+	 * If present, then updates tsp.
+	 * Moreover, if last-updated-tsp = 0 or > 10s, sends topo query.
+	 */
+
+	rdev = i1905_dm_neighbor_lookup(iface, aladdr);
+	if (!rdev) {
+		rdev = i1905_dm_neighbor_create();
+		if (!rdev) {
+			fprintf(stderr, "%s: failed to create nbr-device\n", __func__);
+			return -1;
+		}
+
+		memcpy(rdev->aladdr, aladdr, 6);
+		list_add_tail(&rdev->list, &self->topology.devlist);
+	}
+
+	//TODO: update timestamp of rdev
+
+	/* record macaddr of origin interface if not already done */
+	if (macaddr && !hwaddr_equal(aladdr, macaddr)) {
+
+		list_for_each_entry(rif, &rdev->iflist, list) {
+			if (hwaddr_equal(rif->macaddr, macaddr)) {
+				/* nothing to do; origin is already known */
+				return 0;
+			}
+		}
+
+		rif = i1905_dm_neighbor_interface_create();
+		if (!rif) {
+			fprintf(stderr, "%s: failed to create nbr-iface\n", __func__);
+			return -1;
+		}
+
+		memcpy(rif->macaddr, macaddr, 6);
+		memcpy(rif->aladdr, aladdr, 6);
+		rif->device = rdev;
+		rif->priv = NULL;
+
+		list_add_tail(&rif->list, &rdev->iflist);
+	}
+
+	return 0;
+}
+
+int i1905_dm_neighbor_changed(struct i1905_interface *iface, uint8_t *aladdr)
+{
+	struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device;
+	struct i1905_device *rdev = NULL;
+
+
+	/* This function looksup neighbor device in DM.
+	 * If present, then updates tsp and flag 'changed'.
+	 * Moreover, it sends topo query to know what changed.
+	 */
+
+	rdev = i1905_dm_neighbor_lookup(iface, aladdr);
+	if (!rdev) {
+		rdev = i1905_dm_neighbor_create();
+		if (!rdev) {
+			fprintf(stderr,
+				"%s: failed to create nbr-device\n", __func__);
+			return -1;
+		}
+
+		memcpy(rdev->aladdr, aladdr, 6);
+		list_add_tail(&rdev->list, &self->topology.devlist);
+	}
+
+	//TODO: update timestamp of rdev
+	rdev->changed = true;
+
+	//TODO: send topo query
 
 	return 0;
 }
 
 int i1905_dm_init(struct i1905_dm *dm)
 {
+	struct i1905_selfdevice *self = &dm->self;
+
+	memset(self, 0, sizeof(*self));
+
+	self->version = I1905_VERSION_DOT_1A;
+	self->regband = I1905_REGISTRAR_NONE;
+	self->num_interface = 0;
+	INIT_LIST_HEAD(&self->iflist);
+
+	self->fwd.allow = true;
+	INIT_LIST_HEAD(&self->fwd.rulelist);
 
-	memset(dm->macaddr, 0, 6);
+	self->topology.enable = 0;
+	self->topology.status = 0;
+	self->topology.num_devices = 0;
+	INIT_LIST_HEAD(&self->topology.devlist);
 
-	INIT_LIST_HEAD(&dm->reglist);
-	INIT_LIST_HEAD(&dm->iflist);
-	INIT_LIST_HEAD(&dm->devlist);
+	self->security.method = I1905_SECURITY_PBC;
 
-	INIT_LIST_HEAD(&dm->fwd.rulelist);
+	INIT_LIST_HEAD(&self->reglist);
 
 	return 0;
 }
diff --git a/src/i1905_dm.h b/src/i1905_dm.h
index 0c9b5c702caf8e420a395eb3a71931251b592186..55b5b2c857d542bd8de3893247a92d0e9caaf015 100644
--- a/src/i1905_dm.h
+++ b/src/i1905_dm.h
@@ -6,6 +6,9 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 
 enum i1905_version {
 	I1905_VERSION_DOT_1,
@@ -14,15 +17,17 @@ enum i1905_version {
 };
 
 enum i1905_registrar_type {
-	I1905_REGISTRAR_2G,
-	I1905_REGISTRAR_5G,
-	I1905_REGISTRAR_60G,
+	I1905_REGISTRAR_NONE,
+	I1905_REGISTRAR_2G    = 1 << 0,
+	I1905_REGISTRAR_5G    = 1 << 1,
+	I1905_REGISTRAR_60G   = 1 << 2,
 
-	_I1905_REGISTRAR_MAX,
-	I1905_NUM_REGISTRAR = _I1905_REGISTRAR_MAX,
+	//_I1905_REGISTRAR_MAX,
+	//I1905_NUM_REGISTRAR = _I1905_REGISTRAR_MAX,
 };
 
 enum i1905_security_method {
+	I1905_SECURITY_UNKNOWN,
 	I1905_SECURITY_UCPK,
 	I1905_SECURITY_PBC,
 	I1905_SECURITY_NFC,
@@ -52,7 +57,7 @@ struct i1905_rinterface {
 	struct list_head list;
 };
 
-struct i1905_neighbor {
+struct i1905_net_neighbor {
 	uint8_t macaddr[6];
 	uint8_t num_ifaces;
 	struct list_head riflist;	/* list of struct i1905_rinterface */
@@ -143,29 +148,75 @@ struct i1905_interface {
 	uint8_t macaddr[6];
 	uint8_t aladdr[6];		/* FIXME: or have i1905_device ptr? */
 	uint32_t ifstatus;
+	void *device;			/* points to device it belongs */
+
 	enum i1905_mediatype media;	/* media type */
+	uint8_t *mediainfo;		/* ieee80211_info, ieee1901_info etc. */
+
 	struct i1905_genphy genphy;
+
 	bool allow_ifpower;		/* allow set power state ? */
 	enum i1905_ifpowerstate power;
 
+	uint32_t num_vendor;
 	struct list_head vendorlist;	/* list of vendor properties */
+
+	uint32_t num_links;
 	struct list_head iflinklist;	/* list of interface links */
-	struct list_head nbrlist;       /* list of struct i1905_neighbor */
+
+
+	struct list_head nbrlist;       /* TODO: needed ? */
+
 	struct list_head list;
 	void *priv;			/* interface private data */
 };
 
-
 struct i1905_security {
-	//enum i1905_sectype method;	//TODO
+	enum i1905_security_method method;
 	uint8_t password[64];
 };
 
-struct i1905_device {
-	//uint32_t tsp;
+
+enum ip4addr_type {
+	IP4_TYPE_UNKNOWN,
+	IP4_TYPE_DHCP,
+	IP4_TYPE_STATIC,
+	IP4_TYPE_AUTOIP,
+};
+
+struct i1905_ipv4 {
+	uint8_t macaddr[6];
+	struct in_addr addr;
+	enum ip4addr_type type;
+	struct in_addr dhcpserver;
+	struct list_head list;
+};
+
+enum ip6addr_type {
+	IP6_TYPE_UNKNOWN,
+	IP6_TYPE_LINKLOCAL,
+	IP6_TYPE_DHCP,
+	IP6_TYPE_STATIC,
+	IP6_TYPE_SLAAC,
+};
+
+struct i1905_ipv6 {
 	uint8_t macaddr[6];
+	struct in6_addr addr;
+	enum ip6addr_type type;
+	struct in6_addr origin;
+	struct list_head list;
+};
+
+/* represents another 1905 device in the network */
+struct i1905_device {
+	uint32_t tsp;
+	bool changed;			/* flag topo change notification */
+	bool enabled;
+	uint8_t aladdr[6];		/* AL macaddress */
 	enum i1905_version version;
-	struct list_head reglist;	/* list of struct i1905_registrar */
+	uint8_t regband;		/* bitmap of i1905_registrar_type */
+
 	char name[128];			/* friendly name */
 	char manufacturer[128];
 	char model[128];
@@ -180,21 +231,52 @@ struct i1905_device {
 	uint32_t num_neighbor_l2;
 	uint32_t num_brtuple;
 
-	//TODO ptrs to structs
+	struct list_head ipv4list;	/* list of i1905_ipv4 */
+	struct list_head ipv6list;	/* list of i1905_ipv6 */
+	struct list_head vendorlist;	/* list of i1905_vendor_info */
+	struct list_head iflist;	/* list of i1905_interface */
+	struct list_head non1905_nbrlist;
+	struct list_head nbrlist;       /* list of struct i1905_net_neighbor */
+	struct list_head l2_nbrlist;
+	struct list_head brlist;	/* list of  */
 
-	struct i1905_security security;	// FIXME: needed ?
+	struct i1905_security security;
+	struct list_head reglist;	/* list of i1905_registrar in network */
+
+	struct list_head list;
 };
 
 
-/* 1905 data model */
-struct i1905_dm {
+struct i1905_topology {
+	bool enable;
+	uint8_t status;
+	//TODO: changelog table
+	uint32_t num_devices;
+	struct list_head devlist;	/* list of i1905_device */
+};
+
+/* represents own 1905 device */
+struct i1905_selfdevice {
+	uint32_t tsp;
 	bool enabled;
+	uint8_t aladdr[6];		/* AL macaddress */
 	enum i1905_version version;
-	uint8_t macaddr[6];		/* AL macaddress */
-	struct list_head reglist;	/* list of struct i1905_registrar */
-	struct list_head iflist;	/* list of struct i1905_interface */
-	struct list_head devlist;	/* list of struct i1905_device */
+	uint8_t regband;		/* bitmap of i1905_registrar_type */
+
+	uint32_t num_interface;
+	struct list_head iflist;	/* list of i1905_interface */
+
 	struct i1905_fwdtable fwd;
+	struct i1905_topology topology;
+
+	struct i1905_security security;
+	struct list_head reglist;	/* list of i1905_registrar in network */
+};
+
+
+/* 1905 data model */
+struct i1905_dm {
+	struct i1905_selfdevice self;
 };
 
 
diff --git a/src/i1905_ubus.c b/src/i1905_ubus.c
index 1bf8bdff59eb84c17afa69e86a13d56dbcd85ca3..9916cfb1b71615158dab10c0c4e27e55448ace24 100644
--- a/src/i1905_ubus.c
+++ b/src/i1905_ubus.c
@@ -6,6 +6,8 @@
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <net/if_arp.h>
+#include <net/if.h>
+#include <arpa/inet.h>
 
 #include <json-c/json.h>
 #include <libubox/blobmsg.h>
@@ -338,7 +340,7 @@ int i1905_publish_interface_objects(struct i1905_private *p)
 	int ret = 0;
 
 
-	list_for_each_entry(iface, &p->iflist, list) {
+	list_for_each_entry(iface, &p->dm.self.iflist, list) {
 
 		priv = (struct i1905_interface_private *)iface->priv;
 		snprintf(objname, 63, "i1905.al.%s", iface->ifname);