mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
300 lines
6.5 KiB
C
300 lines
6.5 KiB
C
|
/*
|
||
|
* socket.c
|
||
|
*
|
||
|
* Created on: 16.09.2011
|
||
|
* Author: Oliver
|
||
|
*/
|
||
|
#include <thread.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include "udp.h"
|
||
|
#include "socket.h"
|
||
|
|
||
|
void print_socket(uint8_t socket)
|
||
|
{
|
||
|
socket = socket - 1;
|
||
|
printf ("---SOCKET---\n");
|
||
|
printf("Value: %i, Domain: %i, Type: %i, Protocol: %i \n", sockets[socket].socket, sockets[socket].domain, sockets[socket].type, sockets[socket].protocol);
|
||
|
printf("Port: %i, Family: %i\n", sockets[socket].sa.sin6_port, sockets[socket].sa.sin6_family);
|
||
|
ipv6_print_addr(&sockets[socket].sa.sin6_addr);
|
||
|
}
|
||
|
|
||
|
bool exists_socket(uint8_t socket)
|
||
|
{
|
||
|
if (sockets[socket-1].socket == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
socket_t* getSocket(uint8_t s)
|
||
|
{
|
||
|
if (exists_socket(s))
|
||
|
return &sockets[s-1];
|
||
|
else
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
bool isUDPSocket(uint8_t s)
|
||
|
{
|
||
|
if ((exists_socket(s)) && (getSocket(s)->domain == PF_INET6) && (getSocket(s)->type == SOCK_DGRAM) && ((getSocket(s)->protocol == IPPROTO_UDP) || (getSocket(s)->protocol == 0)))
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool isTCPSocket(uint8_t s)
|
||
|
{
|
||
|
if ((exists_socket(s)) && (getSocket(s)->domain == PF_INET6) && (getSocket(s)->type == SOCK_DGRAM) && ((getSocket(s)->protocol == IPPROTO_UDP) || (getSocket(s)->protocol == 0)))
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int bind_udp_socket(int s, struct sockaddr_in6 *name, int namelen, uint8_t pid)
|
||
|
{
|
||
|
int i;
|
||
|
if (!exists_socket(s))
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
for (i = 1; i < MAX_SOCKETS+1; i++)
|
||
|
{
|
||
|
if (isUDPSocket(i) && (getSocket(i)->sa.sin6_port == name->sin6_port))
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
memcpy(&getSocket(s)->sa, name, namelen);
|
||
|
getSocket(s)->pid = pid;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int socket(int domain, int type, int protocol)
|
||
|
{
|
||
|
int i = 1;
|
||
|
while (getSocket(i) != NULL)
|
||
|
{
|
||
|
i++;
|
||
|
}
|
||
|
if (i > MAX_SOCKETS+1)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
struct socket_t *current_socket = &sockets[i-1];
|
||
|
current_socket->socket = i;
|
||
|
current_socket->domain = domain;
|
||
|
current_socket->type = type;
|
||
|
current_socket->protocol = protocol;
|
||
|
return current_socket->socket;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int connect(int socket, struct sockaddr_in6 *addr, uint32_t addrlen)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int32_t send(int s, void *msg, uint64_t len, int flags)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int32_t recv(int s, void *buf, uint64_t len, int flags)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int32_t recvfrom(int s, void *buf, uint64_t len, int flags, struct sockaddr_in6 *from, uint32_t *fromlen)
|
||
|
{
|
||
|
msg_t m_recv, m_send;
|
||
|
struct ipv6_hdr_t *ipv6_header;
|
||
|
struct udp_hdr_t *udp_header;
|
||
|
uint8_t *payload;
|
||
|
uint16_t payload_size = 0;
|
||
|
|
||
|
msg_receive(&m_recv);
|
||
|
|
||
|
ipv6_header = ((struct ipv6_hdr_t*)&buffer);
|
||
|
udp_header = ((struct udp_hdr_t*)(&buffer[IPV6_HDR_LEN]));
|
||
|
payload = &buffer[IPV6_HDR_LEN+UDP_HDR_LEN];
|
||
|
|
||
|
memset(buf, 0, len);
|
||
|
memcpy(buf, payload, udp_header->length);
|
||
|
payload_size = udp_header->length;
|
||
|
memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16);
|
||
|
memset(&from->sin6_family, AF_INET6, 1);
|
||
|
memset(&from->sin6_flowinfo, 0, 4);
|
||
|
memcpy(&from->sin6_port, &udp_header->src_port, sizeof(udp_header->src_port));
|
||
|
memcpy(fromlen, (void*)(sizeof(sockaddr_in6)), sizeof(fromlen));
|
||
|
msg_reply(&m_recv, &m_send);
|
||
|
return payload_size;
|
||
|
}
|
||
|
|
||
|
int32_t sendto(int s, void *msg, uint64_t len, int flags, struct sockaddr_in6 *to, uint32_t tolen)
|
||
|
{
|
||
|
if (exists_socket(s))
|
||
|
{
|
||
|
if (isUDPSocket(s) && (getSocket(s)->sa.sin6_port == 0))
|
||
|
{
|
||
|
uint8_t send_buffer[UDP_STACK_SIZE];
|
||
|
|
||
|
struct ipv6_hdr_t *temp_ipv6_header = ((struct ipv6_hdr_t*)(&send_buffer));
|
||
|
struct udp_hdr_t *temp_udp_header = ((struct udp_hdr_t*)(&send_buffer[IPV6_HDR_LEN]));
|
||
|
uint8_t *payload = &send_buffer[IPV6_HDR_LEN+UDP_HDR_LEN];
|
||
|
|
||
|
ipv6_print_addr(&to->sin6_addr);
|
||
|
|
||
|
memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16);
|
||
|
ipv6_get_saddr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr));
|
||
|
temp_ipv6_header->version_trafficclass = IPV6_VER;
|
||
|
temp_ipv6_header->trafficclass_flowlabel = 0;
|
||
|
temp_ipv6_header->flowlabel = 0;
|
||
|
temp_ipv6_header->nextheader = IPPROTO_UDP;
|
||
|
temp_ipv6_header->hoplimit = MULTIHOP_HOPLIMIT;
|
||
|
temp_ipv6_header->length = sizeof(temp_udp_header);
|
||
|
|
||
|
temp_udp_header->src_port = 0;
|
||
|
temp_udp_header->dst_port = to->sin6_port;
|
||
|
temp_udp_header->checksum = 0;
|
||
|
|
||
|
memcpy(payload, msg, len);
|
||
|
temp_udp_header->length = UDP_HDR_LEN + len;
|
||
|
|
||
|
temp_udp_header->checksum = ~udp_csum(temp_ipv6_header, temp_udp_header);
|
||
|
|
||
|
printf("Content of UDP Packet: src_port: %i, dst_port: %i, length: %i, checksum: %x\n", temp_udp_header->src_port, temp_udp_header->dst_port, temp_udp_header->length, temp_udp_header->checksum);
|
||
|
sixlowpan_send(&to->sin6_addr, (uint8_t*)(temp_udp_header), temp_udp_header->length, IPPROTO_UDP);
|
||
|
return temp_udp_header->length;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int close(int s)
|
||
|
{
|
||
|
if (exists_socket(s))
|
||
|
{
|
||
|
memset(getSocket(s), 0, sizeof(socket_t));
|
||
|
return 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int bind(int s, struct sockaddr_in6 *name, int namelen, uint8_t pid)
|
||
|
{
|
||
|
if (exists_socket(s))
|
||
|
{
|
||
|
socket_t *current_socket = getSocket(s);
|
||
|
switch (current_socket->domain)
|
||
|
{
|
||
|
case (PF_INET):
|
||
|
{
|
||
|
// Not provided
|
||
|
return -1;
|
||
|
break;
|
||
|
}
|
||
|
case (PF_INET6):
|
||
|
{
|
||
|
switch (current_socket->type)
|
||
|
{
|
||
|
case (SOCK_STREAM):
|
||
|
{
|
||
|
// TODO: TCP sock allocation
|
||
|
return -1;
|
||
|
break;
|
||
|
}
|
||
|
case (SOCK_DGRAM):
|
||
|
{
|
||
|
if ((current_socket->protocol == 0) || (current_socket->protocol == IPPROTO_UDP))
|
||
|
{
|
||
|
return bind_udp_socket(s, name, namelen, pid);
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
int listen(int s, int backlog)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
int accept(int s, struct sockaddr_in6 *addr, uint32_t addrlen)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
int get_udp_process(uint16_t port)
|
||
|
{
|
||
|
uint8_t i = 1;
|
||
|
while (i < MAX_SOCKETS+1)
|
||
|
{
|
||
|
if ((exists_socket(i)) && isUDPSocket(i) && (getSocket(i)->sa.sin6_port == port))
|
||
|
{
|
||
|
return getSocket(i)->pid;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|