void socket_base_print_sockets(void) { int i; printf("\n--- Socket list: ---\n"); for (i = 1; i < MAX_SOCKETS + 1; i++) { if (socket_base_get_socket(i) != NULL) { socket_base_print_internal_socket(socket_base_get_socket(i)); } } }
bool udp_socket_compliancy(int s) { if ((socket_base_exists_socket(s)) && (socket_base_get_socket(s)->socket_values.domain == PF_INET6) && (socket_base_get_socket(s)->socket_values.type == SOCK_DGRAM) && ((socket_base_get_socket(s)->socket_values.protocol == IPPROTO_UDP) || (socket_base_get_socket(s)->socket_values.protocol == 0))) { return true; } else { return false; } }
socket_internal_t *get_udp_socket(udp_hdr_t *udp_header) { uint8_t i = 1; while (i < MAX_SOCKETS + 1) { if (udp_socket_compliancy(i) && (socket_base_get_socket(i)->socket_values.local_address.sin6_port == udp_header->dst_port)) { return socket_base_get_socket(i); } i++; } return NULL; }
int32_t udp_recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen) { (void) flags; msg_t m_recv, m_send; ipv6_hdr_t *ipv6_header; udp_hdr_t *udp_header; uint8_t *payload; socket_base_get_socket(s)->recv_pid = thread_getpid(); msg_receive(&m_recv); ipv6_header = ((ipv6_hdr_t *)m_recv.content.ptr); udp_header = ((udp_hdr_t *)(m_recv.content.ptr + IPV6_HDR_LEN)); payload = (uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN); memset(buf, 0, len); /* cppcheck: the memset sets parts of the buffer to 0 even though it will * be overwritten by the next memcpy. However without the memset the buffer * could contain stale data (if the copied data is less then the buffer * length) and setting just the left over part of the buffer to 0 would * introduce overhead (calculation how much needs to be zeroed). */ /* cppcheck-suppress redundantCopy */ memcpy(buf, payload, NTOHS(udp_header->length) - UDP_HDR_LEN); memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16); from->sin6_family = AF_INET6; from->sin6_flowinfo = 0; from->sin6_port = udp_header->src_port; *fromlen = sizeof(sockaddr6_t); msg_reply(&m_recv, &m_send); return NTOHS(udp_header->length) - UDP_HDR_LEN; }
int udp_bind_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid) { int i; if (!socket_base_exists_socket(s)) { return -1; } for (i = 1; i < MAX_SOCKETS + 1; i++) { if (udp_socket_compliancy(i) && (socket_base_get_socket(i)->socket_values.local_address.sin6_port == name->sin6_port)) { return -1; } } memcpy(&socket_base_get_socket(s)->socket_values.local_address, name, namelen); socket_base_get_socket(s)->recv_pid = pid; return 0; }
int socket_base_close(int s) { socket_internal_t *current_socket = socket_base_get_socket(s); if (udp_socket_compliancy(s)) { memset(current_socket, 0, sizeof(socket_internal_t)); return 0; } else if (tcp_socket_compliancy(s)) { return tcp_teardown(current_socket); } printf("Socket Type not supported!\n"); return -1; }
socket_internal_t *get_tcp_socket_by_context(ipv6_hdr_t *current_ipv6_header, uint16_t current_context) { socket_internal_t *temp_socket; for (int i = 1; i < MAX_SOCKETS + 1; i++) { temp_socket = socket_base_get_socket(i); if ((temp_socket != NULL) && ipv6_addr_is_equal(&temp_socket->socket_values.foreign_address.sin6_addr, ¤t_ipv6_header->srcaddr) && ipv6_addr_is_equal(&temp_socket->socket_values.local_address.sin6_addr, ¤t_ipv6_header->destaddr) && (temp_socket->socket_values.tcp_control.tcp_context.context_id == current_context)) { return temp_socket; } } return NULL; }
int socket_base_socket(int domain, int type, int protocol) { int i = 1; while (socket_base_get_socket(i) != NULL) { i++; } if (i > MAX_SOCKETS) { return -1; } socket_t *current_socket = &socket_base_sockets[i - 1].socket_values; socket_base_sockets[i - 1].socket_id = i; current_socket->domain = domain; current_socket->type = type; current_socket->protocol = protocol; #ifdef MODULE_TCP current_socket->tcp_control.state = 0; #endif return socket_base_sockets[i - 1].socket_id; }
int32_t udp_sendto(int s, const void *buf, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen) { (void) flags; (void) tolen; if (udp_socket_compliancy(s) && (socket_base_get_socket(s)->socket_values.foreign_address.sin6_port == 0)) { uint8_t send_buffer[BUFFER_SIZE]; ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); udp_hdr_t *current_udp_packet = ((udp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN]; memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); ipv6_net_if_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); current_udp_packet->src_port = socket_base_get_free_source_port(IPPROTO_UDP); current_udp_packet->dst_port = to->sin6_port; current_udp_packet->checksum = 0; memcpy(payload, buf, len); current_udp_packet->length = HTONS(UDP_HDR_LEN + len); temp_ipv6_header->length = UDP_HDR_LEN + len; current_udp_packet->checksum = ~ipv6_csum(temp_ipv6_header, (uint8_t *) current_udp_packet, UDP_HDR_LEN + len, IPPROTO_UDP); return ipv6_sendto(&to->sin6_addr, IPPROTO_UDP, (uint8_t *)(current_udp_packet), NTOHS(current_udp_packet->length), NULL); } else { return -1; } }
int socket_base_bind(int s, sockaddr6_t *addr, int addrlen) { if (socket_base_exists_socket(s)) { socket_t *current_socket = &socket_base_get_socket(s)->socket_values; switch (current_socket->domain) { case (PF_INET): { /* Not provided */ return -1; break; } case (PF_INET6): { switch (current_socket->type) { /* TCP */ case (SOCK_STREAM): { if ((current_socket->protocol == 0) || (current_socket->protocol == IPPROTO_TCP)) { return tcp_bind_socket(s, addr, addrlen, thread_getpid()); break; } else { return -1; break; } break; } /* UDP */ case (SOCK_DGRAM): { if ((current_socket->protocol == 0) || (current_socket->protocol == IPPROTO_UDP)) { return udp_bind_socket(s, addr, addrlen, thread_getpid()); break; } else { return -1; break; } break; } case (SOCK_SEQPACKET): { /* not provided */ return -1; break; } case (SOCK_RAW): { /* not provided */ return -1; break; } default: { return -1; break; } } break; } case (PF_UNIX): { /* Not provided */ return -1; break; } } } else { printf("SOCKET DOES NOT EXIST!\n"); return -1; } return -1; }