質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

917閲覧

pythonでICMPv6のIPヘッダを参照したい

iojglarnivo

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2022/11/25 08:45

前提、実現したいこと

pythonを用いてICMPv6メッセージを作成し、受け取るようなシステムを作っています。
ICMPv6ヘッダに自作のオプションを追加しているのでscapy,tcpdumpだとうまく解析できないため、socketライブラリを用いて受け取ったバイナリデータを読み取りたいです。
自作のオプションを含んだパケットの作成、送信は既に実現済みです。

発生している問題

socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMPV6)
だとICMPv6ヘッダを参照し自作オプションもバイナリデータで読み取れますが、IPv6ヘッダを受信できません。

socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_RAW)
だとIPv6ヘッダとICMPv6ヘッダから自作できますが、送信のみに対応しているようで受信できません。

ソースコード1

import socket

s=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMPV6)
s.bind(("",0))
packet,addr=s.recvfrom(1024)
print(packet)
#b'\x80\x00... といったようにICMPヘッダ以降のデータのみ出力

ソースコード2

import socket

s=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.bind(("",0))
packet,addr=s.recvfrom(1024)
print(packet)
#なにも出力されない

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matukeso

2022/11/25 09:27

ipv6ヘッダが欲しい理由はなんでしょう? ソースコード1でaddrに送信元ipv6 アドレスが乗ってたりして、それで十分ということはないですか。
iojglarnivo

2022/11/25 12:37

addrには送信元アドレスしか記載されず、宛先アドレスも参照したいからです。 (届いたパケットがユニキャストで届いたのかマルチキャストで届いたかなどで判別したいため)
guest

回答1

0

ベストアンサー

どのaddrにパケットが到着したかは、IPV6_PKTINFOをsetsosckoptしておけば、s.recvmsgしたときの付帯情報の方に入ってくるのでわかるかと。

python

1>>> s=socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6) 2>>> s.setsockopt( socket.IPPROTO_IPV6, 49, 1 ) 3>>> s.recvmsg( 1000, 200) 4(b'\x81\x00\'\xd7\x00\xe5\x00\x01\xce\xd8\x80c\x00\x00\x00\x00A\xb7\x06\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567', 5[(41, 50, b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00')], 6 0, ('::1', 0, 0, 0)) 7>>>

投稿2022/11/25 15:04

matukeso

総合スコア1588

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iojglarnivo

2022/11/25 16:05

ありがとうございます。ほしいデータが手に入りました。 socketのプロトコルについて勉強しなおします!
iojglarnivo

2022/11/25 16:20

いらっしゃるかはわかりませんが、同じ悩みを持った方用。 data,ancdata,msg_flags,address=s.recvmsg(1000,200) として、 ICMPv6ヘッダ以降のデータ data 送信元アドレス address[0] 宛先アドレス socket.inet_ntop(socket.AF_INET6,ancdata[0][2][:16]) 以上で得られました。 現状はこれで解決しました。何か間違いや訂正があればどなたかコメントお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問