/* * Called from hip_esp_output() */ int endbox_ipv4_packet_check(struct ip *iph, struct sockaddr *lsi, int *packet_count) { __u32 dst; if (!IN_MULTICAST(ntohl(iph->ip_dst.s_addr)) && (((ntohl(iph->ip_dst.s_addr)) & 0x000000FF) != 0x000000FF)) { dst = iph->ip_dst.s_addr; } else { dst = 0; } if (!is_valid_packet(iph->ip_src.s_addr, dst, lsi)) { return(-1); } (*packet_count)++; return(0); }
/* * Called from hip_esp_output() */ int endbox_arp_packet_check(struct arp_hdr *arph, struct sockaddr *lsi, int *packet_count) { struct arp_req_data *arp_req; if ((ntohs(arph->ar_hrd) == 0x01) && /* Ethernet */ (ntohs(arph->ar_pro) == 0x0800) && /* IPv4 */ (arph->ar_hln == 6) && (arph->ar_pln == 4)) { arp_req = (struct arp_req_data*)(arph + 1); if (!is_valid_packet(arp_req->src_ip, arp_req->dst_ip, lsi)) { return(-1); } } else { return(-1); } (*packet_count)++; return(0); }
// New data available event handler void rs485_serial_data_available_handler(void* opaque) { (void)opaque; if(!send_verify_flag) { disable_all_timers(); } int bytes_received = 0; uint32_t uid_from_packet = 0; int add_recipient_opaque; Packet empty_packet; Packet data_packet; uint64_t dummy_read_buffer; // Merge or simply save the received bytes if(partial_receive_flag) { bytes_received = read(_rs485_serial_fd, &receive_buffer[partial_receive_merge_index], (RECEIVE_BUFFER_SIZE - partial_receive_merge_index)); printf("bytes_received %d\n", bytes_received); partial_receive_merge_index = partial_receive_merge_index + bytes_received; } else { partial_receive_merge_index = read(_rs485_serial_fd, receive_buffer, RECEIVE_BUFFER_SIZE); if (partial_receive_merge_index != 13) printf("partial_receive_merge_index %d\n", partial_receive_merge_index); } //log_info("PARTIAL_RECEIVE_MERGE_INDEX = %d", partial_receive_merge_index); // Checks at least 13 bytes is available in the receive buffer if(partial_receive_merge_index >= 13) { int packet_validation_code = is_valid_packet(receive_buffer, partial_receive_merge_index); switch(packet_validation_code) { case PACKET_SEND_VERIFY_OK: // Stop send verify timer if (read(_send_verify_event, &dummy_read_buffer, sizeof(uint64_t))) {} setup_timer(&send_verify_timer, TIME_UNIT_NSEC, 0); timerfd_settime(_send_verify_event, 0, &send_verify_timer, NULL); // Disabling TX gpio_output_clear(_tx_pin); end = microseconds(); // Clearing send verify flag send_verify_flag = 0; // Clearing partial receive flag partial_receive_flag = 0; if(sent_ack_of_data_packet) { sent_ack_of_data_packet = 0; master_current_request_processed = 1; master_poll_slave_timeout_handler(NULL); } log_debug("RS485: Send verified"); return; case PACKET_EMPTY_OK: // Proper empty packet log_debug("RS485: Empty packet received"); if(sent_current_request_from_queue){ queue_pop(&_rs485_extension.packet_to_modbus_queue, NULL); sent_current_request_from_queue = 0; } // Updating recipient in the routing table memcpy(&uid_from_packet, &receive_buffer[3], sizeof(uint32_t)); stack_add_recipient(&_rs485_extension.base, uid_from_packet, receive_buffer[0]); partial_receive_flag = 0; master_current_request_processed = 1; if(sent_ack_of_data_packet) { sent_ack_of_data_packet = 0; } master_poll_slave_timeout_handler(NULL); return; case PACKET_DATA_OK: // Proper data packet log_info("RS485: Data packet received"); // Send message into brickd dispatcher memset(&data_packet, 0, sizeof(Packet)); memcpy(&data_packet, &receive_buffer[3], partial_receive_merge_index - MODBUS_PACKET_OVERHEAD); network_dispatch_response(&data_packet); log_debug("RS485: Dispatched packet to network subsystem"); if(sent_current_request_from_queue){ queue_pop(&_rs485_extension.packet_to_modbus_queue, NULL); sent_current_request_from_queue = 0; } // Updating recipient in the routing table memcpy(&uid_from_packet, &receive_buffer[3], sizeof(uint32_t)); add_recipient_opaque = receive_buffer[0]; stack_add_recipient(&_rs485_extension.base, uid_from_packet, add_recipient_opaque); // Send ACK to the slave memset(&empty_packet, 0, sizeof(PacketHeader)); empty_packet.header.length = 8; send_modbus_packet(_rs485_extension.slaves[master_current_slave_to_process], current_sequence_number, &empty_packet); sent_ack_of_data_packet = 1; return; case PACKET_ERROR_SEND_VERIFY: // Retry the current request log_error("RS485: Send verify failed"); partial_receive_flag = 0; master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; case PACKET_ERROR_ADDRESS: // Retry the current request log_error("RS485: Wrong address in packet"); partial_receive_flag = 0; master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; case PACKET_ERROR_FUNCTION_CODE: log_error("RS485: Wrong function code in packet"); partial_receive_flag = 0; master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; case PACKET_ERROR_SEQUENCE_NUMBER: // Retry the current request log_info("RS485: Wrong sequence number in packet"); partial_receive_flag = 0; master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; case PACKET_ERROR_LENGTH: // Retry the current request log_error("RS485: Wrong length in packet"); partial_receive_flag = 0; master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; case PACKET_ERROR_LENGTH_PARTIAL: log_debug("RS485: Partial data packet recieved"); handle_partial_receive(); return; case PACKET_ERROR_CRC16: // Retry the current request log_error("RS485: Wrong CRC16 in packet"); partial_receive_flag = 0; master_current_retry = MASTER_RETRIES; master_retry_timeout_handler(NULL); return; default: return; } } else { log_debug("RS485: Partial packet recieved"); handle_partial_receive(); return; } if(send_verify_flag) { // Disabling TX gpio_output_clear(_tx_pin); end = microseconds(); // Stop send verify timer if (read(_send_verify_event, &dummy_read_buffer, sizeof(uint64_t))) {} setup_timer(&send_verify_timer, TIME_UNIT_NSEC, 0); timerfd_settime(_send_verify_event, 0, &send_verify_timer, NULL); // Clearing send verify flag send_verify_flag = 0; } abort_current_request(); return; }