# Class describing interception transferred through HI1
#
# Copyright (C) 2011 Matej Gregr, Michal Kajan, Libor Polcak,
#                    Vladimir Vesely, Petr Kramolis
#
# 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 2
# of the License.
# 
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import os
import time
import scapy.all as scapy
from IPy import IP

from ..tools.numeric import inttoNbytes

def inttoNbytes2(integer, bytes_count):
    return "".join([chr(d) for d in eval(inttoNbytes(int(integer), bytes_count))])

def ipv4tobytes(ipstr):
    return "".join([chr(int(d)) for d in reversed(ipstr.split("."))])

def ipv6tobytes(ipstr):
    fullstr = IP(ipstr).strFullsize().replace(":", "")
    res = ""
    for i in range(15, -1, -1):
        res += chr(int(fullstr[(i*2):(i+1)*2], 16))
    return res

reserved = inttoNbytes2(0, 1)

def fill_LiPacket(scapy_packet):
    blob_size = inttoNbytes2(len(scapy_packet), 2)
    ifc = inttoNbytes2(1, 1) # FIXME incorrect ifc number

    timestamp = time.time()
    sec = int(timestamp)
    tssec = inttoNbytes2(sec, 4)
    tsnsec = inttoNbytes2(int(round((timestamp-sec)*1000000000)), 4)

    ip=scapy_packet.getlayer(scapy.IP,1)
    if ip is  None:
        ip=scapy_packet.getlayer(scapy.IPv6,1)

    if ip is None:
        return None # Do not process non-IP

    version = ip.version
    l3_version = inttoNbytes2(version, 1)
    if version == 4:
        dst_ip = ipv4tobytes(ip.dst)
        src_ip = ipv4tobytes(ip.src)
    elif version == 6:
        dst_ip = ipv6tobytes(ip.dst)
        src_ip = ipv6tobytes(ip.dst)
    else:
        return None # Unsuported version

    l4 = ip.getlayer(scapy.TCP, 1)
    if l4:
        proto = 6
    else:
        l4 = ip.getlayer(scapy.UDP, 1)
        if l4:
            proto = 17
        else:
            proto = 0

    if l4:
        src_port = l4.sport
        dst_port = l4.dport
    else:
        src_port = 0
        dst_port = 0

    message = blob_size + ifc + reserved + \
            tssec + \
            tsnsec + \
            reserved * 4 + \
            l3_version + inttoNbytes2(proto, 1) + reserved*2 + \
            src_ip + \
            dst_ip + \
            inttoNbytes2(src_port, 2) + \
            inttoNbytes2(dst_port, 2) + \
            str(scapy_packet)
    return message

