Handle setting of location in lldpctl instead of lldpd.
.Os
.Sh NAME
.Nm lldpctl
-.Nd retrieve neighbors discovered by the LLDP daemon
+.Nd control LLDP daemon
.Sh SYNOPSIS
.Nm
.Op Fl d
+.Op Fl L Ar location
.Op Ar interface ...
.Sh DESCRIPTION
The
.Xr lldpd 8
daemon.
.Pp
-Currently,
+When no specific option is given,
.Nm
-is only able to display the list of discovered neighbors along with
-some of their advertised capabilities.
+displays the list of discovered neighbors along with
+some of their advertised capabilities. If some interfaces are given,
+only those interfaces will be displayed.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl d
Enable more debugging information.
+.It Fl L Ar location
+Enable the transmission of LLDP-MED location TLV for the given
+interfaces. This option can be repeated several times to enable the
+transmission of the location in several formats. Several formats are
+accepted:
+.Bl -tag -width "XX"
+.It Em Coordinate based location
+The format of
+.Ar location
+is
+.Ar 1:48.85667:N:2.2014:E:117.47:m:1
+The first digit is always
+.Ar 1 .
+It is followed by the latitude, a letter for the direction (
+.Ar E
+or
+.Ar W
+for East or West), the longitude and a letter for the direction (
+.Ar N
+or
+.Ar S
+). The next figure is the altitude. It can be expressed in meters (the
+next letter is then
+.Ar m
+) or in floors (the letter should be
+.Ar f
+). The last digit is the datum. It can either be
+.Ar 1
+(WGS84),
+.Ar 2
+(NAD83) or
+.Ar 3
+(NAD83/MLLW).
+.It Em Civic address
+The location can be expressed as an address. The format of the
+location is then
+.Ar 2:FR:6:Commercial Rd:3:Roseville:19:4
+The first digit is always
+.Ar 2 .
+The next two letters are the country code. Then, arguments are paired
+to form the address. The first member of the pair is a digit
+indicating the type of the second member. Here is the list of
+valid types:
+.Bl -tag -width "XXXX." -compact
+.It Sy 0
+Language
+.It Sy 1
+National subdivisions
+.It Sy 2
+County, parish, district
+.It Sy 3
+City, township
+.It Sy 4
+City division, borough, ward
+.It Sy 5
+Neighborhood, block
+.It Sy 6
+Street
+.It Sy 16
+Leading street direction
+.It Sy 17
+Trailing street suffix
+.It Sy 18
+Street suffix
+.It Sy 19
+House number
+.It Sy 20
+House number suffix
+.It Sy 21
+Landmark or vanity address
+.It Sy 22
+Additional location info
+.It Sy 23
+Name
+.It Sy 24
+Postal/ZIP code
+.It Sy 25
+Building
+.It Sy 26
+Unit
+.It Sy 27
+Floor
+.It Sy 28
+Room number
+.It Sy 29
+Place type
+.It Sy 128
+Script
+.El
+.It ECS ELIN
+This is a numerical string using for setting up emergency call. The
+format of the location is then the following:
+.Ar 3:0000000911
+where the first digit should be
+.Ar 3
+and the second argument is the ELIN number.
.El
.Pp
-Optionally, interfaces to display may be specified on the command
-line. By default, all interfaces are displayed.
+When setting a location for a given port, all previous locations are
+erased. To erase all location, just use the empty string. There is
+currently no way to get the location from the command line.
+.El
.Sh FILES
.Bl -tag -width "/var/run/lldpd.socketXX" -compact
.It /var/run/lldpd.socket
.Op Fl m Ar management
.Op Fl p Ar probe time
.Op Fl M Ar class
-.Op Fl L Ar location
.Sh DESCRIPTION
.Nm
is a daemon able to receive and send
will still receive (and publish using SNMP if enabled) those LLDP-MED
TLV but will not send them. Use this option if you don't want to
transmit sensible information like serial numbers.
-.It Fl L Ar location
-Enable the transmission of LLDP-MED location TLV. This option can be
-repeated several times to enable the transmission of the location in
-several formats. Several formats are accepted:
-.Bl -tag -width "XX"
-.It Em Coordinate based location
-The format of
-.Ar location
-is
-.Ar 1:48.85667:N:2.2014:E:117.47:m:1
-The first digit is always
-.Ar 1 .
-It is followed by the latitude, a letter for the direction (
-.Ar E
-or
-.Ar W
-for East or West), the longitude and a letter for the direction (
-.Ar N
-or
-.Ar S
-). The next figure is the altitude. It can be expressed in meters (the
-next letter is then
-.Ar m
-) or in floors (the letter should be
-.Ar f
-). The last digit is the datum. It can either be
-.Ar 1
-(WGS84),
-.Ar 2
-(NAD83) or
-.Ar 3
-(NAD83/MLLW).
-.It Em Civic address
-The location can be expressed as an address. The format of the
-location is then
-.Ar 2:FR:6:Commercial Rd:3:Roseville:19:4
-The first digit is always
-.Ar 2 .
-The next two letters are the country code. Then, arguments are paired
-to form the address. The first member of the pair is a digit
-indicating the type of the second member. Here is the list of
-valid types:
-.Bl -tag -width "XXXX." -compact
-.It Sy 0
-Language
-.It Sy 1
-National subdivisions
-.It Sy 2
-County, parish, district
-.It Sy 3
-City, township
-.It Sy 4
-City division, borough, ward
-.It Sy 5
-Neighborhood, block
-.It Sy 6
-Street
-.It Sy 16
-Leading street direction
-.It Sy 17
-Trailing street suffix
-.It Sy 18
-Street suffix
-.It Sy 19
-House number
-.It Sy 20
-House number suffix
-.It Sy 21
-Landmark or vanity address
-.It Sy 22
-Additional location info
-.It Sy 23
-Name
-.It Sy 24
-Postal/ZIP code
-.It Sy 25
-Building
-.It Sy 26
-Unit
-.It Sy 27
-Floor
-.It Sy 28
-Room number
-.It Sy 29
-Place type
-.It Sy 128
-Script
-.El
-.It ECS ELIN
-This is a numerical string using for setting up emergency call. The
-format of the location is then the following:
-.Ar 3:0000000911
-where the first digit should be
-.Ar 3
-and the second argument is the ELIN number.
-.El
-.Pp
-Locations set using this option are set for all ports. There is
-currently no way to affect different locations to different
-ports. Using this TLV, network connectivity devices usually advertise
-the location of a class III device. Since it is unlikely that all
-devices are in the same location, the location TLV should be different
-for each port. This is not possible actually.
-.Pp
-Therefore, this option is likely to be removed in the future and will
-moved into
-.Xr lldpctl 8 .
.El
.Sh FILES
.Bl -tag -width "/var/run/lldpd.socketXX" -compact
return (u_char *)&bit;
case LLDP_SNMP_MED_REMOTE_CAP_ENABLED:
*var_len = 1;
- bit = swap_bits(hardware->h_rchassis->c_med_cap_enabled);
+ bit = swap_bits(hardware->h_rport->p_med_cap_enabled);
return (u_char *)&bit;
case LLDP_SNMP_MED_REMOTE_POE_DEVICETYPE:
- switch (hardware->h_rchassis->c_med_pow_devicetype) {
+ switch (hardware->h_rport->p_med_pow_devicetype) {
case LLDPMED_POW_TYPE_PSE:
long_ret = 2; break;
case LLDPMED_POW_TYPE_PD:
case LLDP_SNMP_MED_REMOTE_POE_PSE_POWERVAL:
case LLDP_SNMP_MED_REMOTE_POE_PD_POWERVAL:
if (((vp->magic == LLDP_SNMP_MED_REMOTE_POE_PSE_POWERVAL) &&
- (hardware->h_rchassis->c_med_pow_devicetype ==
+ (hardware->h_rport->p_med_pow_devicetype ==
LLDPMED_POW_TYPE_PSE)) ||
((vp->magic == LLDP_SNMP_MED_REMOTE_POE_PD_POWERVAL) &&
- (hardware->h_rchassis->c_med_pow_devicetype ==
+ (hardware->h_rport->p_med_pow_devicetype ==
LLDPMED_POW_TYPE_PD))) {
- long_ret = hardware->h_rchassis->c_med_pow_val;
+ long_ret = hardware->h_rport->p_med_pow_val;
return (u_char *)&long_ret;
}
break;
case LLDP_SNMP_MED_REMOTE_POE_PSE_POWERSOURCE:
- if (hardware->h_rchassis->c_med_pow_devicetype ==
+ if (hardware->h_rport->p_med_pow_devicetype ==
LLDPMED_POW_TYPE_PSE) {
- switch (hardware->h_rchassis->c_med_pow_source) {
+ switch (hardware->h_rport->p_med_pow_source) {
case LLDPMED_POW_SOURCE_PRIMARY:
long_ret = 2; break;
case LLDPMED_POW_SOURCE_BACKUP:
}
break;
case LLDP_SNMP_MED_REMOTE_POE_PD_POWERSOURCE:
- if (hardware->h_rchassis->c_med_pow_devicetype ==
+ if (hardware->h_rport->p_med_pow_devicetype ==
LLDPMED_POW_TYPE_PD) {
- switch (hardware->h_rchassis->c_med_pow_source) {
+ switch (hardware->h_rport->p_med_pow_source) {
case LLDPMED_POW_SOURCE_PSE:
long_ret = 2; break;
case LLDPMED_POW_SOURCE_LOCAL:
case LLDP_SNMP_MED_REMOTE_POE_PSE_POWERPRIORITY:
case LLDP_SNMP_MED_REMOTE_POE_PD_POWERPRIORITY:
if (((vp->magic == LLDP_SNMP_MED_REMOTE_POE_PSE_POWERPRIORITY) &&
- (hardware->h_rchassis->c_med_pow_devicetype ==
+ (hardware->h_rport->p_med_pow_devicetype ==
LLDPMED_POW_TYPE_PSE)) ||
((vp->magic == LLDP_SNMP_MED_REMOTE_POE_PD_POWERPRIORITY) &&
- (hardware->h_rchassis->c_med_pow_devicetype ==
+ (hardware->h_rport->p_med_pow_devicetype ==
LLDPMED_POW_TYPE_PD))) {
- switch (hardware->h_rchassis->c_med_pow_priority) {
+ switch (hardware->h_rport->p_med_pow_priority) {
case LLDPMED_POW_PRIO_CRITICAL:
long_ret = 2; break;
case LLDPMED_POW_PRIO_HIGH:
type = name[*length - 1];
if ((type < 1) || (type > LLDPMED_APPTYPE_LAST))
goto remotemedpolicy_failed;
- policy = &hardware->h_rchassis->c_med_policy[type-1];
+ policy = &hardware->h_rport->p_med_policy[type-1];
if (policy->type != type)
goto remotemedpolicy_failed;
type = name[*length - 1];
if ((type < 1) || (type > LLDPMED_APPTYPE_LAST))
goto remotemedlocation_failed;
- location = &hardware->h_rchassis->c_med_location[type-1];
+ location = &hardware->h_rport->p_med_location[type-1];
if (location->format != type)
goto remotemedlocation_failed;
struct client_handle client_handles[] = {
{ HMSG_NONE, client_handle_none },
{ HMSG_GET_INTERFACES, client_handle_get_interfaces },
- { HMSG_GET_CHASSIS, client_handle_get_port_related },
- { HMSG_GET_PORT, client_handle_get_port_related },
+ { HMSG_GET_CHASSIS, client_handle_port_related },
+ { HMSG_GET_PORT, client_handle_port_related },
+#ifdef ENABLE_LLDPMED
+ { HMSG_SET_LOCATION, client_handle_port_related },
+#endif
#ifdef ENABLE_DOT1
- { HMSG_GET_VLANS, client_handle_get_port_related },
+ { HMSG_GET_VLANS, client_handle_port_related },
#endif
{ HMSG_SHUTDOWN, client_handle_shutdown },
{ 0, NULL } };
return;
}
- if ((t = (struct hmsg*)calloc(1, MAX_HMSGSIZE)) == NULL) {
+ if ((t = (struct hmsg*)malloc(MAX_HMSGSIZE)) == NULL) {
LLOG_WARNX("unable to allocate memory to answer to %d",
h->hdr.pid);
return;
}
void
-client_handle_get_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s)
+client_handle_port_related(struct lldpd *cfg, struct hmsg *r, struct hmsg *s)
{
char *ifname;
struct lldpd_hardware *hardware;
void *p;
+ int i;
ifname = (char*)(&r->data);
- if (ifname[r->hdr.len - 1] != 0) {
- LLOG_WARNX("bad message format for get port related message");
+ if ((r->hdr.len < IFNAMSIZ) || (ifname[IFNAMSIZ - 1] != 0)) {
+ LLOG_WARNX("bad message format for get port related message (%d)",
+ r->hdr.type);
s->hdr.len = -1;
return;
}
TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
if (strncmp(ifname, hardware->h_ifname, IFNAMSIZ) == 0) {
- if ((hardware->h_rport == NULL) ||
- (hardware->h_rchassis == NULL)) {
- s->hdr.len = 0;
- s->hdr.type = HMSG_NONE;
- return;
+ if (r->hdr.type != HMSG_SET_LOCATION) {
+ if ((hardware->h_rport == NULL) ||
+ (hardware->h_rchassis == NULL)) {
+ s->hdr.len = 0;
+ s->hdr.type = HMSG_NONE;
+ return;
+ }
}
p = &s->data;
switch (r->hdr.type) {
+#ifdef ENABLE_LLDPMED
+ case HMSG_SET_LOCATION:
+ p = (char*)&r->data + IFNAMSIZ;
+ for (i=0; i < LLDPMED_LOCFORMAT_LAST; i++) {
+ free(hardware->h_lport.p_med_location[i].data);
+ hardware->h_lport.p_med_location[i].data = NULL;
+ hardware->h_lport.p_med_location[i].format = 0;
+ }
+ if (ctl_msg_unpack_structure(STRUCT_LLDPD_MED_LOC
+ STRUCT_LLDPD_MED_LOC STRUCT_LLDPD_MED_LOC,
+ hardware->h_lport.p_med_location,
+ 3*sizeof(struct lldpd_med_loc), r, &p) == -1) {
+ LLOG_WARNX("unable to set location for %s", ifname);
+ s->hdr.len = -1;
+ return;
+ }
+ hardware->h_lport.p_med_cap_enabled |= LLDPMED_CAP_LOCATION;
+ break;
+#endif
#ifdef ENABLE_DOT1
case HMSG_GET_VLANS:
if (ctl_msg_pack_list(STRUCT_LLDPD_VLAN,
void
ctl_msg_init(struct hmsg *t, enum hmsg_type type)
{
+ memset(t, 0, MAX_HMSGSIZE);
t->hdr.type = type;
t->hdr.len = 0;
t->hdr.pid = getpid();
#endif
#ifdef ENABLE_LLDPMED
- if (global->g_lchassis.c_med_cap_enabled) {
+ if (port->p_med_cap_enabled) {
/* LLDP-MED cap */
memset(&medcap, 0, sizeof(medcap));
medcap.tlv_head.type_len = LLDP_TLV_HEAD(LLDP_TLV_ORG,
iov[c].iov_len = len; \
}
- if (global->g_lchassis.c_med_cap_enabled & LLDPMED_CAP_IV) {
+ if (port->p_med_cap_enabled & LLDPMED_CAP_IV) {
LLDP_INVENTORY(global->g_lchassis.c_med_hw,
medhw, LLDP_TLV_MED_IV_HW);
LLDP_INVENTORY(global->g_lchassis.c_med_fw,
/* LLDP-MED location */
for (i = 0; i < LLDPMED_LOCFORMAT_LAST; i++) {
- if (global->g_lchassis.c_med_location[i].format == i + 1) {
+ if (port->p_med_location[i].format == i + 1) {
memset(&medloc[i], 0, sizeof(struct lldp_org));
medloc[i].tlv_head.type_len =
LLDP_TLV_HEAD(LLDP_TLV_ORG,
sizeof(medloc[i].tlv_org_id) +
sizeof(medloc[i].tlv_org_subtype) + 1 +
- global->g_lchassis.c_med_location[i].data_len);
+ port->p_med_location[i].data_len);
memcpy(medloc[i].tlv_org_id, med,
sizeof(medloc[i].tlv_org_id));
medloc[i].tlv_org_subtype = LLDP_TLV_MED_LOCATION;
iov[c].iov_len = sizeof(medloc[i]);
IOV_NEW;
iov[c].iov_base =
- &global->g_lchassis.c_med_location[i].format;
+ &port->p_med_location[i].format;
iov[c].iov_len = 1;
IOV_NEW;
iov[c].iov_base =
- global->g_lchassis.c_med_location[i].data;
+ port->p_med_location[i].data;
iov[c].iov_len =
- global->g_lchassis.c_med_location[i].data_len;
+ port->p_med_location[i].data_len;
}
}
}
chassis->c_med_type =
*(u_int8_t*)(frame + f);
f += size - 6;
- chassis->c_med_cap_enabled |=
+ port->p_med_cap_enabled |=
LLDPMED_CAP_CAP;
break;
case LLDP_TLV_MED_POLICY:
f += 4;
break;
}
- chassis->c_med_policy[(policy >> 24) - 1].type =
+ port->p_med_policy[(policy >> 24) - 1].type =
(policy >> 24);
- chassis->c_med_policy[(policy >> 24) - 1].unknown =
+ port->p_med_policy[(policy >> 24) - 1].unknown =
((policy & 0x800000) != 0);
- chassis->c_med_policy[(policy >> 24) - 1].tagged =
+ port->p_med_policy[(policy >> 24) - 1].tagged =
((policy & 0x400000) != 0);
- chassis->c_med_policy[(policy >> 24) - 1].vid =
+ port->p_med_policy[(policy >> 24) - 1].vid =
(policy & 0x001FFE00) >> 9;
- chassis->c_med_policy[(policy >> 24) - 1].priority =
+ port->p_med_policy[(policy >> 24) - 1].priority =
(policy & 0x1C0) >> 6;
- chassis->c_med_policy[(policy >> 24) - 1].dscp =
+ port->p_med_policy[(policy >> 24) - 1].dscp =
policy & 0x3F;
f += size - 4;
- chassis->c_med_cap_enabled |=
+ port->p_med_cap_enabled |=
LLDPMED_CAP_POLICY;
break;
case LLDP_TLV_MED_LOCATION:
f += size - 5;
break;
}
- if ((chassis->c_med_location[loctype - 1].data =
+ if ((port->p_med_location[loctype - 1].data =
(char*)malloc(size - 5)) == NULL) {
LLOG_WARN("unable to allocate memory "
"for LLDP-MED location for "
hardware->h_ifname);
goto malformed;
}
- memcpy(chassis->c_med_location[loctype - 1].data,
+ memcpy(port->p_med_location[loctype - 1].data,
(char*)(frame + f),
size - 5);
- chassis->c_med_location[loctype - 1].data_len =
+ port->p_med_location[loctype - 1].data_len =
size - 5;
- chassis->c_med_location[loctype - 1].format = loctype;
+ port->p_med_location[loctype - 1].format = loctype;
f += size - 5;
- chassis->c_med_cap_enabled |=
+ port->p_med_cap_enabled |=
LLDPMED_CAP_LOCATION;
break;
case LLDP_TLV_MED_MDI:
}
switch (*(u_int8_t*)(frame + f) & 0xC0) {
case 0x0:
- chassis->c_med_pow_devicetype = LLDPMED_POW_TYPE_PSE;
- chassis->c_med_cap_enabled |=
+ port->p_med_pow_devicetype = LLDPMED_POW_TYPE_PSE;
+ port->p_med_cap_enabled |=
LLDPMED_CAP_MDI_PSE;
switch (*(u_int8_t*)(frame + f) & 0x30) {
case 0x0:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_UNKNOWN;
break;
case 0x10:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_PRIMARY;
break;
case 0x20:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_BACKUP;
break;
default:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_RESERVED;
}
break;
case 0x40:
- chassis->c_med_pow_devicetype = LLDPMED_POW_TYPE_PD;
- chassis->c_med_cap_enabled |=
+ port->p_med_pow_devicetype = LLDPMED_POW_TYPE_PD;
+ port->p_med_cap_enabled |=
LLDPMED_CAP_MDI_PD;
switch (*(u_int8_t*)(frame + f) & 0x30) {
case 0x0:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_UNKNOWN;
break;
case 0x10:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_PSE;
break;
case 0x20:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_LOCAL;
break;
default:
- chassis->c_med_pow_source =
+ port->p_med_pow_source =
LLDPMED_POW_SOURCE_BOTH;
}
break;
default:
- chassis->c_med_pow_devicetype =
+ port->p_med_pow_devicetype =
LLDPMED_POW_TYPE_RESERVED;
}
switch (*(u_int8_t*)(frame + f) & 0x0F) {
case 0x0:
- chassis->c_med_pow_priority =
+ port->p_med_pow_priority =
LLDPMED_POW_PRIO_UNKNOWN;
break;
case 0x1:
- chassis->c_med_pow_priority =
+ port->p_med_pow_priority =
LLDPMED_POW_PRIO_CRITICAL;
break;
case 0x2:
- chassis->c_med_pow_priority =
+ port->p_med_pow_priority =
LLDPMED_POW_PRIO_HIGH;
break;
case 0x3:
- chassis->c_med_pow_priority =
+ port->p_med_pow_priority =
LLDPMED_POW_PRIO_LOW;
break;
default:
- chassis->c_med_pow_priority =
+ port->p_med_pow_priority =
LLDPMED_POW_PRIO_UNKNOWN;
}
f += 1;
- chassis->c_med_pow_val =
+ port->p_med_pow_val =
ntohs(*(u_int16_t*)(frame + f));
f += size - 5;
break;
break;
}
f += size - 4;
- chassis->c_med_cap_enabled |=
+ port->p_med_cap_enabled |=
LLDPMED_CAP_IV;
break;
default:
{
extern const char *__progname;
- fprintf(stderr, "usage: %s [-d]\n", __progname);
+ fprintf(stderr, "usage: %s [options]\n", __progname);
+ fprintf(stderr, "see manual page lldpctl(8) for more information\n");
exit(1);
}
if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL)
fatal(NULL);
ctl_msg_init(h, HMSG_GET_VLANS);
- h->hdr.len += strlcpy((char *)&h->data, interface,
- MAX_HMSGSIZE - sizeof(struct hmsg_hdr)) + 1;
+ strlcpy((char *)&h->data, interface, IFNAMSIZ);
+ h->hdr.len += IFNAMSIZ;
if (ctl_msg_send(s, h) == -1)
fatalx("get_vlans: unable to send request");
if (ctl_msg_recv(s, h) == -1)
if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL)
fatal(NULL);
ctl_msg_init(h, HMSG_GET_CHASSIS);
- h->hdr.len += strlcpy((char *)&h->data, interface,
- MAX_HMSGSIZE - sizeof(struct hmsg_hdr)) + 1;
+ strlcpy((char *)&h->data, interface, IFNAMSIZ);
+ h->hdr.len += IFNAMSIZ;
if (ctl_msg_send(s, h) == -1)
fatalx("get_chassis: unable to send request to get chassis");
if (ctl_msg_recv(s, h) == -1)
if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL)
fatal(NULL);
ctl_msg_init(h, HMSG_GET_PORT);
- h->hdr.len += strlcpy((char *)&h->data, interface,
- MAX_HMSGSIZE - sizeof(struct hmsg_hdr)) + 1;
+ strlcpy((char *)&h->data, interface, IFNAMSIZ);
+ h->hdr.len += IFNAMSIZ;
if (ctl_msg_send(s, h) == -1)
fatalx("get_port: unable to send request to get port");
if (ctl_msg_recv(s, h) == -1)
}
void
-display_med(struct lldpd_chassis *chassis)
+display_med(struct lldpd_chassis *chassis, struct lldpd_port *port)
{
int i;
char *value;
printf(" Inventory");
printf("\n");
for (i = 0; i < LLDPMED_APPTYPE_LAST; i++) {
- if (i+1 == chassis->c_med_policy[i].type) {
+ if (i+1 == port->p_med_policy[i].type) {
printf(" LLDP-MED Network Policy for ");
- switch(chassis->c_med_policy[i].type) {
+ switch(port->p_med_policy[i].type) {
case LLDPMED_APPTYPE_VOICE:
printf("Voice");
break;
printf("Reserved");
}
printf(":\n Policy: ");
- if (chassis->c_med_policy[i].unknown) {
+ if (port->p_med_policy[i].unknown) {
printf("unknown, ");
} else {
printf("defined, ");
}
- if (!chassis->c_med_policy[i].tagged) {
+ if (!port->p_med_policy[i].tagged) {
printf("un");
}
printf("tagged");
printf("\n VLAN ID: ");
- if (chassis->c_med_policy[i].vid == 0) {
+ if (port->p_med_policy[i].vid == 0) {
printf("Priority Tagged");
- } else if (chassis->c_med_policy[i].vid == 4095) {
+ } else if (port->p_med_policy[i].vid == 4095) {
printf("reserved");
} else {
- printf("%u", chassis->c_med_policy[i].vid);
+ printf("%u", port->p_med_policy[i].vid);
}
printf("\n Layer 2 Priority: ");
- printf("%u", chassis->c_med_policy[i].priority);
+ printf("%u", port->p_med_policy[i].priority);
printf("\n DSCP Value: ");
- printf("%u\n", chassis->c_med_policy[i].dscp);
+ printf("%u\n", port->p_med_policy[i].dscp);
}
}
for (i = 0; i < LLDPMED_LOCFORMAT_LAST; i++) {
- if (i+1 == chassis->c_med_location[i].format) {
+ if (i+1 == port->p_med_location[i].format) {
printf(" LLDP-MED Location Identification: ");
- switch(chassis->c_med_location[i].format) {
+ switch(port->p_med_location[i].format) {
case LLDPMED_LOCFORMAT_COORD:
printf("\n Coordinate-based data: ");
- if (chassis->c_med_location[i].data_len != 16)
+ if (port->p_med_location[i].data_len != 16)
printf("bad data length");
else {
u_int64_t l;
/* Latitude and longitude */
- l = (ntohll(*(u_int64_t*)chassis->c_med_location[i].data) &
+ l = (ntohll(*(u_int64_t*)port->p_med_location[i].data) &
0x03FFFFFFFF000000ULL) >> 24;
display_latitude_or_longitude(0, l);
printf(", ");
- l = (ntohll(*(u_int64_t*)(chassis->c_med_location[i].data + 5)) &
+ l = (ntohll(*(u_int64_t*)(port->p_med_location[i].data + 5)) &
0x03FFFFFFFF000000ULL) >> 24;
display_latitude_or_longitude(1, l);
/* Altitude */
printf(", ");
- l = (ntohll(*(u_int64_t*)(chassis->c_med_location[i].data + 10)) &
+ l = (ntohll(*(u_int64_t*)(port->p_med_location[i].data + 10)) &
0x3FFFFFFF000000ULL) >> 24;
display_fixed_precision(l, 22, 8, 1);
- switch ((*(u_int8_t*)(chassis->c_med_location[i].data +
+ switch ((*(u_int8_t*)(port->p_med_location[i].data +
10)) & 0xf0) {
case (1 << 4):
printf(" meters"); break;
}
/* Datum */
- switch (*(u_int8_t*)(chassis->c_med_location[i].data +
+ switch (*(u_int8_t*)(port->p_med_location[i].data +
15)) {
case 1:
printf(", WGS84"); break;
break;
case LLDPMED_LOCFORMAT_CIVIC:
printf("Civic address: ");
- if ((chassis->c_med_location[i].data_len < 3) ||
- (chassis->c_med_location[i].data_len - 1 !=
- *(u_int8_t*)chassis->c_med_location[i].data))
+ if ((port->p_med_location[i].data_len < 3) ||
+ (port->p_med_location[i].data_len - 1 !=
+ *(u_int8_t*)port->p_med_location[i].data))
printf("bad data length");
else {
int l = 4, n, catype, calength, j = 0;
printf("\n%28s: %c%c", "Country",
- ((char *)chassis->c_med_location[i].data)[2],
- ((char *)chassis->c_med_location[i].data)[3]);
- while ((n = (chassis->
- c_med_location[i].data_len - l)) >= 2) {
- catype = *(u_int8_t*)(chassis->
- c_med_location[i].data + l);
- calength = *(u_int8_t*)(chassis->
- c_med_location[i].data + l + 1);
+ ((char *)port->p_med_location[i].data)[2],
+ ((char *)port->p_med_location[i].data)[3]);
+ while ((n = (port->
+ p_med_location[i].data_len - l)) >= 2) {
+ catype = *(u_int8_t*)(port->
+ p_med_location[i].data + l);
+ calength = *(u_int8_t*)(port->
+ p_med_location[i].data + l + 1);
if (n < 2 + calength) {
printf("bad data length");
break;
printf("unknown type %d", catype);
break;
}
- if ((value = strndup((char *)(chassis->
- c_med_location[i].data + l + 2),
+ if ((value = strndup((char *)(port->
+ p_med_location[i].data + l + 2),
calength)) == NULL) {
printf("not enough memory");
break;
}
break;
case LLDPMED_LOCFORMAT_ELIN:
- if ((value = strndup((char *)(chassis->
- c_med_location[i].data),
- chassis->c_med_location[i].data_len)) == NULL) {
+ if ((value = strndup((char *)(port->
+ p_med_location[i].data),
+ port->p_med_location[i].data_len)) == NULL) {
printf("not enough memory");
break;
}
break;
default:
printf("unknown location data format: \n %s",
- dump(chassis->c_med_location[i].data,
- chassis->c_med_location[i].data_len, 20, ' '));
+ dump(port->p_med_location[i].data,
+ port->p_med_location[i].data_len, 20, ' '));
}
printf("\n");
}
}
- if (chassis->c_med_pow_devicetype) {
+ if (port->p_med_pow_devicetype) {
printf(" LLDP-MED Extended Power-over-Ethernet:\n");
printf(" Power Type & Source: ");
- switch (chassis->c_med_pow_devicetype) {
+ switch (port->p_med_pow_devicetype) {
case LLDPMED_POW_TYPE_PSE:
printf("PSE Device");
break;
default:
printf("reserved");
}
- switch (chassis->c_med_pow_source) {
+ switch (port->p_med_pow_source) {
case LLDPMED_POW_SOURCE_UNKNOWN:
case LLDPMED_POW_SOURCE_RESERVED:
printf(", unknown"); break;
break;
}
printf("\n Power Priority: ");
- switch (chassis->c_med_pow_priority) {
+ switch (port->p_med_pow_priority) {
case LLDPMED_POW_PRIO_CRITICAL:
printf("critical"); break;
case LLDPMED_POW_PRIO_HIGH:
printf("unknown");
}
printf("\n Power Value: ");
- if(chassis->c_med_pow_val < 1024) {
- printf("%u mW", chassis->c_med_pow_val * 100);
+ if(port->p_med_pow_val < 1024) {
+ printf("%u mW", port->p_med_pow_val * 100);
} else {
printf("reserved");
}
}
#endif
-int
-main(int argc, char *argv[])
+void
+display_interfaces(int s, int argc, char *argv[])
{
- int s, i;
- int ch, debug = 1;
+ int i;
struct interfaces ifs;
#ifdef ENABLE_DOT1
struct vlans vls;
struct lldpd_chassis chassis;
struct lldpd_port port;
char sep[80];
-
- /*
- * Get and parse command line options
- */
- while ((ch = getopt(argc, argv, "d")) != -1) {
- switch (ch) {
- case 'd':
- debug++;
- break;
- default:
- usage();
- }
- }
-
- log_init(debug);
+
memset(sep, '-', 79);
sep[79] = 0;
-
- if ((s = ctl_connect(LLDPD_CTL_SOCKET)) == -1)
- fatalx("unable to connect to socket " LLDPD_CTL_SOCKET);
get_interfaces(s, &ifs);
-
+
printf("%s\n", sep);
printf(" LLDP neighbors\n");
printf("%s\n", sep);
}
#endif
#ifdef ENABLE_LLDPMED
- if (chassis.c_med_cap_enabled) {
+ if (port.p_med_cap_enabled) {
printf("\n");
- display_med(&chassis);
+ display_med(&chassis, &port);
}
#endif
printf("%s\n", sep);
}
}
+}
+
+#ifdef ENABLE_LLDPMED
+int
+lldpd_parse_location(struct lldpd_port *port, const char *location)
+{
+ char *l, *e, *s, *data, *n;
+ double ll, altitude;
+ u_int32_t intpart, floatpart;
+ int type = 0, i;
+
+ if (strlen(location) == 0)
+ return 0;
+ if ((l = strdup(location)) == NULL)
+ fatal(NULL);
+ s = l;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ *e = '\0';
+ type = atoi(s);
+ switch (type) {
+ case LLDPMED_LOCFORMAT_COORD:
+ /* Coordinates */
+ if ((port->p_med_location[0].data =
+ (char *)malloc(16)) == NULL)
+ fatal(NULL);
+ port->p_med_location[0].data_len = 16;
+ port->p_med_location[0].format = LLDPMED_LOCFORMAT_COORD;
+ data = port->p_med_location[0].data;
+
+ /* Latitude and longitude */
+ for (i = 0; i < 2; i++) {
+ s = e+1;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ *e = '\0';
+ ll = atof(s);
+ s = e + 1;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ *e = '\0';
+ intpart = (int)ll;
+ floatpart = (ll - intpart) * (1 << 25);
+ if (((i == 0) && (*s == 'S')) ||
+ ((i == 1) && (*s == 'W'))) {
+ intpart = ~intpart;
+ intpart += 1;
+ floatpart = ~floatpart;
+ floatpart += 1;
+ } else if (((i == 0) && (*s != 'N')) ||
+ ((i == 1) && (*s != 'E')))
+ goto invalid_location;
+ *(u_int8_t *)data = (6 << 2) | /* Precision */
+ ((intpart & 0x180) >> 7); /* Int part 2 bits */
+ data++;
+ *(u_int8_t *)data = (((intpart & 0x7f) << 1) | /* Int part 7 bits */
+ ((floatpart & 0x1000000) >> 24)); /* Float part 1 bit */
+ data++;
+ *(u_int8_t *)data = (floatpart & 0xff0000) >> 16; /* 8 bits */
+ data++;
+ *(u_int8_t *)data = (floatpart & 0xff00) >> 8; /* 8 bits */
+ data++;
+ *(u_int8_t *)data = (floatpart & 0xff); /* 8 bits */
+ data++;
+ }
+
+ /* Altitude */
+ s = e+1;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ *e = '\0';
+ altitude = atof(s);
+ s = e+1;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ *e = '\0';
+ if (altitude < 0) {
+ intpart = -(int)altitude;
+ floatpart = (-(altitude + intpart)) * (1 << 8);
+ intpart = ~intpart; intpart += 1;
+ floatpart = ~floatpart; floatpart += 1;
+ } else {
+ intpart = (int)altitude;
+ floatpart = (altitude - intpart) * (1 << 8);
+ }
+ if ((*s != 'm') && (*s != 'f'))
+ goto invalid_location;
+ *(u_int8_t *)data = ((((*s == 'm')?1:2) << 4) | /* Type 4 bits */
+ 0); /* Precision 4 bits */
+ data++;
+ *(u_int8_t *)data = ((6 << 6) | /* Precision 2 bits */
+ ((intpart & 0x3f0000) >> 16)); /* Int 6 bits */
+ data++;
+ *(u_int8_t *)data = (intpart & 0xff00) >> 8; /* Int 8 bits */
+ data++;
+ *(u_int8_t *)data = intpart & 0xff; /* Int 8 bits */
+ data++;
+ *(u_int8_t *)data = floatpart & 0xff; /* Float 8 bits */
+ data++;
+
+ /* Datum */
+ s = e + 1;
+ if (index(s, ':') != NULL)
+ goto invalid_location;
+ *(u_int8_t *)data = atoi(s);
+ break;
+ case LLDPMED_LOCFORMAT_CIVIC:
+ /* Civic address */
+ port->p_med_location[1].data_len = 4;
+ s = e+1;
+ if ((s = index(s, ':')) == NULL)
+ goto invalid_location;
+ s = s+1;
+ do {
+ if ((s = index(s, ':')) == NULL)
+ break;
+ s = s+1;
+ /* s is the beginning of the word */
+ if ((n = index(s, ':')) == NULL)
+ n = s + strlen(s);
+ /* n is the end of the word */
+ port->p_med_location[1].data_len += (n - s) + 2;
+ if ((s = index(s, ':')) == NULL)
+ break;
+ s = s+1;
+ } while (1);
+ s = e+1;
+ if ((port->p_med_location[1].data =
+ (char *)malloc(port->p_med_location[1].data_len)) ==
+ NULL)
+ fatal(NULL);
+ port->p_med_location[1].format = LLDPMED_LOCFORMAT_CIVIC;
+ data = port->p_med_location[1].data;
+ *(u_int8_t *)data = port->p_med_location[1].data_len - 1;
+ data++;
+ *(u_int8_t *)data = 2; /* Client location */
+ data++;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ if ((e - s) != 2)
+ goto invalid_location;
+ memcpy(data, s, 2); /* Country code */
+ data += 2;
+ while (*e != '\0') {
+ s=e+1;
+ if ((e = index(s, ':')) == NULL)
+ goto invalid_location;
+ *e = '\0';
+ *(u_int8_t *)data = atoi(s);
+ data++;
+ s=e+1;
+ if ((e = index(s, ':')) == NULL)
+ e = s + strlen(s);
+ *(u_int8_t *)data = e - s;
+ data++;
+ memcpy(data, s, e-s);
+ data += e-s;
+ }
+ break;
+ case LLDPMED_LOCFORMAT_ELIN:
+ s = e+1;
+ port->p_med_location[2].data_len = strlen(s);
+ if ((port->p_med_location[2].data =
+ (char *)malloc(strlen(s))) == NULL)
+ fatal(NULL);
+ port->p_med_location[2].format = LLDPMED_LOCFORMAT_ELIN;
+ strcpy(port->p_med_location[2].data, s);
+ break;
+ default:
+ type = 0;
+ goto invalid_location;
+ }
+
+ port->p_med_cap_enabled |= LLDPMED_CAP_LOCATION;
+ return 0;
+invalid_location:
+ LLOG_WARNX("the format of the location is invalid (%s)",
+ location);
+ if (type) {
+ free(port->p_med_location[type-1].data);
+ memset(&port->p_med_location[type-1], 0,
+ sizeof(struct lldpd_med_loc));
+ }
+ free(l);
+ return -1;
+}
+
+void
+set_location(int s, int argc, char *argv[])
+{
+ int i, ch;
+ struct interfaces ifs;
+ struct lldpd_interface *iff;
+ struct lldpd_port port;
+ void *p;
+ struct hmsg *h;
+
+ if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL)
+ fatal(NULL);
+
+ memset(&port, 0, sizeof(struct lldpd_port));
+ optind = 1;
+ while ((ch = getopt(argc, argv, "dL:")) != -1) {
+ switch (ch) {
+ case 'L':
+ if ((lldpd_parse_location(&port, optarg)) == -1)
+ fatalx("incorrect location");
+ break;
+ }
+ }
+
+ get_interfaces(s, &ifs);
+ TAILQ_FOREACH(iff, &ifs, next) {
+ if (optind < argc) {
+ for (i = optind; i < argc; i++)
+ if (strncmp(argv[i], iff->name, IFNAMSIZ) == 0)
+ break;
+ if (i == argc)
+ continue;
+ }
+
+ ctl_msg_init(h, HMSG_SET_LOCATION);
+ strlcpy((char *)&h->data, iff->name, IFNAMSIZ);
+ h->hdr.len += IFNAMSIZ;
+ p = (char*)&h->data + IFNAMSIZ;
+ if (ctl_msg_pack_structure(STRUCT_LLDPD_MED_LOC
+ STRUCT_LLDPD_MED_LOC STRUCT_LLDPD_MED_LOC,
+ port.p_med_location,
+ 3*sizeof(struct lldpd_med_loc), h, &p) == -1) {
+ LLOG_WARNX("set_location: unable to set location for %s", iff->name);
+ fatalx("aborting");
+ }
+ if (ctl_msg_send(s, h) == -1)
+ fatalx("set_location: unable to send request");
+ if (ctl_msg_recv(s, h) == -1)
+ fatalx("set_location: unable to receive answer");
+ if (h->hdr.type != HMSG_SET_LOCATION)
+ fatalx("set_location: unknown answer type received");
+ LLOG_INFO("Location set succesfully for %s", iff->name);
+ }
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int ch, s, debug = 1;
+#define ACTION_SET_LOCATION 1
+ int action = 0;
- close(s);
+ /*
+ * Get and parse command line options
+ */
+ while ((ch = getopt(argc, argv, "dL:")) != -1) {
+ switch (ch) {
+ case 'd':
+ debug++;
+ break;
+ case 'L':
+#ifdef ENABLE_LLDPMED
+ action = ACTION_SET_LOCATION;
+#else
+ fprintf(stderr, "LLDP-MED support is not built-in\n");
+ usage();
+#endif
+ break;
+ default:
+ usage();
+ }
+ }
+
+ log_init(debug);
+ if ((s = ctl_connect(LLDPD_CTL_SOCKET)) == -1)
+ fatalx("unable to connect to socket " LLDPD_CTL_SOCKET);
+
+ switch (action) {
+#ifdef ENABLE_LLDPMED
+ case ACTION_SET_LOCATION:
+ set_location(s, argc, argv);
+ break;
+#endif
+ default:
+ display_interfaces(s, argc, argv);
+ }
+
+ close(s);
return 0;
}
void
lldpd_port_cleanup(struct lldpd_port *port)
{
+#ifdef ENABLE_LLDPMED
+ int i;
+ for (i=0; i < LLDPMED_LOCFORMAT_LAST; i++)
+ free(port->p_med_location[i].data);
+#endif
#ifdef ENABLE_DOT1
lldpd_vlan_cleanup(port);
#endif
lldpd_chassis_cleanup(struct lldpd_chassis *chassis)
{
#ifdef ENABLE_LLDPMED
- int i;
free(chassis->c_med_hw);
free(chassis->c_med_fw);
free(chassis->c_med_sn);
free(chassis->c_med_manuf);
free(chassis->c_med_model);
free(chassis->c_med_asset);
- for (i=0; i < LLDPMED_LOCFORMAT_LAST; i++)
- free(chassis->c_med_location[i].data);
#endif
free(chassis->c_id);
free(chassis->c_name);
hardware->h_raw_real = -1;
hardware->h_start_probe = 0;
hardware->h_proto_macs = (u_int8_t*)calloc(cfg->g_multi+1, ETH_ALEN);
+#ifdef ENABLE_LLDPMED
+ hardware->h_lport.p_med_cap_enabled = LLDPMED_CAP_CAP;
+ if (!cfg->g_noinventory)
+ hardware->h_lport.p_med_cap_enabled |= LLDPMED_CAP_IV;
+#endif
#ifdef ENABLE_DOT1
TAILQ_INIT(&hardware->h_lport.p_vlans);
} else {
lldpd_recv_all(cfg);
}
-#ifdef ENABLE_LLDPMED
-void
-lldpd_parse_location(struct lldpd_chassis *chassis, const char *location)
-{
- char *l, *e, *s, *data, *n;
- double ll, altitude;
- u_int32_t intpart, floatpart;
- int type = 0, i;
-
- if ((l = strdup(location)) == NULL)
- fatal(NULL);
- s = l;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- *e = '\0';
- type = atoi(s);
- switch (type) {
- case LLDPMED_LOCFORMAT_COORD:
- /* Coordinates */
- if ((chassis->c_med_location[0].data =
- (char *)malloc(16)) == NULL)
- fatal(NULL);
- chassis->c_med_location[0].data_len = 16;
- chassis->c_med_location[0].format = LLDPMED_LOCFORMAT_COORD;
- data = chassis->c_med_location[0].data;
-
- /* Latitude and longitude */
- for (i = 0; i < 2; i++) {
- s = e+1;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- *e = '\0';
- ll = atof(s);
- s = e + 1;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- *e = '\0';
- intpart = (int)ll;
- floatpart = (ll - intpart) * (1 << 25);
- if (((i == 0) && (*s == 'S')) ||
- ((i == 1) && (*s == 'W'))) {
- intpart = ~intpart;
- intpart += 1;
- floatpart = ~floatpart;
- floatpart += 1;
- } else if (((i == 0) && (*s != 'N')) ||
- ((i == 1) && (*s != 'E')))
- goto invalid_location;
- *(u_int8_t *)data = (6 << 2) | /* Precision */
- ((intpart & 0x180) >> 7); /* Int part 2 bits */
- data++;
- *(u_int8_t *)data = (((intpart & 0x7f) << 1) | /* Int part 7 bits */
- ((floatpart & 0x1000000) >> 24)); /* Float part 1 bit */
- data++;
- *(u_int8_t *)data = (floatpart & 0xff0000) >> 16; /* 8 bits */
- data++;
- *(u_int8_t *)data = (floatpart & 0xff00) >> 8; /* 8 bits */
- data++;
- *(u_int8_t *)data = (floatpart & 0xff); /* 8 bits */
- data++;
- }
-
- /* Altitude */
- s = e+1;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- *e = '\0';
- altitude = atof(s);
- s = e+1;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- *e = '\0';
- if (altitude < 0) {
- intpart = -(int)altitude;
- floatpart = (-(altitude + intpart)) * (1 << 8);
- intpart = ~intpart; intpart += 1;
- floatpart = ~floatpart; floatpart += 1;
- } else {
- intpart = (int)altitude;
- floatpart = (altitude - intpart) * (1 << 8);
- }
- if ((*s != 'm') && (*s != 'f'))
- goto invalid_location;
- *(u_int8_t *)data = ((((*s == 'm')?1:2) << 4) | /* Type 4 bits */
- 0); /* Precision 4 bits */
- data++;
- *(u_int8_t *)data = ((6 << 6) | /* Precision 2 bits */
- ((intpart & 0x3f0000) >> 16)); /* Int 6 bits */
- data++;
- *(u_int8_t *)data = (intpart & 0xff00) >> 8; /* Int 8 bits */
- data++;
- *(u_int8_t *)data = intpart & 0xff; /* Int 8 bits */
- data++;
- *(u_int8_t *)data = floatpart & 0xff; /* Float 8 bits */
- data++;
-
- /* Datum */
- s = e + 1;
- if (index(s, ':') != NULL)
- goto invalid_location;
- *(u_int8_t *)data = atoi(s);
- break;
- case LLDPMED_LOCFORMAT_CIVIC:
- /* Civic address */
- chassis->c_med_location[1].data_len = 4;
- s = e+1;
- if ((s = index(s, ':')) == NULL)
- goto invalid_location;
- s = s+1;
- do {
- if ((s = index(s, ':')) == NULL)
- break;
- s = s+1;
- /* s is the beginning of the word */
- if ((n = index(s, ':')) == NULL)
- n = s + strlen(s);
- /* n is the end of the word */
- chassis->c_med_location[1].data_len += (n - s) + 2;
- if ((s = index(s, ':')) == NULL)
- break;
- s = s+1;
- } while (1);
- s = e+1;
- if ((chassis->c_med_location[1].data =
- (char *)malloc(chassis->c_med_location[1].data_len)) ==
- NULL)
- fatal(NULL);
- chassis->c_med_location[1].format = LLDPMED_LOCFORMAT_CIVIC;
- data = chassis->c_med_location[1].data;
- *(u_int8_t *)data = chassis->c_med_location[1].data_len - 1;
- data++;
- *(u_int8_t *)data = 2; /* Client location */
- data++;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- if ((e - s) != 2)
- goto invalid_location;
- memcpy(data, s, 2); /* Country code */
- data += 2;
- while (*e != '\0') {
- s=e+1;
- if ((e = index(s, ':')) == NULL)
- goto invalid_location;
- *e = '\0';
- *(u_int8_t *)data = atoi(s);
- data++;
- s=e+1;
- if ((e = index(s, ':')) == NULL)
- e = s + strlen(s);
- *(u_int8_t *)data = e - s;
- data++;
- memcpy(data, s, e-s);
- data += e-s;
- }
- break;
- case LLDPMED_LOCFORMAT_ELIN:
- s = e+1;
- chassis->c_med_location[2].data_len = strlen(s);
- if ((chassis->c_med_location[2].data =
- (char *)malloc(strlen(s))) == NULL)
- fatal(NULL);
- chassis->c_med_location[2].format = LLDPMED_LOCFORMAT_ELIN;
- strcpy(chassis->c_med_location[2].data, s);
- break;
- default:
- goto invalid_location;
- }
-
- chassis->c_med_cap_enabled |= LLDPMED_CAP_LOCATION;
- return;
-invalid_location:
- LLOG_WARNX("the format of the location is invalid (%s)",
- location);
- if (type) {
- free(chassis->c_med_location[type-1].data);
- memset(&chassis->c_med_location[type-1], 0,
- sizeof(struct lldpd_med_loc));
- }
- free(l);
-}
-#endif
-
void
lldpd_shutdown(int sig)
{
int snmp = 0;
#endif
char *mgmtp = NULL;
- char *popt, opts[] = "vdxm:p:M:iL:@ ";
+ char *popt, opts[] = "vdxm:p:M:i@ ";
int probe = 0, i, found, vlan = 0;
#ifdef ENABLE_LLDPMED
int lldpmed = 0, noinventory = 0;
case 'i':
noinventory = 1;
break;
- case 'L':
- /* Handled later */
- break;
#else
case 'M':
case 'i':
- case 'L':
case 'P':
fprintf(stderr, "LLDP-MED support is not built-in\n");
usage();
cfg->g_lchassis.c_med_type = lldpmed;
cfg->g_lchassis.c_med_cap_available = LLDPMED_CAP_CAP |
LLDPMED_CAP_IV | LLDPMED_CAP_LOCATION;
- cfg->g_lchassis.c_med_cap_enabled = LLDPMED_CAP_CAP;
- if (!noinventory)
- cfg->g_lchassis.c_med_cap_enabled |= LLDPMED_CAP_IV;
- optind = 1;
- while ((ch = getopt(argc, argv, opts)) != -1) {
- switch (ch) {
- case 'L':
- lldpd_parse_location(&cfg->g_lchassis, optarg);
- break;
- }
- }
+ cfg->g_noinventory = noinventory;
}
#endif
u_int32_t c_mgmt_if;
#ifdef ENABLE_LLDPMED
-#define STRUCT_LLDPD_CHASSIS_MED \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_POLICY \
- STRUCT_LLDPD_MED_LOC \
- STRUCT_LLDPD_MED_LOC \
- STRUCT_LLDPD_MED_LOC \
- "wwbbbbwsssssss"
-
- struct lldpd_med_policy c_med_policy[LLDPMED_APPTYPE_LAST];
- struct lldpd_med_loc c_med_location[LLDPMED_LOCFORMAT_LAST];
+#define STRUCT_LLDPD_CHASSIS_MED "wwbsssssss"
u_int16_t c_med_cap_available;
- u_int16_t c_med_cap_enabled;
u_int8_t c_med_type;
- u_int8_t c_med_pow_devicetype; /* PD or PSE */
- u_int8_t c_med_pow_source;
- u_int8_t c_med_pow_priority;
- u_int16_t c_med_pow_val;
char *c_med_hw;
char *c_med_fw;
char *c_med_sw;
#define STRUCT_LLDPD_PORT_DOT3 ""
#endif
+#ifdef ENABLE_LLDPMED
+#define STRUCT_LLDPD_PORT_MED "w" \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_POLICY \
+ STRUCT_LLDPD_MED_LOC \
+ STRUCT_LLDPD_MED_LOC \
+ STRUCT_LLDPD_MED_LOC \
+ "bbbw"
+ u_int16_t p_med_cap_enabled;
+ struct lldpd_med_policy p_med_policy[LLDPMED_APPTYPE_LAST];
+ struct lldpd_med_loc p_med_location[LLDPMED_LOCFORMAT_LAST];
+ u_int8_t p_med_pow_devicetype; /* PD or PSE */
+ u_int8_t p_med_pow_source;
+ u_int8_t p_med_pow_priority;
+ u_int16_t p_med_pow_val;
+#else
+#define STRUCT_LLDPD_PORT_MED ""
+#endif
+
+
#ifdef ENABLE_DOT1
#define STRUCT_LLDPD_PORT_DOT1 "wPP"
u_int16_t p_pvid;
#endif
};
-#define STRUCT_LLDPD_PORT "(bCsw" STRUCT_LLDPD_PORT_DOT3 STRUCT_LLDPD_PORT_DOT1 ")"
+#define STRUCT_LLDPD_PORT "(bCsw" \
+ STRUCT_LLDPD_PORT_DOT3 \
+ STRUCT_LLDPD_PORT_MED \
+ STRUCT_LLDPD_PORT_DOT1 ")"
struct lldpd_frame {
int size;
int g_multi; /* Set to 1 if multiple protocols */
int g_probe_time;
int g_listen_vlans;
+#ifdef ENABLE_LLDPMED
+ int g_noinventory;
+#endif
time_t g_lastsent;
int g_lastrid;
HMSG_GET_CHASSIS,
HMSG_GET_PORT,
HMSG_GET_VLANS,
+ HMSG_SET_LOCATION,
HMSG_SHUTDOWN
};
struct hmsg *);
void client_handle_get_interfaces(struct lldpd *, struct hmsg *,
struct hmsg *);
-void client_handle_get_port_related(struct lldpd *, struct hmsg *,
+void client_handle_port_related(struct lldpd *, struct hmsg *,
struct hmsg *);
void client_handle_shutdown(struct lldpd *, struct hmsg *,
struct hmsg *);