#-------------------------------------------------------------------------------
# Name:        pcap_monitor.py
# Purpose:
#
# Author:      Diarmuid
#
# Created:     16/12/2013
# Copyright:   (c) ACRA 2013
# Licence:     <your licence>
# About:       This is a simple test script that loops through a pcap file pulling out the
#               packets.
#-------------------------------------------------------------------------------
 
import socket,os,struct,sys
import argparse
import datetime, time
 
 
import AcraNetwork.iNetX as inetx
import AcraNetwork.Pcap as pcap
from AcraNetwork.SimpleEthernet import mactoreadable
import AcraNetwork.ParserAligned as ParserAligned
 
 
 
 
def main():
 
    try:
        pcapfile = pcap.Pcap("SSR_ABM_102_capture_example1.pcap")
    except IOError:
        print "ERROR: Could not find input file SSR_ABM_102_capture_example1.pcap"
        exit()
 
    # Keep a running count of the packets
    packet_count = 1
    # Keep a count of previous sequence number to detect a dropped packets
    PreviousSeqNum = dict()
 
    while True: # while we are not at the end of the file
        try:
            # So we loop through the file one packet at a time. This will eventually return an
            # exception at the end of file so handle that when it occurs
            (eth_packet,ip_packet,udp_packet) = pcapfile.ReadNextUDPPacket()
 
 
            if udp_packet.isinetx: # This is a rough guess assuming the control word is 0x11000000
                inetx_packet = inetx.iNetX()
                inetx_packet.unpack(udp_packet.payload)
 
                #----------------------------
                # Check for dropped packet
                #----------------------------
                if inetx_packet.streamid not in PreviousSeqNum:
                    PreviousSeqNum[inetx_packet.streamid] = inetx_packet.sequence
                else:
                    if PreviousSeqNum[inetx_packet.streamid]+1 != inetx_packet.sequence:
                        print "ERROR: Dropped {} packets on streamid={:#x} at packet count={}".format(inetx_packet.sequence - PreviousSeqNum[inetx_packet.streamid] + 1,inetx_packet.streamid,packet_count)
                    PreviousSeqNum[inetx_packet.streamid] = inetx_packet.sequence
 
                print "----- StreamID={:#10x} SourceIP= {:10s} -----".format(inetx_packet.streamid,ip_packet.srcip)
                #--------------------------------------------------------------------------------
                # Packets on stream id 0x11121314 is a parser aligned block so lets look at this
                #--------------------------------------------------------------------------------
                if inetx_packet.streamid == 0x11121314:
                    parser_aligned_packet = ParserAligned.ParserAlignedPacket()
                    # unpack the payload as the parser data
                    parser_aligned_packet.unpack(inetx_packet.payload)
 
                    # Loop through all the blocks in the packet and spit them out
                    for pblock in parser_aligned_packet.parserblocks:
                        (payload_data,) =struct.unpack('>I',pblock.payload)
                        print "Sequence Number = {:8} Quadbyes={:5} Msgcnt={:5} BusId={:4} Elapsed={:20} ".format(inetx_packet.sequence, pblock.quadbytes,pblock.messagecount,pblock.busid,pblock.elapsedtime,payload_data)
 
 
            packet_count += 1
 
        except NotImplementedError:
            # We received a packet that we don't care about. So skip silently
            packet_count += 1
            pass
 
        except IOError:
            # We are at the end of the file so lets jump to the next file
            print ( "End of file reached")
            exit()
 
 
if __name__ == '__main__':
    main()