バックナンバーはこちら。
https://www.simulationroom999.com/blog/In-vehicle-network-backnumber/
はじめに
今回からnpcapで送信の話。
EthernetFrameの送信の話。
サンプルのsendpackについての話。
デバイスリスト関連の修正の話。
などなど。
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
受信の後は?
良し!
これでpcapは完璧。
そんなわけないじゃん。
大量にあるAPIの内、パケットキャプチャをする上で最低限のAPIしかやってないじゃん。
でも、パケットキャプチャできれば上々でしょー!
いやいや。
目的忘れてるよ?
え?
目的?
なんだっけ?
自由にEthernetFrameを送信するんでしょ?
ん?
え?
あー?
あ!そうだ!
キャプチャというかEthernetFrameの受信をしたいんじゃないんだよ!
送信したいんだよ!!!
謀ったな!フクさん!!!
(なぜ太郎くんを騙す必要があるんだ・・・。)
pcapでの送信サンプル
で、送信するにはどうすれば良いの?
これもサンプルがある。
お、じゃーチョロそう!
ちなみにどこに?
前回使ったのがpktdump_exってプロジェクトだったんだけど、
今回使うのはsendpackってプロジェクトになる。
sendpackをスタートアッププロジェクトに切り替える。
後はF5押して実行!
待て。まだだ。
何?サンプルんだからそのまま動くんじゃん?
pktdump_exと違って、sendpackは直接ネットワークインターフェース名を指定するタイプなんだよねー。
使い勝手が少し悪いんで改造する。
コード差分はこんな感じ
修正差分
diff U3B sendpack_old.c sendpack.c
--- sendpack_old.c Mon Dec 7 10:42:02 2020
+++ sendpack.c Fri Dec 4 00:49:12 2020
@@ -26,10 +26,11 @@
int main(int argc, char **argv)
{
+ pcap_if_t *alldevs, *d;
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
u_char packet[100];
- int i;
+ u_int inum, i = 0;
#ifdef _WIN32
/* Load Npcap and its functions. */
@@ -40,6 +41,7 @@
}
#endif
+#if 0
/* Check the validity of the command line */
if (argc != 2)
{
@@ -57,6 +59,83 @@
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by Npcap\n", argv[1]);
return 2;
+ }
+#endif
+ printf("pktdump_ex: prints the packets of the network using Npcap.\n");
+ printf(" Usage: pktdump_ex [-s source]\n\n"
+ " Examples:\n"
+ " pktdump_ex -s file.acp\n"
+ " pktdump_ex -s \\Device\\NPF_{C8736017-F3C3-4373-94AC-9A34B7DAD998}\n\n");
+
+ if (argc < 3)
+ {
+ printf("\nNo adapter selected: printing the device list:\n");
+ /* The user didn't provide a packet source: Retrieve the local device list */
+ if (pcap_findalldevs(&alldevs, errbuf) == -1)
+ {
+ fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
+ exit(1);
+ }
+
+ /* Print the list */
+ for (d = alldevs; d; d = d->next)
+ {
+ printf("%d. %s\n ", ++i, d->name);
+
+ if (d->description)
+ printf(" (%s)\n", d->description);
+ else
+ printf(" (No description available)\n");
+ }
+
+ if (i == 0)
+ {
+ printf("\nNo interfaces found! Make sure Npcap is installed.\n");
+ return -1;
+ }
+
+ printf("Enter the interface number (1-%d):", i);
+ scanf("%d", &inum);
+
+ if (inum < 1 || inum > i)
+ {
+ printf("\nInterface number out of range.\n");
+
+ /* Free the device list */
+ pcap_freealldevs(alldevs);
+ return -1;
+ }
+
+ /* Jump to the selected adapter */
+ for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
+
+ /* Open the adapter */
+ if ((fp = pcap_open_live(d->name, // name of the device
+ 65536, // portion of the packet to capture.
+ // 65536 grants that the whole packet will be captured on all the MACs.
+ 1, // promiscuous mode (nonzero means promiscuous)
+ 1000, // read timeout
+ errbuf // error buffer
+ )) == NULL)
+ {
+ fprintf(stderr, "\nError opening adapter\n");
+ return -1;
+ }
+ }
+ else
+ {
+ /* Do not check for the switch type ('-s') */
+ if ((fp = pcap_open_live(argv[2], // name of the device
+ 65536, // portion of the packet to capture.
+ // 65536 grants that the whole packet will be captured on all the MACs.
+ 1, // promiscuous mode (nonzero means promiscuous)
+ 1000, // read timeout
+ errbuf // error buffer
+ )) == NULL)
+ {
+ fprintf(stderr, "\nError opening adapter\n");
+ return -1;
+ }
}
/* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */
修正内容
随分いろいろ差し込んでるけど
何したの?
前回のpktdump_exで使ってたpcap_findalldevsでデバイスリストを表示して
そこから選択できるようにした。
あー。なるほど。
でも、デバッグ実装する場合そっちの方が使い勝手が良さそうだねー。
まとめ
まとめだよ。
- 今回からnpcapでEthernetFrameの送信。
- サンプルのsendpackを使用。
- デバイスリストから選択できるように一部修正。
バックナンバーはこちら。
コメント