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)
パケットのキャプチャ
送信したパケットをキャプチャした結果は以下のとおりです。確かに「パケットの作成」で設定したパケットが送信されているのを確認できます。