static int TCP_handle_incoming_ipv4_packet(tsTCPThreadInfo *psTCPThreadInfo)
{
    ssize_t iBytesRecieved;
    
#define PACKET_BUFFER_SIZE 4096
    char buffer[PACKET_BUFFER_SIZE];
    int iProtocolVersion;
    
    iBytesRecieved = recv(psTCPThreadInfo->iClientSocket, buffer, 1, 0);
    if (iBytesRecieved != 1)
    {
        daemon_log(LOG_ERR, "Could not get TCP packet header");
        return iBytesRecieved;
    }
    iProtocolVersion = buffer[0];
    
    switch (iProtocolVersion)
    {
        case (1):
        {
            uint16_t u16PacketLength;
            iBytesRecieved = recv(psTCPThreadInfo->iClientSocket, &u16PacketLength, 2, 0);
            if (iBytesRecieved != 2)
            {
                daemon_log(LOG_ERR, "Could not get TCP packet length");
                return iBytesRecieved;
            }
            u16PacketLength = ntohs(u16PacketLength);
            
            iBytesRecieved = recv(psTCPThreadInfo->iClientSocket, buffer, u16PacketLength, 0);
            if (iBytesRecieved != u16PacketLength)
            {
                daemon_log(LOG_ERR, "Could not get TCP packet payload");
                return iBytesRecieved;
            }
            
            {
                char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
                inet_ntop(AF_INET, &psTCPThreadInfo->sClientIPv4Address.sin_addr, buffer, INET6_ADDRSTRLEN);
                if (verbosity >= LOG_DEBUG)
                {
                    daemon_log(LOG_DEBUG, "Data from client %s:%d: %d bytes", buffer, ntohs(psTCPThreadInfo->sClientIPv4Address.sin_port), (int)iBytesRecieved);
                }
            }
        
            {
                int iBytesSent;
                struct sockaddr_in6 sDestAddress;
                const uint32_t u32HeaderSize = sizeof(struct in6_addr);

                memset (&sDestAddress, 0, sizeof(struct sockaddr_in6));
                sDestAddress.sin6_family  = AF_INET6;
                sDestAddress.sin6_port    = htons(1873);

                {
                    /* Check if this packet is intended for the coordinator */
                    char acCoordAddr[sizeof(struct in6_addr)] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
                    if (memcmp(acCoordAddr, buffer, sizeof(struct in6_addr)) == 0)
                    {
#ifdef USE_ZEROCONF
                        int iNumAddresses;
                        struct in6_addr *asAddresses;
                        if (ZC_Get_Module_Addresses(&asAddresses, &iNumAddresses) != 0)
                        {
                            daemon_log(LOG_ERR, "Could not get coordinator address");
                            return -1;
                        }
                        
                        if (iNumAddresses != 1)
                        {
                            daemon_log(LOG_ERR, "Got an unhandled number of coordinators (%d)", iNumAddresses);
                            return -1;
                        }
                        else
                        {
                            char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
                            inet_ntop(AF_INET6, asAddresses, buffer, INET6_ADDRSTRLEN);
                            daemon_log(LOG_INFO, "Got coordinator address %s", buffer);
                        }
                        memcpy(&sDestAddress.sin6_addr, asAddresses, sizeof(struct in6_addr));
                        free(asAddresses);
#else /* USE_ZEROCONF */
                        /* Read the address from the textfile */
                        if (Get_Module_Address(&sDestAddress.sin6_addr) == 0)
                        {
                            char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
                            inet_ntop(AF_INET6, asAddresses, buffer, INET6_ADDRSTRLEN);
                            daemon_log(LOG_INFO, "Got coordinator address %s", buffer);
                        }
                        else
                        {
                            return -1;
                        }
#endif /* USE_ZEROCONF */
                    }
                    else
                    {
                        memcpy(&sDestAddress.sin6_addr, buffer, sizeof(struct in6_addr));
                    }
                    
                    iBytesSent = sendto(psTCPThreadInfo->iIPv6Socket, &buffer[u32HeaderSize], iBytesRecieved-u32HeaderSize, 0, 
                                               (struct sockaddr*)&sDestAddress, sizeof(struct sockaddr_in6));
                }
            }
            break;
        }
        default:
            daemon_log(LOG_ERR, "Unknown protocol version %d", iProtocolVersion);
            break;
    }
#undef PACKET_BUFFER_SIZE
    return iBytesRecieved;
}
Пример #2
0
static int handle_incoming_ipv4_packet(int listen_socket)
{
    ssize_t iBytesRecieved;
    struct sockaddr_in IPv4Address;
    unsigned int AddressSize = sizeof(struct sockaddr_in);
    tsConectionMapping *psMapping;
    
#define PACKET_BUFFER_SIZE 4096
    char buffer[PACKET_BUFFER_SIZE];
    
    iBytesRecieved = recvfrom(listen_socket, buffer, PACKET_BUFFER_SIZE, 0,
                                                (struct sockaddr*)&IPv4Address, &AddressSize);
    if (iBytesRecieved > 0)
    {
        psMapping = psGetMapping(&IPv4Address);
        if (!psMapping)
        {
            char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
            inet_ntop(AF_INET, &IPv4Address.sin_addr, buffer, INET6_ADDRSTRLEN);
            if (verbosity >= LOG_DEBUG)
            {
                daemon_log(LOG_DEBUG, "Creating mapping for new client %s:%d", buffer, ntohs(IPv4Address.sin_port));
            }
            psMapping = psCreateMapping(&IPv4Address);
        }
        
        {
            char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
            inet_ntop(AF_INET, &IPv4Address.sin_addr, buffer, INET6_ADDRSTRLEN);
            if (verbosity >= LOG_DEBUG)
            {
                daemon_log(LOG_DEBUG, "Data from client %s:%d: %d bytes", buffer, ntohs(IPv4Address.sin_port), iBytesRecieved);
            }
        }

        if (psMapping)
        {
            int iBytesSent;
            struct sockaddr_in6 sDestAddress;
            uint32_t u32HeaderSize;
            
            //printf("Forwarding packet payload to port %x\n", htons(1873));
            
            /* Update last packet time */
            gettimeofday(&psMapping->sLastPacketTime, NULL);
            
            memset (&sDestAddress, 0, sizeof(struct sockaddr_in6));
            sDestAddress.sin6_family  = AF_INET6;
            sDestAddress.sin6_port    = htons(1873);
            
            switch (buffer[0]) /* Version field */
            {
                case (1): 
                    u32HeaderSize = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(struct in6_addr);

                    /* Check if this packet is intended for the coordinator */
                    char acCoordAddr[sizeof(struct in6_addr)] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
                    
                    if (memcmp(acCoordAddr, &buffer[sizeof(uint8_t) + sizeof(uint16_t)], sizeof(struct in6_addr)) == 0)
                    {
#ifdef USE_ZEROCONF
                        int iNumAddresses;
                        struct in6_addr *asAddresses;
                        if (ZC_Get_Module_Addresses(&asAddresses, &iNumAddresses) != 0)
                        {
                            daemon_log(LOG_ERR, "Could not get coordinator address");
                            return -1;
                        }
                        
                        if (iNumAddresses != 1)
                        {
                            daemon_log(LOG_ERR, "Got an unhandled number of coordinators (%d)", iNumAddresses);
                            return -1;
                        }
                        else
                        {
                            char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
                            inet_ntop(AF_INET6, asAddresses, buffer, INET6_ADDRSTRLEN);
                            daemon_log(LOG_INFO, "Got coordinator address %s", buffer);
                        }
                        memcpy(&sDestAddress.sin6_addr, asAddresses, sizeof(struct in6_addr));
                        free(asAddresses);
#else /* USE_ZEROCONF */
                        /* Read the address from the textfile */
                        if (Get_Module_Address(&sDestAddress.sin6_addr) == 0)
                        {
                            char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
                            inet_ntop(AF_INET6, asAddresses, buffer, INET6_ADDRSTRLEN);
                            daemon_log(LOG_INFO, "Got coordinator address %s", buffer);
                        }
                        else
                        {
                            return -1;
                        }
#endif /* USE_ZEROCONF */
                    }
                    else
                    {
                        memcpy(&sDestAddress.sin6_addr, &buffer[sizeof(uint8_t) + sizeof(uint16_t)], sizeof(struct in6_addr));
                    }
                    break;
                    
                default:
                    daemon_log(LOG_ERR, "Unknown JIPv4 header version");
                    return -1;
            }
            
            iBytesSent = sendto(psMapping->iIPv6Socket, &buffer[u32HeaderSize], iBytesRecieved-u32HeaderSize, 0, 
                    (struct sockaddr*)&sDestAddress, sizeof(struct sockaddr_in6));
            if (verbosity >= LOG_DEBUG)
            {
                char buffer[INET6_ADDRSTRLEN] = "Could not determine address\n";
                inet_ntop(AF_INET6, &sDestAddress.sin6_addr, buffer, INET6_ADDRSTRLEN);
                daemon_log(LOG_DEBUG, "Sent %d bytes to address %s", iBytesSent, buffer);
            }
        }
    }
    else
    {
        daemon_log(LOG_DEBUG, "Received a weird number of bytes %d", iBytesRecieved);
    }
#undef PACKET_BUFFER_SIZE
    return 0;
}