int send_data (connection_data *connection, char *data) { data_packet d_packet; char *ptr = NULL; static uint32_t sequence_nr; d_packet.proto_id = "herp"; d_packet.packet_type = DATA; d_packet.seq_nr = sequence_nr; #ifdef _DEBUG_ printf("Client_id: %d, %d last_seen_pkt[%d] = %d\n", connection->client_id, connection->client_id-1, connection->client_id-1, connection->last_seen_pkt[connection->client_id-1]); #endif d_packet.client_id = connection->client_id; d_packet.data = (void *)data; d_packet.trailer = "derp"; ptr = packet_to_string(&d_packet, DATA); if (sendto(connection->sock_fd, ptr, strlen(ptr)+1, 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) <0) { perror ("sendto (func send_data) failed!"); return -1; } free(ptr); sequence_nr++; return 0; }
/** @copydoc socket_command_struct::handle_func */ void socket_command_file_update(uint8_t *data, size_t len, size_t pos) { char filename[MAX_BUF]; unsigned long ucomp_len; unsigned char *dest; FILE *fp; if (file_updates_requested != 0) { file_updates_requested--; } packet_to_string(data, len, &pos, filename, sizeof(filename)); ucomp_len = packet_to_uint32(data, len, &pos); len -= pos; /* Uncompress it. */ dest = emalloc(ucomp_len); uncompress((Bytef *) dest, (uLongf *) & ucomp_len, (const Bytef *) data + pos, (uLong) len); data = dest; len = ucomp_len; fp = path_fopen(filename, "wb"); if (!fp) { LOG(BUG, "Could not open file '%s' for writing.", filename); efree(dest); return; } /* Update the file. */ fwrite(data, 1, len, fp); fclose(fp); efree(dest); }
int connection_termination(connection_data *connection, uint8_t side) { handshake_packet *rst_ack_packet = NULL; char *ptr = NULL; int i; #ifdef _DEBUG_ printf("Terminating connection.\n"); #endif switch(side) { case SERVER: #ifdef _DEBUG_ printf("Preparing ACK packet for termination.\n"); #endif rst_ack_packet = malloc(sizeof(handshake_packet)); rst_ack_packet->proto_id = "herp"; rst_ack_packet->packet_type = HANDSHAKE; rst_ack_packet->client_ip = connection->client_ip; rst_ack_packet->client_port = connection->client_port; rst_ack_packet->client_id = connection->client_id; rst_ack_packet->flags = ACK; rst_ack_packet->trailer = "derp"; #ifdef _DEBUG_ printf("Converting to string.\n"); #endif ptr = packet_to_string(rst_ack_packet, HANDSHAKE); #ifdef _DEBUG_ printf("Sending ACK for termination.\n"); #endif for(i = 0; i < 2; i++) { if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) { perror("sendto() failed in ACK for termination"); CLOSE(connection->sock_fd); return -1; } } free(ptr); free(rst_ack_packet); break; case CLIENT: #ifdef _DEBUG_ printf("Closing socket.\n"); #endif CLOSE(connection->sock_fd); #ifdef _DEBUG_ printf("Freeing connection_data.\n"); #endif free(connection->destination); free(connection); break; } net_cleanup(); return 0; }
/* For verbose runs, print a short packet dump of all live packets. */ static void verbose_packet_dump(struct state *state, const char *type, struct packet *live_packet, s64 time_usecs) { if (state->config->verbose) { char *dump = NULL, *dump_error = NULL; packet_to_string(live_packet, DUMP_SHORT, &dump, &dump_error); printf("%s packet: %9.6f %s%s%s\n", type, usecs_to_secs(time_usecs), dump, dump_error ? "\n" : "", dump_error ? dump_error : ""); free(dump); free(dump_error); } }
/* Add a dump of the given packet to the given error message. * Frees *error and replaces it with a version that has the original * *error followed by the given type and a hex dump of the given * packet. */ static void add_packet_dump(char **error, const char *type, struct packet *packet, s64 time_usecs, enum dump_format_t format) { if (packet->ip_bytes != 0) { char *old_error = *error; char *dump = NULL, *dump_error = NULL; packet_to_string(packet, format, &dump, &dump_error); asprintf(error, "%s\n%s packet: %9.6f %s%s%s", old_error, type, usecs_to_secs(time_usecs), dump, dump_error ? "\n" : "", dump_error ? dump_error : ""); free(dump); free(dump_error); free(old_error); } }
void pipeline_process_packet(struct pipeline *pl, struct packet *pkt) { struct flow_table *table, *next_table; if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *pkt_str = packet_to_string(pkt); VLOG_DBG_RL(LOG_MODULE, &rl, "processing packet: %s", pkt_str); free(pkt_str); } if (!packet_handle_std_is_ttl_valid(pkt->handle_std)) { if ((pl->dp->config.flags & OFPC_INVALID_TTL_TO_CONTROLLER) != 0) { VLOG_DBG_RL(LOG_MODULE, &rl, "Packet has invalid TTL, sending to controller."); send_packet_to_controller(pl, pkt, 0/*table_id*/, OFPR_INVALID_TTL); } else { VLOG_DBG_RL(LOG_MODULE, &rl, "Packet has invalid TTL, dropping."); } packet_destroy(pkt); return; } next_table = pl->tables[0]; while (next_table != NULL) { struct flow_entry *entry; VLOG_DBG_RL(LOG_MODULE, &rl, "trying table %u.", next_table->stats->table_id); pkt->table_id = next_table->stats->table_id; table = next_table; next_table = NULL; entry = flow_table_lookup(table, pkt); if (entry != NULL) { if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *m = ofl_structs_flow_stats_to_string(entry->stats, pkt->dp->exp); VLOG_DBG_RL(LOG_MODULE, &rl, "found matching entry: %s.", m); free(m); } execute_entry(pl, entry, &next_table, &pkt); /* Packet could be destroyed by a meter instruction */ if (!pkt) return; if (next_table == NULL) { /* Cookie field is set 0xffffffffffffffff because we cannot associate it to any particular flow */ action_set_execute(pkt->action_set, pkt, 0xffffffffffffffff); packet_destroy(pkt); return; } } else { /* OpenFlow 1.3 default behavior on a table miss */ VLOG_DBG_RL(LOG_MODULE, &rl, "No matching entry found. Dropping packet."); packet_destroy(pkt); return; } } VLOG_WARN_RL(LOG_MODULE, &rl, "Reached outside of pipeline processing cycle."); }
/** @copydoc socket_command_struct::handle_func */ void socket_command_party(uint8_t *data, size_t len, size_t pos) { uint8_t type; type = packet_to_uint8(data, len, &pos); /* List of parties, or list of party members. */ if (type == CMD_PARTY_LIST || type == CMD_PARTY_WHO) { list_clear(list_party); while (pos < len) { if (type == CMD_PARTY_LIST) { char party_name[MAX_BUF], party_leader[MAX_BUF]; packet_to_string(data, len, &pos, party_name, sizeof(party_name)); packet_to_string(data, len, &pos, party_leader, sizeof(party_leader)); list_add(list_party, list_party->rows, 0, party_name); list_add(list_party, list_party->rows - 1, 1, party_leader); } else if (type == CMD_PARTY_WHO) { char name[MAX_BUF], bars[MAX_BUF]; uint8_t hp, sp; packet_to_string(data, len, &pos, name, sizeof(name)); hp = packet_to_uint8(data, len, &pos); sp = packet_to_uint8(data, len, &pos); list_add(list_party, list_party->rows, 0, name); PARTY_STAT_BAR(); list_add(list_party, list_party->rows - 1, 1, bars); } } /* Sort the list of party members alphabetically. */ if (type == CMD_PARTY_WHO) { list_sort(list_party, LIST_SORT_ALPHA); } /* Update column names, depending on the list contents. */ list_set_column(list_party, 0, -1, -1, type == CMD_PARTY_LIST ? "Party name" : "Player", -1); list_set_column(list_party, 1, -1, -1, type == CMD_PARTY_LIST ? "Leader" : "Stats", -1); list_contents = type; cur_widget[PARTY_ID]->redraw = 1; cur_widget[PARTY_ID]->show = 1; SetPriorityWidget(cur_widget[PARTY_ID]); } else if (type == CMD_PARTY_JOIN) { /* Join command; store the party name we're member of, and show the * list of party members, if the party widget is not hidden. */ packet_to_string(data, len, &pos, cpl.partyname, sizeof(cpl.partyname)); if (cur_widget[PARTY_ID]->show) { send_command("/party who"); } } else if (type == CMD_PARTY_LEAVE) { /* Leave; clear the party name and switch to list of parties (unless * the party widget is hidden). */ cpl.partyname[0] = '\0'; if (cur_widget[PARTY_ID]->show) { send_command("/party list"); } } else if (type == CMD_PARTY_PASSWORD) { char buf[MAX_BUF]; /* Party requires password, bring up the console for the player to * enter the password. */ packet_to_string(data, len, &pos, cpl.partyjoin, sizeof(cpl.partyjoin)); snprintf(buf, sizeof(buf), "?MCON /joinpassword "); keybind_process_command(buf); } else if (type == CMD_PARTY_UPDATE) { char name[MAX_BUF], bars[MAX_BUF]; uint8_t hp, sp; uint32_t row; /* Update list of party members. */ if (list_contents != CMD_PARTY_WHO) { return; } packet_to_string(data, len, &pos, name, sizeof(name)); hp = packet_to_uint8(data, len, &pos); sp = packet_to_uint8(data, len, &pos); PARTY_STAT_BAR(); cur_widget[PARTY_ID]->redraw = 1; for (row = 0; row < list_party->rows; row++) { if (!strcmp(list_party->text[row][0], name)) { efree(list_party->text[row][1]); list_party->text[row][1] = estrdup(bars); return; } } list_add(list_party, list_party->rows, 0, name); list_add(list_party, list_party->rows - 1, 1, bars); list_sort(list_party, LIST_SORT_ALPHA); } else if (type == CMD_PARTY_REMOVE_MEMBER) { char name[MAX_BUF]; uint32_t row; /* Remove member from the list of party members. */ if (list_contents != CMD_PARTY_WHO) { return; } packet_to_string(data, len, &pos, name, sizeof(name)); cur_widget[PARTY_ID]->redraw = 1; for (row = 0; row < list_party->rows; row++) { if (!strcmp(list_party->text[row][0], name)) { list_remove_row(list_party, row); return; } } } }
int connect_session(connection_data *connection, char *server_ip, uint16_t server_port, uint16_t client_port) { handshake_packet syn_packet, *received_packet = NULL; struct sockaddr_in server, client; socklen_t client_len; int i = 0, return_value = 0; char *ptr = NULL; char *client_ip = malloc(sizeof(char) * 16); uint32_t sock_fd = 0; srand(time(NULL)); net_init(); #ifdef _DEBUG_ printf("Before creating socket.\n"); #endif if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("socket() failed"); return -1; } #ifdef _DEBUG_ printf("After creating socket.\n"); printf("Creating sockaddr_in to find out client ip\n"); #endif memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr(server_ip); server.sin_port = htons(server_port); #ifdef _DEBUG_ printf("Using a connected UDP socket to find out client ip\n"); #endif if (connect(sock_fd, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("connect() failed (in trying to find out client ip)"); return -1; } client_len = sizeof(client); #ifdef _DEBUG_ printf("Using getsockname() to get local IP the socket bound to\n"); #endif if (getsockname(sock_fd, (struct sockaddr *)&client, &client_len) < 0) { perror("getsockname() failed when trying to find out client ip"); return -1; } #ifdef _DEBUG_ printf("Fetching the IP address from client sockaddr struct\n"); #endif if (inet_ntop(AF_INET, &client.sin_addr, client_ip, 16) < 0) { perror("inet_ntop() failed to get client ip"); return -1; } CLOSE(sock_fd); #ifdef _DEBUG_ printf("Client ip in buffer: %s\n", client_ip); printf("Before creating socket.\n"); #endif if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("socket() failed"); return -1; } #ifdef _DEBUG_ printf("After creating socket.\n"); printf("Preparing SYN packet.\n"); #endif syn_packet.proto_id = "herp"; syn_packet.packet_type = HANDSHAKE; syn_packet.client_ip = client_ip; syn_packet.client_port = client_port; syn_packet.client_id = rand(); syn_packet.flags = SYN; syn_packet.trailer = "derp"; #ifdef _DEBUG_ printf("Converting to string.\n"); #endif ptr = packet_to_string(&syn_packet, HANDSHAKE); #ifdef _DEBUG_ printf("Setting up listening socket.\n"); #endif connection = create_connection_data(client_ip, client_port, syn_packet.client_id, sock_fd, connection); #ifdef _DEBUG_ printf("Binding socket.\n"); #endif if (bind(connection->sock_fd, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) { perror("Bind() failed"); CLOSE(connection->sock_fd); return -1; } #ifdef _DEBUG_ printf("Creating connection_data.\n"); #endif connection = create_connection_data(server_ip, server_port, syn_packet.client_id, connection->sock_fd, connection); connection->client_ip = client_ip; connection->client_port = client_port; for(i = 0; i < 3; i++) { #ifdef _DEBUG_ printf("Try %d\n", i+1); printf("Struct data: %d %d %d socket: %d client_id: %d\n", connection->destination->sin_family, connection->destination->sin_port, connection->destination->sin_addr.s_addr, connection->sock_fd, connection->client_id); #endif if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) { perror("sendto() failed"); CLOSE(connection->sock_fd); return -1; } #ifdef _DEBUG_ printf("Entering listening mode.\n"); #endif ptr = listen_socket(connection, 5, 0); #ifdef _DEBUG_ if (ptr != NULL) printf("Received string: %s\n", ptr); #endif if (ptr != NULL) { if (atoi(&ptr[5]) == HANDSHAKE) { #ifdef _DEBUG_ printf("It is a handshake packet outside recv_data!\n"); #endif received_packet = (handshake_packet *)string_to_packet(ptr, HANDSHAKE); #ifdef _DEBUG_ printf("ptr size %d\n", strlen(ptr)); #endif if (!is_packet(received_packet, HANDSHAKE) && !strncmp(connection->client_ip, received_packet->client_ip, strlen(connection->client_ip)) && (received_packet->flags == ACK)) { #ifdef _DEBUG_ printf("ACK packet received: %p.\n", connection); #endif connection->client_id = received_packet->client_id; free(client_ip); return 0; } } else { #ifdef _DEBUG_ printf("Is not a packet :(\n"); #endif break; } } } fprintf(stderr, "No server responded with a ACK, stopping connection attempts...\n"); free(client_ip); return 1; }
int end_session(connection_data *connection) { handshake_packet rst_packet, *received_packet = NULL; char *ptr = NULL; int i; rst_packet.proto_id = "herp"; rst_packet.packet_type = HANDSHAKE; rst_packet.client_ip = connection->client_ip; rst_packet.client_port = connection->client_port; rst_packet.client_id = connection->client_id; rst_packet.flags = RST; rst_packet.trailer = "derp"; ptr = packet_to_string(&rst_packet, HANDSHAKE); if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) { perror("sendto() failed"); CLOSE(connection->sock_fd); return -1; } for (i = 0; i < 2; i++) { #ifdef _DEBUG_ printf("Listening for ACK packet from termination.\n"); #endif ptr = listen_socket(connection, 3, 0); #ifdef _DEBUG_ if (ptr != NULL) { printf("ptr size %d\n", strlen(ptr)); printf("packet type: %d ptr: %s\n", atoi(&ptr[5]), ptr); } #endif if (ptr != NULL) { if (atoi(&ptr[5]) == HANDSHAKE) { #ifdef _DEBUG_ printf("Converting from string to packet.\n"); #endif received_packet = (handshake_packet *)string_to_packet (ptr, HANDSHAKE); #ifdef _DEBUG_ printf("It is a handshake packet outside recv_data()!\n"); #endif if (!is_packet(received_packet, HANDSHAKE) && (received_packet->flags == ACK)) { #ifdef _DEBUG_ printf("ACK Packet received.\n"); #endif connection_termination(connection, CLIENT); break; } } } } free(received_packet); return 0; }
int accept_session (connection_data *connection, uint16_t port, int client_id) { handshake_packet ack_packet, *received_packet = NULL; static int first_time = 1; static uint16_t sock_fd; char *ptr = NULL; if (first_time) { #ifdef _DEBUG_ printf("Inside a first_time only\n"); #endif net_init(); #ifdef _DEBUG_ printf("Before creating socket.\n"); #endif if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("socket() failed"); return -1; } #ifdef _DEBUG_ printf("After creating socket.\n"); #endif } connection = create_connection_data("0.0.0.0", port, 0, sock_fd, connection); if (first_time) { #ifdef _DEBUG_ printf("Setting up listening socket.\n"); printf("Binding socket.\n"); #endif if (bind(sock_fd, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) { perror("Bind() failed"); CLOSE(sock_fd); return -1; } first_time = 0; } while(1) { #ifdef _DEBUG_ printf("Listening for SYN packet.\n"); printf("connection->sock_fd: %d\n", connection->sock_fd); #endif ptr = listen_socket(connection, 60, 0); #ifdef _DEBUG_ printf("Received string: %s\n", ptr); #endif if (ptr != NULL) { if (atoi(&ptr[5]) == HANDSHAKE) { #ifdef _DEBUG_ printf("Converting from string to packet.\n"); #endif received_packet = (handshake_packet *)string_to_packet(ptr, HANDSHAKE); #ifdef _DEBUG_ printf("ptr size %d\n", strlen(ptr)); printf("It is a handshake packet outside recv_data!\n"); printf("Content: %s %u %s %u %u %s\n", received_packet->proto_id, received_packet->packet_type, received_packet->client_ip, received_packet->client_port, received_packet->flags, received_packet->trailer); #endif if (!is_packet(received_packet, HANDSHAKE) && received_packet->flags == SYN) { #ifdef _DEBUG_ printf("SYN Packet received.\n"); #endif break; } else if (!is_packet(received_packet, HANDSHAKE) && received_packet->flags == RST) { connection_termination(connection, SERVER); return 1; } } } } #ifdef _DEBUG_ printf("Preparing ACK packet.\n"); #endif ack_packet.proto_id = "herp"; ack_packet.packet_type = HANDSHAKE; ack_packet.client_ip = received_packet->client_ip; ack_packet.client_port = received_packet->client_port; ack_packet.client_id = client_id; ack_packet.flags = ACK; ack_packet.trailer = "derp"; #ifdef _DEBUG_ printf("Creating connection_data struct.\n"); #endif connection = create_connection_data(received_packet->client_ip, received_packet->client_port, client_id, connection->sock_fd, connection); #ifdef _DEBUG_ printf("Converting packet_to_string.\n"); #endif ptr = packet_to_string(&ack_packet, HANDSHAKE); #ifdef _DEBUG_ printf("Sending ACK packet.\n"); #endif if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) { perror("sendto() failed"); CLOSE(connection->sock_fd); return -1; } #ifdef _DEBUG_ printf("pointer address %p\n", connection); #endif free(received_packet); free(ptr); return 0; }