This section is about recipes to resolve a particular problem using scapy.

Send a response back to a captured packet

We want to sniff only one packet that is sent to the default interface in udp towards port 5060:

>>> pkt = sniff(count=1, filter="udp and dst port 5060")

Once data captured, this is how our packet looks:

>>> print pkt
[<Ether  dst=00:00:00:00:00:00 src=00:00:00:00:00:00 type=IPv4 |<IP  version=4L ihl=5L tos=0x0 len=453 id=414 flags=DF frag=0L ttl=64 proto=udp chksum=0xadbf src=192.168.4.61 dst=192.168.4.67 options='' |<UDP  sport=1115 dport=sip len=433 chksum=0x8b8d |<Raw  load='INVITE sip:grosnaindesbois@example.com SIP/2.0\r\nVia: exemple.com\r\nFrom: root <sip:nonalaeroport@example.com>;tag=deadbeaf31337\r\nTo: <sip:grosnaindesbois@example.com>\r\nCall-ID: 12a147fa901999f915788f8d8b262d92@example.com\r\nCseQ: 20 PUBLISH\r\nContact: <sip:nonalaeroport@example.com>\r\nMax_forwards: 70\r\nUser Agent: yaua, Yet Another UA v.0.42\r\nContent-Type: application/sdp\r\nSubject: STR Test\r\nExpires: 7200\r\nContent-Length: 0\r\n' |>>>>]
>>> 

Let's look at our data stacked by scapy:

>>> ipdata = pkt[IP]
>>> ipdata.show()
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 453
  id= 414
  flags= DF
  frag= 0L
  ttl= 64
  proto= udp
  chksum= 0xadbf
  src= 192.168.4.61
  dst= 192.168.4.61
  options= ''
###[ UDP ]###
     sport= 1115
     dport= sip
     len= 433
     chksum= 0x8b8d
###[ Raw ]###
        load= 'INVITE sip:grosnaindesbois@example.com SIP/2.0\r\nVia: exemple.com\r\nFrom: root <sip:nonalaeroport@example.com>;tag=deadbeaf31337\r\nTo: <sip:grosnaindesbois@example.com>\r\nCall-ID: 12a147fa901999f915788f8d8b262d92@example.com\r\nCseQ: 20 PUBLISH\r\nContact: <sip:nonalaeroport@example.com>\r\nMax_forwards: 70\r\nUser Agent: yaua, Yet Another UA v.0.42\r\nContent-Type: application/sdp\r\nSubject: STR Test\r\nExpires: 7200\r\nContent-Length: 0\r\n'
>>> 

Now we want to reply the same answer, we just invert source/destination IP and ports and we are done:

>>> source=ipdata.getlayer(IP).dst
>>> destination=ipdata.getlayer(IP).src
>>> sourceport=ipdata.getlayer(UDP).dport
>>> destinationport=ipdata.getlayer(UDP).sport

We now build the packet we want to send:

>>> rpkt = IP(src=source,dst=destination)/UDP(sport=sourceport, dport=destinationport)/ipdata.getlayer(Raw)

And we send it:

>>> send(rpkt)
.
Sent 1 packets.
>>>