Skip to content
Extraits de code Groupes Projets
our_utils.c 3,98 ko
Newer Older
  • Learn to ignore specific revisions
  • #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>
    
    
    Vany Ingenzi's avatar
    Vany Ingenzi a validé
    #include "log.h"
    
    #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);
    
    Vany Ingenzi's avatar
    Vany Ingenzi a validé
        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));
    
    Vany Ingenzi's avatar
    Vany Ingenzi a validé
        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)
    {
    
    Vany Ingenzi's avatar
    Vany Ingenzi a validé
        if ( source_addr != NULL && dest_addr == NULL )
    
        {
            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){ 
    
            return -1;
        }
    
        int err             = connect(sfd, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_storage));
    
        if (err != EISCONN && err != 0)
            return -1;
    
        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));
    
        return 0;
    }