Newer
Older
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "our_utils.h"
const char * real_address(const char *address, struct sockaddr_in6 *rval)
{
struct addrinfo hints;
struct addrinfo *result;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_CANONNAME;
hints.ai_protocol = 0;
int res = getaddrinfo(address, NULL, &hints, &result);
if ( res != 0 )
return gai_strerror(res);
rval = (struct sockaddr_in6 *) memcpy( (void *) rval, result->ai_addr, sizeof(struct sockaddr_in6));
freeaddrinfo(result);
return NULL;
}
void ipv6_to_str_unexpanded(char *str, const struct in6_addr *addr) {
sprintf(str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
(int)addr->s6_addr[0], (int)addr->s6_addr[1],
(int)addr->s6_addr[2], (int)addr->s6_addr[3],
(int)addr->s6_addr[4], (int)addr->s6_addr[5],
(int)addr->s6_addr[6], (int)addr->s6_addr[7],
(int)addr->s6_addr[8], (int)addr->s6_addr[9],
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
}
int create_socket_bind(struct sockaddr_in6 * source_addr)
{
// TODO: Create a IPv6 socket supporting datagrams
int sock = socket(AF_INET6, SOCK_DGRAM, 0);
// TODO: Bind it to the source
int err = bind(sock, (struct sockaddr *) source_addr, sizeof(struct sockaddr_in6));
if (err == -1)
return -1;
char text[100];
ipv6_to_str_unexpanded(text, &(source_addr->sin6_addr));
//const char * addr_str = inet_ntop(AF_INET6, (void *) &(source_addr->sin6_addr), text, 100);
DEBUG("Successfully bound to IPv6 address : %s, port : %d", text, ntohs(source_addr->sin6_port));
return sock;
}
int create_socket_connect(struct sockaddr_in6 * dest_addr)
{
int sock = socket(AF_INET6, SOCK_DGRAM, 0);
int err = connect(sock, (struct sockaddr *) dest_addr, sizeof(*dest_addr));
if (err == -1)
return -1;
char text[100];
ipv6_to_str_unexpanded(text, &(dest_addr->sin6_addr));
DEBUG("Successfully connected to IPv6 addresss: %s, port : %d", text, ntohs(dest_addr->sin6_port));
return sock;
}
int create_socket(struct sockaddr_in6 *source_addr, int src_port, struct sockaddr_in6 *dest_addr, int dst_port)
{
{
source_addr->sin6_port = htons(src_port);
return create_socket_bind(source_addr);
} else if ( source_addr == NULL && dest_addr != NULL ){
dest_addr->sin6_port = htons(dst_port);
return create_socket_connect(dest_addr);
}
return -1;
}
int wait_for_client(int sfd)
int MAX_MESSAGE_SIZE = 1024;
uint8_t buff[MAX_MESSAGE_SIZE]; // allocate the receive buffer on the stack
struct sockaddr_storage peer_addr; // allocate the peer's address on the stack. It will be initialized when we receive a message
socklen_t peer_addr_len = sizeof(struct sockaddr_storage); // variable that will contain the length of the peer's address
ssize_t amount_read = recvfrom(sfd, buff, MAX_MESSAGE_SIZE, MSG_PEEK, (struct sockaddr *) &peer_addr, &peer_addr_len);
if (amount_read == -1){
int err = connect(sfd, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_storage));
if (err != EISCONN && err != 0)
return -1;
Vany Ingenzi
a validé
char text[100];
struct sockaddr_in6 * cast = (struct sockaddr_in6 *) &peer_addr;
ipv6_to_str_unexpanded(text, &(cast->sin6_addr));
DEBUG("Successfully connected to IPv6 addresss: %s, port : %d", text, ntohs(cast->sin6_port));