'How to modify PN field for each packet sent by Scapy (MACSec)

I'm trying to send created MACSec packets using Scapy in order to simulate Replay Protection faults. I'm not looking at receiving and processing them, just to send and capture (using tcpdump).

The problem with Scapy's MACSec implementation is that I can't see a way to increment the PN number with each packet, it all seems to be static on that end which is a problem as I can't simulate the Out Of Sequence event.

How would a loop look like which modifies PN on the fly (adds 1 for example)?

sa = MACsecSA(sci=b'\x52\x54\x00\x13\x01\x56\x00\x01', an=0, pn=1, key=b'aaaaaaaaaaaaaaaa', icvlen=16, encrypt=1, send_sci=1)

p = Ether(src='02:00:48:e2:00:01', dst='10:0e:7e:c3:c2:40')/IP(src='192.168.0.1', dst='192.168.0.2')/ICMP(type='echo-request')/"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"

m = sa.encap(p)
sendp(m count=5)
m.show()


Solution 1:[1]

You can create the scapy SA in a loop, increment the PN for each SA and send one packet per SA.

packet = Ether(dst=dmac, src='10:20:30:40:50:70') / Dot1Q(vlan=vlan) / \
                     IP(dst='100.100.100.3', src='192.168.0.1') / Raw(load='a' * 1000)
packets = []
for pn in range(100, 200):
    scapy_sa = MACsecSA(sci=ssci, an=0, pn=pn, key=bytes(sak, 'ascii'), encrypt=1, send_sci=1, icvlen=16)
    packets.append(scapy_sa.encrypt(scapy_sa.encap(packet)))
            
            # send your packets

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1