+ int last_epoch_microsec_len =
+ sizeof(char) * sizeof(long long unsigned int) * 4 + 1;
+ memset(json_str, '\0', DATA_MAX_NAME_LEN);
+ snprintf(json_str, last_epoch_microsec_len, "%llu",
+ (long long unsigned int)CDTIME_T_TO_US(cdtime()));
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // priority
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_PRIORITY_FIELD,
+ strlen(CONNECTIVITY_PRIORITY_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_PRIORITY_VALUE,
+ strlen(CONNECTIVITY_PRIORITY_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // reportingEntityName
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_REPORTING_ENTITY_NAME_FIELD,
+ strlen(CONNECTIVITY_REPORTING_ENTITY_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_REPORTING_ENTITY_NAME_VALUE,
+ strlen(CONNECTIVITY_REPORTING_ENTITY_NAME_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // sequence
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_SEQUENCE_FIELD,
+ strlen(CONNECTIVITY_SEQUENCE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, CONNECTIVITY_SEQUENCE_VALUE,
+ strlen(CONNECTIVITY_SEQUENCE_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // sourceName
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_SOURCE_NAME_FIELD,
+ strlen(CONNECTIVITY_SOURCE_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)interface, strlen(interface)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // startEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_START_EPOCH_MICROSEC_FIELD,
+ strlen(CONNECTIVITY_START_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ int start_epoch_microsec_len =
+ sizeof(char) * sizeof(long long unsigned int) * 4 + 1;
+ memset(json_str, '\0', DATA_MAX_NAME_LEN);
+ snprintf(json_str, start_epoch_microsec_len, "%llu",
+ (long long unsigned int)timestamp);
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // version
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_VERSION_FIELD,
+ strlen(CONNECTIVITY_VERSION_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, CONNECTIVITY_VERSION_VALUE,
+ strlen(CONNECTIVITY_VERSION_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END common event header ***
+
+ // *** BEGIN state change fields ***
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_STATE_CHANGE_FIELDS_FIELD,
+ strlen(CONNECTIVITY_STATE_CHANGE_FIELDS_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // newState
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_NEW_STATE_FIELD,
+ strlen(CONNECTIVITY_NEW_STATE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ int new_state_len =
+ (state == 0 ? strlen(CONNECTIVITY_NEW_STATE_FIELD_DOWN_VALUE)
+ : strlen(CONNECTIVITY_NEW_STATE_FIELD_UP_VALUE));
+
+ if (yajl_gen_string(
+ g, (u_char *)(state == 0 ? CONNECTIVITY_NEW_STATE_FIELD_DOWN_VALUE
+ : CONNECTIVITY_NEW_STATE_FIELD_UP_VALUE),
+ new_state_len) != yajl_gen_status_ok)
+ goto err;
+
+ // oldState
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_OLD_STATE_FIELD,
+ strlen(CONNECTIVITY_OLD_STATE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ int old_state_len =
+ (old_state == 0 ? strlen(CONNECTIVITY_OLD_STATE_FIELD_DOWN_VALUE)
+ : strlen(CONNECTIVITY_OLD_STATE_FIELD_UP_VALUE));
+
+ if (yajl_gen_string(
+ g, (u_char *)(old_state == 0 ? CONNECTIVITY_OLD_STATE_FIELD_DOWN_VALUE
+ : CONNECTIVITY_OLD_STATE_FIELD_UP_VALUE),
+ old_state_len) != yajl_gen_status_ok)
+ goto err;
+
+ // stateChangeFieldsVersion
+ if (yajl_gen_string(g,
+ (u_char *)CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_FIELD,
+ strlen(CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_VALUE,
+ strlen(CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // stateInterface
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_STATE_INTERFACE_FIELD,
+ strlen(CONNECTIVITY_STATE_INTERFACE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)interface, strlen(interface)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_map_close(g) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END state change fields ***
+
+ if (yajl_gen_map_close(g) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_get_buf(g, &buf2, &len) != yajl_gen_status_ok)
+ goto err;
+
+ *buf = strdup((char *)buf2);
+
+ if (*buf == NULL) {
+ ERROR("connectivity plugin: strdup failed during gen_message_payload: %s",
+ STRERRNO);
+ goto err;
+ }
+
+ yajl_gen_free(g);
+
+ return 0;
+
+err:
+ yajl_gen_free(g);
+ ERROR("connectivity plugin: gen_message_payload failed to generate JSON");
+ return -1;
+}
+
+static interface_list_t *add_interface(const char *interface, int status,
+ int prev_status) {
+ interface_list_t *il = calloc(1, sizeof(*il));
+
+ if (il == NULL) {
+ ERROR("connectivity plugin: calloc failed during add_interface: %s",
+ STRERRNO);
+ return NULL;
+ }
+
+ char *interface2 = strdup(interface);
+ if (interface2 == NULL) {
+ sfree(il);
+ ERROR("connectivity plugin: strdup failed during add_interface: %s",
+ STRERRNO);
+ return NULL;
+ }
+
+ il->interface = interface2;
+ il->status = status;
+ il->prev_status = prev_status;
+ il->timestamp = (long long unsigned int)CDTIME_T_TO_US(cdtime());
+ il->sent = 0;
+ il->next = interface_list_head;
+ interface_list_head = il;
+
+ DEBUG("connectivity plugin: added interface %s", interface2);
+
+ return il;
+}
+
+static int connectivity_link_state(struct nlmsghdr *msg) {
+ pthread_mutex_lock(&connectivity_data_lock);
+
+ struct nlattr *attr;
+ struct ifinfomsg *ifi = mnl_nlmsg_get_payload(msg);