# Network-related conversions conversions
#
# Copyright (C) 2012 Michal Kajan, Libor Polčák, Petr Kramoliš, Martin Holkovič
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
This module collects functions and classes related to processing of network
data structures and their conversions.
"""

import IPy
import binascii
import socket

def ipv6to128bits(ipv6):
    """ Converts given IPv6 addres to 128-bits-long bytes """
    addr = ipv6.strFullsize().replace(":", "").split("/")[0]
    return bytes(reversed(bytes.fromhex(addr)))

def ipv6from128bits(ipv6, netmask = 128):
    """ Converts given 128-bits-long bytes to IPv6 address """
    addrstr = str(binascii.hexlify(bytes(reversed(ipv6))), "utf8")
    return IPy.IP(addrstr + "/%d" % netmask, 6)

def recv_bytes(s, byte_count):
    """ Receives byte_count bytes from socket s

    Blocks until specified amount of bytes is received.
    """
    data = b""
    empty_count = 0
    while len(data) < byte_count:
        remaining = byte_count - len(data)
        data += s.recv(remaining)
        if len(data) == 0:
            empty_count += 1
            if empty_count == 5:
                raise socket.error("tools.recv_bytes: Cannot read bytes from socket, is it closed?")
    return data
