diff --git a/src/1905_tlvs.h b/src/1905_tlvs.h index c0a87bb2e11bf2bcecfd529ed51e401f915944d0..1949ad70f49f6c6c0e40a7e600709c5d5807cae2 100644 --- a/src/1905_tlvs.h +++ b/src/1905_tlvs.h @@ -8,6 +8,10 @@ #include <stdint.h> +#define ETHERTYPE_1905 0x893a +#define ETHERTYPE_LLDP 0x88cc + + /* 1905 CMDU types */ #define CMDU_TYPE_TOPOLOGY_DISCOVERY 0x0000 #define CMDU_TYPE_TOPOLOGY_NOTIFICATION 0x0001 @@ -200,7 +204,7 @@ struct i1905_neighbor { /* TLV: 1905 neighbor devices */ struct tlv_1905neighbor { uint8_t local_macaddr[6]; - uint8_t num_1905nbrs; + //uint8_t num_1905nbrs; struct i1905_neighbor nbr[]; } __attribute__((packed)); diff --git a/src/i1905.c b/src/i1905.c index c09c5847cc245047d0266947b552381c3e0ee5b7..8ff8292aaf8dae91db729138fee70f7a98cecdc5 100644 --- a/src/i1905.c +++ b/src/i1905.c @@ -43,8 +43,6 @@ #include "lldp_tlvs.h" -#define ETHERTYPE_1905 0x893a -#define ETHERTYPE_LLDP 0x88cc uint8_t MCAST_1905[] = "\x01\x80\xC2\x00\x00\x13"; uint8_t MCAST_LLDP[] = "\x01\x80\xC2\x00\x00\x0E"; @@ -222,7 +220,7 @@ static struct i1905_interface *i1905_alloc_interface(const char *ifname, if (!n) return NULL; - snprintf(n->ifname, 15, "%s", ifname); + snprintf(n->ifname, 16, "%s", ifname); n->ifindex = if_nametoindex(ifname); if_gethwaddr(ifname, n->macaddr); if_getflags(ifname, &n->ifstatus); @@ -478,11 +476,11 @@ static void i1905_recv_1905(struct uloop_fd *fd, unsigned int events) res = recvfrom(pif->sock_1905, rxf->head, 1518, 0, NULL, NULL); if (res == -1) { - fprintf(stderr, "1905 recv error\n"); + //fprintf(stderr, "1905 recv error\n"); break; } - bufprintf(rxf->head, res, "Received data"); + bufprintf(rxf->head, res, "Received 1905 CMDU"); if (*(rxf->head + 12) == 0x81 && *(rxf->head + 13) == 0x00) { /* vlan tagged */ @@ -606,7 +604,7 @@ static void i1905_recv_lldp(struct uloop_fd *fd, unsigned int events) res = recvfrom(pif->sock_lldp, rxf->head, 1518, 0, NULL, NULL); if (res == -1) { - fprintf(stderr, "lldp recv error\n"); + //fprintf(stderr, "lldp recv error\n"); break; } @@ -824,7 +822,7 @@ static int i1905_init_al(struct i1905_private *p) { int ret; - i1905_dm_init(&p->dm); + i1905_dm_init(&p->dm, &p->cfg); ret = i1905_init_interfaces(p); if (ret) @@ -954,8 +952,9 @@ int i1905_run_topology_discovery(struct i1905_private *p) } frm->cdata = (struct cmdu_linear *)(frm->head + 18); - frm->cdata->hdr.type = CMDU_TYPE_TOPOLOGY_DISCOVERY; - frm->cdata->hdr.mid = cmdu_get_next_mid(); + cmdu_set_type(frm, CMDU_TYPE_TOPOLOGY_DISCOVERY); + cmdu_set_mid(frm, cmdu_get_next_mid()); + CMDU_SET_LAST_FRAGMENT(frm->cdata); frm->data = (uint8_t *)(frm->cdata + 1); frm->tail = frm->data; @@ -996,13 +995,14 @@ int i1905_run_topology_discovery(struct i1905_private *p) return -1; } + cmdu_put_eom(frm); + ret = i1905_send_cmdu(iface->priv, MCAST_1905, iface->aladdr, ETHERTYPE_1905, frm); if (ret) { fprintf(stderr, "Error sending TOPOLOGY_DISCOVERY\n"); } - tlv_free_linear(t); cmdu_free(frm); } diff --git a/src/i1905.h b/src/i1905.h index 2e15c22b4d050d03310a616df4df08ea41f8c90e..6a015dc0a6ba1d2d79fca682e9c36eae5b497885 100644 --- a/src/i1905.h +++ b/src/i1905.h @@ -66,6 +66,9 @@ int i1905_cmdu_tx(struct i1905_interface_private *ifp, uint8_t *dst, uint8_t *src, uint16_t type, uint16_t *mid, uint8_t *data, int datalen); +int i1905_send_cmdu(struct i1905_interface_private *ifp, + uint8_t *dst, uint8_t *src, uint16_t ethtype, + struct cmdu_buff *frm); int i1905_process_cmdu(struct i1905_interface_private *pif, struct cmdu_buff *rxf); @@ -83,7 +86,7 @@ struct i1905_extmodule *i1905_load_extmodule(const char *name); int i1905_unload_extmodule(struct i1905_extmodule *mod); struct i1905_dm *i1905_dm_get(); -int i1905_dm_init(struct i1905_dm *dm); +int i1905_dm_init(struct i1905_dm *dm, struct i1905_config *cfg); int i1905_dm_free(struct i1905_dm *dm); int i1905_dm_neighbor_discovered(struct i1905_interface *iface, diff --git a/src/i1905_dm.c b/src/i1905_dm.c index ca2c61c6b516c6ff3427b68239726886a3640247..4ffd6857c245d4c158b2be0cdaef1f31ac3e257f 100644 --- a/src/i1905_dm.c +++ b/src/i1905_dm.c @@ -30,6 +30,7 @@ #include "util.h" #include "bufutil.h" #include "cmdu.h" +#include "config.h" #include "i1905_dm.h" #include "1905_tlvs.h" @@ -127,10 +128,10 @@ struct i1905_interface *i1905_dm_neighbor_interface_lookup(struct i1905_device * list_for_each_entry(rif, &rdev->iflist, list) { if (hwaddr_equal(rif->macaddr, ifmacaddr)) - break; + return rif; } - return rif; + return NULL; } struct i1905_device *i1905_dm_neighbor_lookup(struct i1905_interface *iface, @@ -143,10 +144,10 @@ struct i1905_device *i1905_dm_neighbor_lookup(struct i1905_interface *iface, list_for_each_entry(rdev, &self->topology.devlist, list) { if (hwaddr_equal(rdev->aladdr, aladdr)) - break; + return rdev; } - return rdev; + return NULL; } @@ -196,6 +197,7 @@ int i1905_dm_neighbor_update_nbrlist(struct i1905_device *rdev, struct tlv *t) struct tlv_1905neighbor *nbr = (struct tlv_1905neighbor *)t->data; struct i1905_interface *rif; + uint16_t remlen = tlv_length(t); int j; @@ -217,7 +219,10 @@ int i1905_dm_neighbor_update_nbrlist(struct i1905_device *rdev, struct tlv *t) /* XXX: quickest way is to replace old nbrlist with this one */ list_flush(&rif->nbrlist, struct i1905_net_neighbor, list); - for (j = 0; j < nbr->num_1905nbrs; j++) { + remlen -= 12; /* local_macaddr, aladdr */ + j = 0; + + while (remlen > 0) { struct i1905_net_neighbor *rdev_nbr = NULL; rdev_nbr = i1905_dm_neighbor_nbr_create(); @@ -226,6 +231,8 @@ int i1905_dm_neighbor_update_nbrlist(struct i1905_device *rdev, struct tlv *t) rdev_nbr->br_present = nbr->nbr[j].has_bridge; list_add_tail(&rdev_nbr->list, &rif->nbrlist); } + remlen -= sizeof(struct i1905_neighbor); + j++; } return 0; @@ -383,6 +390,8 @@ int i1905_dm_neighbor_discovered(struct i1905_interface *iface, uint8_t *aladdr, memcpy(rdev->aladdr, aladdr, 6); list_add_tail(&rdev->list, &self->topology.devlist); + fprintf(stderr, "%s: New neighbor " MACFMT " discovered.\n", + __func__, MAC2STR(aladdr)); } //TODO: update timestamp of rdev @@ -446,12 +455,14 @@ int i1905_dm_neighbor_changed(struct i1905_interface *iface, uint8_t *aladdr) return 0; } -int i1905_dm_init(struct i1905_dm *dm) +int i1905_dm_init(struct i1905_dm *dm, struct i1905_config *cfg) { struct i1905_selfdevice *self = &dm->self; memset(self, 0, sizeof(*self)); + self->enabled = true; + memcpy(self->aladdr, cfg->macaddr, 6); self->version = I1905_VERSION_DOT_1A; self->regband = I1905_REGISTRAR_NONE; self->num_interface = 0;