int main(int argc, const char *argv[]) { packet_t *packet; uint8_t *bytes; size_t length; /* Create a SYN */ packet = packet_create_syn(0x1234, 0x0000, 0x0000); packet_print(packet); /* Convert it to bytes and free the original */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); safe_free(bytes); /* Create a MSG */ packet = packet_create_msg(0x1234, 0x0000, 0x0001, (uint8_t*)"AAAAA", 5); packet_print(packet); /* Convert it to bytes and free the orignal */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); safe_free(bytes); /* Create a FIN */ packet = packet_create_fin(0x1234); packet_print(packet); /* Convert it to bytes and free the orignal */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); safe_free(bytes); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); print_memory(); return 0; }
size_t packet_get_fin_size(options_t options) { static size_t size = 0; /* If the size isn't known yet, calculate it. */ if(size == 0) { packet_t *p = packet_create_fin(0, ""); uint8_t *data = packet_to_bytes(p, &size, options); safe_free(data); packet_destroy(p); } return size; }
uint8_t *session_get_outgoing(session_t *session, size_t *length, size_t max_length) { packet_t *packet = NULL; uint8_t *result = NULL; uint8_t *data = NULL; size_t data_length = -1; /* Suck in any data we can from the driver. */ poll_for_data(session); /* Don't transmit too quickly without receiving anything. */ if(!can_i_transmit_yet(session)) return NULL; /* It's pretty ugly, but I don't see any other way, since ping requires * special packets we have to handle it separately. */ if(session->is_ping) { /* Read data without consuming it (ie, leave it in the buffer till it's ACKed) */ data = buffer_read_remaining_bytes(session->outgoing_buffer, &data_length, max_length - packet_get_ping_size(), FALSE); packet = packet_create_ping(session->id, (char*)data); safe_free(data); LOG_INFO("In PING, sending a PING packet (%zd bytes of data...)", data_length); } else { switch(session->state) { case SESSION_STATE_NEW: LOG_INFO("In SESSION_STATE_NEW, sending a SYN packet (SEQ = 0x%04x)...", session->my_seq); packet = packet_create_syn(session->id, session->my_seq, (options_t)0); if(session->is_command) packet_syn_set_is_command(packet); if(session->name) packet_syn_set_name(packet, session->name); break; case SESSION_STATE_ESTABLISHED: /* Read data without consuming it (ie, leave it in the buffer till it's ACKed) */ data = buffer_read_remaining_bytes(session->outgoing_buffer, &data_length, max_length - packet_get_msg_size(session->options), FALSE); LOG_INFO("In SESSION_STATE_ESTABLISHED, sending a MSG packet (SEQ = 0x%04x, ACK = 0x%04x, %zd bytes of data...)", session->my_seq, session->their_seq, data_length); if(data_length == 0 && session->is_shutdown) packet = packet_create_fin(session->id, "Stream closed"); else packet = packet_create_msg_normal(session->id, session->my_seq, session->their_seq, data, data_length); safe_free(data); break; default: LOG_FATAL("Wound up in an unknown state: 0x%x", session->state); exit(1); } } if(packet) { /* Print packet data if we're supposed to. */ if(packet_trace) { printf("OUTGOING: "); packet_print(packet, session->options); } update_counter(session); result = packet_to_bytes(packet, length, session->options); packet_destroy(packet); } return result; }