0
votes

I'm trying to learn the Ryu SDN Controller for a personal project, and i need to know certain packet information to decide what to do with it.

I've already imported :

from ryu.lib.packet import ethernet
from ryu.lib.packet import packet
from ryu.lib.packet import arp
from ryu.lib.packet import ipv4
from ryu.lib.packet import tcp
from ryu.lib.packet import tcp

And with the above modules i've made a sequence of prints to check de full packet especifications:

msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']

pkt = packet.Packet(msg.data)
eth = pkt.get_protocols(ethernet.ethernet)[0]
arp_pkt = pkt.get_protocol(arp.arp)
ipv4_pkt = pkt.get_protocol(ipv4.ipv4)
tcp_pkt = pkt.get_protocol(tcp.tcp)
udp_pkt = pkt.get_protocol(udp.udp)

print("\nEth pkt: {0}".format(eth))
print("\nIPV4 pkt: {0}".format(ipv4_pkt))
print("\nARP pkt: {0}".format(arp_pkt))
print("\nTCP pkt: {0}".format(tcp_pkt))
print("\nUDP pkt: {0}".format(udp_pkt))

and when i try to estabilish a TCP connection i receive the following prints:

Eth pkt: ethernet(dst='00:00:00:00:00:02',ethertype=2048,src='00:00:00:00:00:01')

IPV4 pkt: ipv4(csum=32564,dst='10.0.0.2',flags=2,header_length=5,identification=42869,offset=0,option=None,proto=6,src='10.0.0.1',tos=16,total_length=60,ttl=64,version=4)

ARP pkt: None

TCP pkt: tcp(ack=0,bits=2,csum=6900,dst_port=5001,offset=10,option='\x02\x04\x05\xb4\x04\x02\x08\n\x00\x10\xf05\x00\x00\x00\x00\x01\x03\x03\t',seq=1729779520,src_port=58573,urgent=0,window_size=29200)

UDP pkt: None
packet in 1 00:00:00:00:00:01 00:00:00:00:00:02 1

my question is: how do i for instance retrive de destination port from insde tcp_pkt :

tcp_pkt = tcp(ack=0,bits=2,csum=6900,dst_port=5001,offset=10,option='\x02\x04\x05\xb4\x04\x02\x08\n\x00\x10\xf05\x00\x00\x00\x00\x01\x03\x03\t',seq=1729779520,src_port=58573,urgent=0,window_size=29200)

is there something like tcp_pkt.dst()? Or is there a another way to catch that value?

2

2 Answers

0
votes

The Ryu repository is on GitHub and can be found here.

If you take a look at the packet module, you'll find a file called tcp.py.

For extracting the destination port from a given network packet, you need to access the transport layer header. In this case it is TCP, so from the file (tcp.py) that I included above you can see that there is a variable called dst_port.

Therefore, in your code you should include:

from ryu.lib.packet import ethernet, packet, arp, ipv4, tcp, udp

msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']

pkt = packet.Packet(msg.data)
eth = pkt.get_protocols(ethernet.ethernet)[0]
arp_pkt = pkt.get_protocol(arp.arp)
ipv4_pkt = pkt.get_protocol(ipv4.ipv4)
#fetches 3rd item from list of protocols (tcp or udp). Instead of having separate udp and tcp
layer4_header = pkt.protocols[2]
#Now to extract the destination port
destination_port = layer4_header.dst_port
0
votes

TCP Source port and Destination ports can be retrieved just like you retrieve ethernet source and destination MAC addresses. However, you have to put a small check in order to make sure if there is TCP traffic:

if pkt.get_protocols(tcp.tcp):
    print(pkt.get_protocols(tcp.tcp)[0].dst_port)