nscp::packet handler_impl::process(const nscp::packet &packet) { nscp::packet response; BOOST_FOREACH(const nscp::data::frame &frame, packet.frames_) { if (frame.header.type == nscp::data::frame_payload) { process_payload(response, frame); } else if (frame.header.type == nscp::data::frame_envelope) { process_header(response, frame); } else if (frame.header.type == nscp::data::frame_error) { process_error(response, frame); } else { this->log_error("nscp:handler", __FILE__, __LINE__, "Unknown packet: " + packet.to_string()); return nscp::factory::create_error("Unknown packet: " + packet.to_string()); } } return response; }
genErr_t process_l7(void *jobj_ref) { debug ("In function %s", __FUNCTION__); struct json_object *jobj = (struct json_object *)jobj_ref; void *tjobj = NULL; tjobj=get_val_from_key(jobj, "payload", lObj); if(tjobj) { process_payload(tjobj); free_json_obj(tjobj); } else { debug ("%s", "payload not available"); } return (SUCCESS); }
/** * Function called by the transport for each received message. * This function should also be called with "NULL" for the * message to signal that the other peer disconnected. * * @param cls closure, const char* with the name of the plugin we received the message from * @param peer (claimed) identity of the other peer * @param message the message, NULL if we only care about * learning about the delay until we should receive again -- FIXME! * @param ats performance information * @param ats_count number of records in ats * @param session identifier used for this session (NULL for plugins * that do not offer bi-directional communication to the sender * using the same "connection") * @param sender_address binary address of the sender (if we established the * connection or are otherwise sure of it; should be NULL * for inbound TCP/UDP connections since it it not clear * that we could establish ourselves a connection to that * IP address and get the same system) * @param sender_address_len number of bytes in sender_address * @return how long the plugin should wait until receiving more data * (plugins that do not support this, can ignore the return value) */ static struct GNUNET_TIME_Relative plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, struct Session *session, const char *sender_address, uint16_t sender_address_len) { const char *plugin_name = cls; struct GNUNET_TIME_Relative ret; struct GNUNET_HELLO_Address address; uint16_t type; address.peer = *peer; address.address = sender_address; address.address_length = sender_address_len; address.transport_name = plugin_name; ret = GNUNET_TIME_UNIT_ZERO; if (NULL == message) goto end; type = ntohs (message->type); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Message with type %u from peer `%s'\n", type, GNUNET_i2s (peer)); GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes total received"), ntohs (message->size), GNUNET_NO); switch (type) { case GNUNET_MESSAGE_TYPE_HELLO: GST_validation_handle_hello (message); return ret; case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Processing `%s' from `%s'\n", "PING", (sender_address != NULL) ? GST_plugins_a2s (&address) : "<inbound>"); GST_validation_handle_ping (peer, message, &address, session); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Processing `%s' from `%s'\n", "PONG", (sender_address != NULL) ? GST_plugins_a2s (&address) : "<inbound>"); GST_validation_handle_pong (peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT: GST_neighbours_handle_connect (message, peer, &address, session, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK: GST_neighbours_handle_connect_ack (message, peer, &address, session, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: GST_neighbours_handle_session_ack (message, peer, &address, session, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: GST_neighbours_handle_disconnect_message (peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: GST_neighbours_keepalive (peer); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE: GST_neighbours_keepalive_response (peer, ats, ats_count); break; default: /* should be payload */ GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes payload received"), ntohs (message->size), GNUNET_NO); ret = process_payload (peer, &address, session, message, ats, ats_count); break; } end: #if 1 /* FIXME: this should not be needed, and not sure it's good to have it, but without * this connections seem to go extra-slow */ GNUNET_ATS_address_update (GST_ats, &address, session, ats, ats_count); #endif GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Allowing receive from peer %s to continue in %llu ms\n", GNUNET_i2s (peer), (unsigned long long) ret.rel_value); return ret; }
/*! * @brief Authenticate and decrypt a (CCM) stream. * * @param user_ctx The user's context * @param auth_ctx Info on this Auth operation * @param cipher_key_info Key to encrypt payload * @param auth_key_info (unused - same key in CCM) * @param auth_data_length Length in bytes of @a auth_data * @param auth_data Any auth-only data * @param payload_length Length in bytes of @a payload * @param ct The encrypted data * @param auth_value The authentication code to validate * @param[out] payload The location to store decrypted data * * @return A return code of type #fsl_shw_return_t. */ fsl_shw_return_t fsl_shw_auth_decrypt(fsl_shw_uco_t * user_ctx, fsl_shw_acco_t * auth_ctx, fsl_shw_sko_t * cipher_key_info, fsl_shw_sko_t * auth_key_info, uint32_t auth_data_length, const uint8_t * auth_data, uint32_t payload_length, const uint8_t * ct, const uint8_t * auth_value, uint8_t * payload) { SAH_SF_DCLS; uint8_t *calced_auth = NULL; unsigned blocking = user_ctx->flags & FSL_UCO_BLOCKING_MODE; SAH_SF_USER_CHECK(); /* Only support INIT and FINALIZE flags right now. */ if (auth_ctx->mode != FSL_ACC_MODE_CCM) { ret = FSL_RETURN_BAD_MODE_S; goto out; } if ((auth_ctx->flags & (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_LOAD | FSL_ACCO_CTX_SAVE | FSL_ACCO_CTX_FINALIZE)) != (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_FINALIZE)) { ret = FSL_RETURN_BAD_FLAG_S; goto out; } ret = load_ctr_key(&desc_chain, user_ctx, auth_ctx, cipher_key_info); if (ret != FSL_RETURN_OK_S) { goto out; } /* Decrypt the MAC which the user passed in */ header = SAH_HDR_SKHA_ENC_DEC; DESC_IN_OUT(header, auth_ctx->mac_length, auth_value, auth_ctx->mac_length, auth_ctx->unencrypted_mac); #ifndef NO_ZERO_IV_LOAD ret = load_dummy_iv(&desc_chain, user_ctx, 1, auth_ctx->auth_info.CCM_ctx_info.block_size_bytes); #endif if (auth_data_length > 0) { ret = add_assoc_preamble(&desc_chain, user_ctx, auth_ctx, auth_data, auth_data_length); if (ret != FSL_RETURN_OK_S) { goto out; } } /* if auth_data_length > 0 */ ret = process_payload(&desc_chain, user_ctx, 0, payload_length, ct, payload); if (ret != FSL_RETURN_OK_S) { goto out; } /* Now pull CBC context (unencrypted MAC) out for comparison. */ /* Need to allocate a place for it, to handle non-blocking mode * when this stack frame will disappear! */ calced_auth = DESC_TEMP_ALLOC(auth_ctx->mac_length); ret = extract_mac(&desc_chain, user_ctx, auth_ctx->mac_length, calced_auth); if (ret != FSL_RETURN_OK_S) { goto out; } if (!blocking) { /* get_results will need this for comparison */ desc_chain->out1_ptr = calced_auth; desc_chain->out2_ptr = auth_ctx->unencrypted_mac; desc_chain->out_len = auth_ctx->mac_length; } SAH_SF_EXECUTE(); if (blocking && (ret == FSL_RETURN_OK_S)) { unsigned i; /* Validate the auth code */ for (i = 0; i < auth_ctx->mac_length; i++) { if (calced_auth[i] != auth_ctx->unencrypted_mac[i]) { ret = FSL_RETURN_AUTH_FAILED_S; break; } } } out: SAH_SF_DESC_CLEAN(); DESC_TEMP_FREE(calced_auth); (void)auth_key_info; return ret; } /* fsl_shw_gen_decrypt() */
/*! * @brief Generate a (CCM) auth code and encrypt the payload. * * This is a very complicated function. Seven (or eight) descriptors are * required to perform a CCM calculation. * * First: Load CTR0 and key. * * Second: Run an octet of data through to bump to CTR1. (This could be * done in software, but software will have to bump and later decrement - * or copy and bump. * * Third: (in Virtio) Load a descriptor with data of zeros for CBC IV. * * Fourth: Run any (optional) "additional data" through the CBC-mode * portion of the algorithm. * * Fifth: Run the payload through in CCM mode. * * Sixth: Extract the unencrypted MAC. * * Seventh: Load CTR0. * * Eighth: Encrypt the MAC. * * @param user_ctx The user's context * @param auth_ctx Info on this Auth operation * @param cipher_key_info Key to encrypt payload * @param auth_key_info (unused - same key in CCM) * @param auth_data_length Length in bytes of @a auth_data * @param auth_data Any auth-only data * @param payload_length Length in bytes of @a payload * @param payload The data to encrypt * @param[out] ct The location to store encrypted data * @param[out] auth_value The location to store authentication code * * @return A return code of type #fsl_shw_return_t. */ fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx, fsl_shw_acco_t * auth_ctx, fsl_shw_sko_t * cipher_key_info, fsl_shw_sko_t * auth_key_info, uint32_t auth_data_length, const uint8_t * auth_data, uint32_t payload_length, const uint8_t * payload, uint8_t * ct, uint8_t * auth_value) { SAH_SF_DCLS; SAH_SF_USER_CHECK(); if (auth_ctx->mode != FSL_ACC_MODE_CCM) { ret = FSL_RETURN_BAD_MODE_S; goto out; } /* Only support INIT and FINALIZE flags right now. */ if ((auth_ctx->flags & (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_LOAD | FSL_ACCO_CTX_SAVE | FSL_ACCO_CTX_FINALIZE)) != (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_FINALIZE)) { ret = FSL_RETURN_BAD_FLAG_S; goto out; } ret = load_ctr_key(&desc_chain, user_ctx, auth_ctx, cipher_key_info); if (ret != FSL_RETURN_OK_S) { goto out; } header = SAH_HDR_SKHA_ENC_DEC; DESC_IN_OUT(header, auth_ctx->cipher_ctx_info.block_size_bytes, garbage_output, auth_ctx->cipher_ctx_info.block_size_bytes, garbage_output); #ifndef NO_ZERO_IV_LOAD ret = load_dummy_iv(&desc_chain, user_ctx, 1, auth_ctx->auth_info.CCM_ctx_info.block_size_bytes); if (ret != FSL_RETURN_OK_S) { goto out; } #endif if (auth_data_length > 0) { ret = add_assoc_preamble(&desc_chain, user_ctx, auth_ctx, auth_data, auth_data_length); if (ret != FSL_RETURN_OK_S) { goto out; } } /* if auth_data_length > 0 */ ret = process_payload(&desc_chain, user_ctx, 1, payload_length, payload, ct); if (ret != FSL_RETURN_OK_S) { goto out; } /* Pull out the CBC-MAC value. */ ret = extract_mac(&desc_chain, user_ctx, auth_ctx->mac_length, auth_ctx->unencrypted_mac); if (ret != FSL_RETURN_OK_S) { goto out; } /* Now load CTR0 in, and encrypt the MAC */ ret = encrypt_mac(&desc_chain, user_ctx, auth_ctx, auth_ctx->unencrypted_mac, auth_value); if (ret != FSL_RETURN_OK_S) { goto out; } SAH_SF_EXECUTE(); out: SAH_SF_DESC_CLEAN(); (void)auth_key_info; return ret; } /* fsl_shw_gen_encrypt() */
/** * Function called by the transport for each received message. * * @param cls closure, const char* with the name of the plugin we received the message from * @param address address and (claimed) identity of the other peer * @param message the message, NULL if we only care about * learning about the delay until we should receive again * @param session identifier used for this session (NULL for plugins * that do not offer bi-directional communication to the sender * using the same "connection") * @return how long the plugin should wait until receiving more data * (plugins that do not support this, can ignore the return value) */ struct GNUNET_TIME_Relative GST_receive_callback (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, const struct GNUNET_MessageHeader *message) { const char *plugin_name = cls; struct GNUNET_TIME_Relative ret; uint16_t type; ret = GNUNET_TIME_UNIT_ZERO; if (NULL == message) goto end; type = ntohs (message->type); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message with type %u from peer `%s'\n", type, GNUNET_i2s (&address->peer)); GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes total received"), ntohs (message->size), GNUNET_NO); GST_neighbours_notify_data_recv (address, message); switch (type) { case GNUNET_MESSAGE_TYPE_HELLO_LEGACY: /* Legacy HELLO message, discard */ return ret; case GNUNET_MESSAGE_TYPE_HELLO: if (GNUNET_OK != GST_validation_handle_hello (message)) { GNUNET_break_op (0); GST_blacklist_abort_matching (address, session); } return ret; case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing PING from `%s'\n", GST_plugins_a2s (address)); if (GNUNET_OK != GST_validation_handle_ping (&address->peer, message, address, session)) { GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Processing PONG from `%s'\n", GST_plugins_a2s (address)); if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message)) { GNUNET_break_op (0); GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN: /* Do blacklist check if communication with this peer is allowed */ (void) GST_blacklist_test_allowed (&address->peer, NULL, &connect_bl_check_cont, GNUNET_copy_message (message), address, session); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK: if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message, address, session)) { GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: if (GNUNET_OK != GST_neighbours_handle_session_ack (message, address, session)) { GNUNET_break_op(0); GST_blacklist_abort_matching (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: GST_neighbours_handle_disconnect_message (&address->peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA: GST_neighbours_handle_quota_message (&address->peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: GST_neighbours_keepalive (&address->peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE: GST_neighbours_keepalive_response (&address->peer, message); break; default: /* should be payload */ GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes payload received"), ntohs (message->size), GNUNET_NO); ret = process_payload (address, session, message); break; } end: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Allowing receive from peer %s to continue in %s\n", GNUNET_i2s (&address->peer), GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES)); return ret; }
int handle_startup(int which, void * obj) { struct nebstruct_process_struct *ps = (struct nebstruct_process_struct *)obj; time_t now = ps->timestamp.tv_sec; switch(ps->type) { case NEBTYPE_PROCESS_START: if(daemon_mode && !sigrestart) return 0; case NEBTYPE_PROCESS_DAEMONIZE: { json_t * pubdef = NULL, *pulldef = NULL, *reqdef = NULL; int numthreads = 1; if(get_values(config, "iothreads", JSON_INTEGER, 0, &numthreads, "publish", JSON_OBJECT, 0, &pubdef, "pull", JSON_OBJECT, 0, &pulldef, "reply", JSON_OBJECT, 0, &reqdef, NULL) != 0) { syslog(LOG_ERR, "Parameter error while starting NagMQ"); return -1; } if(!pubdef && !pulldef && !reqdef) return 0; zmq_ctx = zmq_init(numthreads); if(zmq_ctx == NULL) { syslog(LOG_ERR, "Error initialzing ZMQ: %s", zmq_strerror(errno)); return -1; } if(pubdef && handle_pubstartup(pubdef) < 0) return -1; if(pulldef) { unsigned long interval = 2; get_values(pulldef, "interval", JSON_INTEGER, 0, &interval, NULL); if((pullsock = getsock("pull", ZMQ_PULL, pulldef)) == NULL) return -1; schedule_new_event(EVENT_USER_FUNCTION, 1, now, 1, interval, NULL, 1, input_reaper, pullsock, 0); } if(reqdef) { unsigned long interval = 2; get_values(reqdef, "interval", JSON_INTEGER, 0, &interval, NULL); if((reqsock = getsock("reply", ZMQ_REP, reqdef)) == NULL) return -1; schedule_new_event(EVENT_USER_FUNCTION, 1, now, 1, interval, NULL, 1, input_reaper, reqsock, 0); } if(pulldef || reqdef) neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, handle, 0, handle_timedevent); break; } case NEBTYPE_PROCESS_SHUTDOWN: case NEBTYPE_PROCESS_RESTART: if(pullsock) zmq_close(pullsock); if(reqsock) zmq_close(reqsock); if(pubext) zmq_close(pubext); zmq_term(zmq_ctx); break; case NEBTYPE_PROCESS_EVENTLOOPSTART: case NEBTYPE_PROCESS_EVENTLOOPEND: if(pubext) { struct payload * payload; payload = payload_new(); switch(ps->type) { case NEBTYPE_PROCESS_EVENTLOOPSTART: payload_new_string(payload, "type", "eventloopstart"); break; case NEBTYPE_PROCESS_EVENTLOOPEND: payload_new_string(payload, "type", "eventloopend"); break; } payload_new_timestamp(payload, "timestamp", &ps->timestamp); payload_finalize(payload); process_payload(payload); } break; } return 0; }
void process_serial(void) { if (zcl_ati()) { // ATI command response for (uint8_t i = 0; i < sizeof(ati_resp)-1; i++) { char c = pgm_get(ati_resp[i],byte); serial_send(c); } // MAC address, big endian, colon separated serial_send_hex(mac >> 56); serial_send(':'); serial_send_hex(mac >> 48); serial_send(':'); serial_send_hex(mac >> 40); serial_send(':'); serial_send_hex(mac >> 32); serial_send(':'); serial_send_hex(mac >> 24); serial_send(':'); serial_send_hex(mac >> 16); serial_send(':'); serial_send_hex(mac >> 8); serial_send(':'); serial_send_hex(mac >> 0); serial_send('\n'); // May continue to packet processing } if (zcl_own_fault()) { /* If buffer overflow or other internal error * happened, there is not much to do. TODO Maybe there * should be some internal flag? Or proper ZigBee * error? */ serial_send(ACK); zcl_receiver_reset(); return; } if (!zcl_packet_available()) return; // We have a packet. Checking CRC. uint16_t *msg_crc = (uint16_t *)(zcl.raw + zcl.packet.length + 2); uint16_t crc = 0xffff; for (uint16_t i = 0; i < zcl.packet.length; i++) { crc = _crc_xmodem_update(crc, zcl.raw[i+2]); } /* Answering ACK and processing the answer if it was * correct. Otherwise just send NAK and let the sender to * resend it later */ if (*msg_crc == crc) { serial_send(ACK); process_payload(); } else { serial_send(NAK); } // Re-enable the receiver zcl_receiver_reset(); }