バックナンバーはこちら。
https://www.simulationroom999.com/blog/In-vehicle-network-backnumber/
はじめに
ネットワークシミュレーションに向けてlwIPの送信、受信のインターフェースの特定をする。
登場人物
博識フクロウのフクさん
イラスト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
lwIPのインターフェース
まず、lwIPの下にnpcapを差し込もうと思ったら・・・。
うんうん。
送信、受信のインターフェースを特定する必要がある!!
正解!!
受信の方はethernet_input関数で良かったはず。
うん。
lwIP疑似受信でやったね。
lwIPの送信用インターフェース
うーん、
そういえば、疑似受信はその名のとおり受信できれば良かったから、
送信側のインターフェースって特に気にしなかったなぁ。
そうだね。
送信側は何もしらべてないかなー。
・・・
・・・
(太郎くん!ここが粘り所だよ!)
よし、過去の記事を漁りつつソースコードを追う!!
おー!!
lwIPの送信用インターフェース特定とその経緯
~1時間後~
って、過去の記事を見てたら、なんかそれっぽいのを見つけた。
ここで、lwip_tx_funcって関数が定義されてるんだけど、
この関数って、netif_add関数の引数に渡すtestif_init関数内で
netifのlinkoutputってメンバ変数に登録されてるんだよね。
/* no-op send function */
static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
{
BYTE *pbuf;
int i;
int cnt = 0;
LWIP_UNUSED_ARG(netif);
LWIP_UNUSED_ARG(p);
return ERR_OK;
}
static err_t testif_init(struct netif *netif)
{
netif->name[0] = 't';
netif->name[1] = 's';
netif->output = etharp_output;
netif->linkoutput = lwip_tx_func;
netif->mtu = 1500;
netif->hwaddr_len = 6;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
netif->hwaddr[0] = 0x00;
netif->hwaddr[1] = 0x23;
netif->hwaddr[2] = 0xC1;
netif->hwaddr[3] = 0xDE;
netif->hwaddr[4] = 0xD0;
netif->hwaddr[5] = 0x0D;
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
netif->ip6_autoconfig_enabled = 1;
netif_create_ip6_linklocal_address(netif, 1);
netif->flags |= NETIF_FLAG_MLD6;
#endif
return ERR_OK;
}
良く見つけたね。
私もあんまりここら辺は記憶に残ってないよ。
で、linkoutputが何者か調べるため、
\include\lwip\netif.h
をみたところ、以下のコメントがあった。
This function is called by ethernet_output() when it wants to send a packet on the interface. This function outputs the pbuf as-is on the link medium.
ふむふむ。
要約すると、
- パケットを送信するときにethernet_output()によって呼び出される。
- pbufが出力用バッファとして渡される。
確かにこれが送信用インターフェースっぽいね。
そして、linkoutputは以下の関数ポインタの型になってた。
typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p);
ここでポイントになるのが、
struct pbuf *p
(ほう。なかなか鋭い)
これって、受信の時にも使った連結リスト型のバッファだね。
大正解!!
連結リストの話はここで出て来たね。
しかし、そうなると、
送信側の処理をちょっと考える必要があるのかなー。
そこらへんは次回、考えてみよう。
まとめ
まとめだよ。
- lwIPの受信インターフェースは以前やった。
- 送信インターフェースはやってなかった。
- netifのlinkoutputってメンバ変数に登録するコールバック関数が送信インターフェース。
- ただし、連結リストのバッファを渡す必要がある。
バックナンバーはこちら。
コメント