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

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

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

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

解決済

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

iojglarnivo
iojglarnivo

総合スコア1

Python 3.x

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

1回答

0グッド

1クリップ

210閲覧

投稿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)
#なにも出力されない

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

matukeso

2022/11/25 09:27

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

2022/11/25 12:37

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

回答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

総合スコア1427

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

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]) 以上で得られました。 現状はこれで解決しました。何か間違いや訂正があればどなたかコメントお願いします。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

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