from scapy.all import *
import netifaces as ni
#import sys


def ThreeWay(lip, sip, sport):

    seq_num = RandShort()
    seq_num = int(seq_num)    

    ip_layer = IP(src=lip, dst=sip)
    syn_tcp_layer = TCP(sport=sport, dport=21, flags="S", seq=seq_num) 
    synack_packet = sr1(ip_layer/syn_tcp_layer, verbose=0)
    seq_num += 1
    ack_num = synack_packet.seq + 1
    ack_tcp_layer = TCP(sport=sport, dport=21, flags="A", seq=seq_num, ack=ack_num)
    res = sr1(ip_layer/ack_tcp_layer, verbose=0)
    
    ##Incrementing to send back
    seq_num = res[TCP].ack
    ack_num = res[TCP].seq
    return seq_num,ack_num, res

def main():
    server_ip="10.10.10.102"
    local_ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
    source_port = RandShort()
    source_port = int(source_port)
    sequence_number = 0
    acknowledgment_number = 0

    debugging = True

    sequence_number, acknowledgment_number, response_packet = ThreeWay(local_ip, server_ip, source_port)

    replay = sniff(offline="ftpsessionstart.pcap")
    replay_count = len(replay)
    replay_loop = 0

    load = 0

    if response_packet.haslayer(Raw):
        load = len(response_packet[Raw].load)
    else:
        load = 0


    replay[replay_loop][IP].src = local_ip
    replay[replay_loop][IP].dst = server_ip
    replay[replay_loop][IP].chksum = None
    replay[replay_loop][TCP].seq = sequence_number
    replay[replay_loop][TCP].ack = acknowledgment_number + load
    replay[replay_loop][TCP].sport = response_packet[TCP].dport
    replay[replay_loop][TCP].chksum = None 

    while True:
        
        if replay[replay_loop][TCP].flags == "A":
            sendp(replay[replay_loop], verbose=0)
            if debugging:
                print(replay[replay_loop][IP].src, replay[replay_loop][IP].dst, replay[replay_loop][TCP].seq, replay[replay_loop][TCP].ack)
        else:
            response_packet = srp1(replay[replay_loop], verbose=0)
            if replay[replay_loop].haslayer(Raw):
                if debugging:
                    print(replay[replay_loop][IP].src, replay[replay_loop][IP].dst, replay[replay_loop][TCP].seq, replay[replay_loop][TCP].ack, replay[replay_loop][Raw].load)
            else:
                if debugging:
                    print(replay[replay_loop][IP].src, replay[replay_loop][IP].dst, replay[replay_loop][TCP].seq, replay[replay_loop][TCP].ack)

            if response_packet.haslayer(Raw):
                load = len(response_packet[Raw].load)
                if debugging:
                    print(response_packet[IP].src, response_packet[IP].dst, response_packet[TCP].seq, response_packet[TCP].ack, response_packet[Raw].load)
            else:
                load = 0
                if debugging:
                    print(response_packet[IP].src, response_packet[IP].dst, response_packet[TCP].seq, response_packet[TCP].ack)      

        replay_loop += 1
        if replay_loop < replay_count:
            replay[replay_loop][IP].src = local_ip
            replay[replay_loop][IP].dst = server_ip
            replay[replay_loop][IP].chksum = None
            replay[replay_loop][TCP].seq = response_packet[TCP].ack
            replay[replay_loop][TCP].ack = response_packet[TCP].seq + load
            replay[replay_loop][TCP].sport = response_packet[TCP].dport
            replay[replay_loop][TCP].chksum = None 
        else:
            ##Further discussion with remote host would be after this
            break        


    print("Replay Complete")

if __name__ == "__main__":
    main()


