猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

Ryuのソースコードリーディング その3 パケットの送信

パケットを作成して、NICからの送信を行います。

パケットの作成

 パケットを作成したのちに、add_protocolでL2、L3各レイヤーのヘッダを入れていきます。ここではL3までのパケットを作成しました。引数に指定していないので、デフォルトで設定されている値がヘッダに含まれています。get_protocolでヘッダの中身を表示させています。

>>> from ryu.lib.packet import *
>>> from ryu.lib.packet import ipv4

>>> pkt = packet.Packet()

>>> pkt.add_protocol(ethernet.ethernet())
>>> pkt.get_protocol(ethernet.ethernet)
ethernet(dst='ff:ff:ff:ff:ff:ff',ethertype=2048,src='00:00:00:00:00:00')

>>> pkt.add_protocol(ipv4.ipv4())
>>> pkt.get_protocol(ipv4.ipv4)
ipv4(csum=0,dst='0.0.0.0',flags=0,header_length=5,identification=0,offset=0,option=None,proto=0,src='0.0.0.0',tos=0,total_length=0,ttl=255,version=4)

パケットの送信

 serializeで作成したパケットをバイナリ化して、NICから送信します。serialize前はdataは空ですが、serialize後はバイナリが入っていることが確認できます。そのデータをrawSocketプログラミングの要領で送信します。

>>> pkt.data

>>> pkt.serialize()
>>> pkt.data
bytearray(b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00\x14\x00\x00\x00\x00\xff\x00\xbb\xea\x00\x00\x00\x00\x00\x00\x00\x00')

>>> from socket import *
>>> rawSocket = socket(AF_PACKET, SOCK_RAW)
>>> rawSocket.bind(("eth1", 0))
>>> rawSocket.send(pkt.data)

パケットのキャプチャ

 送信したパケットをキャプチャした結果は以下のとおりです。確かに「パケットの作成」で設定したパケットが送信されているのを確認できます。
f:id:alexei-karamazov:20131228002447p:plain