【Ethernet】車載ネットワーク その38【lwIP疑似受信①】

【Ethernet】車載ネットワーク その38【lwIP疑似受信①】 車載ネットワーク

バックナンバーはこちら。
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の疑似受信

太郎くん
太郎くん

そういえば、今回は「疑似受信」って言い方だね。
いつもだと「シミュレーション」とか言いそうなのに。

フクさん
フクさん

シミュレーションでも良いけど、
まぁ目的はIPフラグメントの解決だけだしねー。
シミュレーションってほどではないだろう。

太郎くん
太郎くん

まぁlwIPを使ってはいるけど、
プロトコルスタックを純粋に再現してるわけでもないから、
確かにそうかも。

lwIPの疑似受信用コード

フクさん
フクさん

というわけで作ったコードはこれだ!

#include <Windows.h>


#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/dns.h"
#include "netif/etharp.h"
#if LWIP_IPV6
#include "lwip/ethip6.h"
#include "lwip/nd6.h"
#endif

#include "lwip/apps/httpd.h"
#include "lwip/apps/snmp.h"
#include "lwip/apps/lwiperf.h"
#include "lwip/apps/mdns.h"
#include "lwip/apps/netbiosns.h"


#include <string.h>
#include <stdio.h>

/* This define enables multi packet processing.
 * For this, the input is interpreted as 2 byte length + data + 2 byte length + data...
 * #define LWIP_FUZZ_MULTI_PACKET
*/
u8_t pktbuf[20000];



/* 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;
}

static void input_pkt(struct netif *netif, const u8_t *data, size_t len)
{
  struct pbuf *p, *q;
  err_t err;

  LWIP_ASSERT("pkt too big", len <= 0xFFFF);
  p = pbuf_alloc(PBUF_RAW, (u16_t)len, PBUF_POOL);
  LWIP_ASSERT("alloc failed", p);
  for(q = p; q != NULL; q = q->next) {
    MEMCPY(q->payload, data, q->len);
    data += q->len;
  }
  err = netif->input(p, netif);
  if (err != ERR_OK) {
    pbuf_free(p);
  }
}

static void input_pkts(struct netif *netif, const u8_t *data, size_t len)
{
  input_pkt(netif, data, len);
}

u32_t sys_now(void)
{
	return GetTickCount();
}

void * sio_open(u8_t devnum)
{
	return NULL;
}

void sio_send(u8_t c, void* fd)
{
}

u32_t sio_tryread(void* fd, u8_t *data, u32_t len)
{
	return 0;
}

#include "lwip/udp.h"
#include "lwip/igmp.h"

struct test_udp_rxdata {
  u32_t rx_cnt;
  u32_t rx_bytes;
  struct udp_pcb *pcb;
};

static struct netif test_netif1;

static void test_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
    const ip_addr_t *addr, u16_t port)
{
  struct test_udp_rxdata *ctr = (struct test_udp_rxdata *)arg;
  int i;
  int cnt = 0;
  BYTE *pbuf;

  LWIP_UNUSED_ARG(addr);
  LWIP_UNUSED_ARG(port);


  ctr->rx_cnt++;
  ctr->rx_bytes += p->tot_len;
  do {
	  pbuf = (BYTE*)p->payload;
	  for( i =0 ; i < p->len; i++ ){
		  printf("%02X ", pbuf[i]);
		  if ( (cnt % 16) == 15) printf("\n");
		  cnt++;
	  }
	  p = p->next;
  }while( p != NULL );
  
  printf("\n\n");
  

  if (p != NULL) {
    pbuf_free(p);
  }
}

BYTE txdata1[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,0xdc,0x20,0x00,0xff,0x11,0x6a,0x0f,0xc0,0xa8,0x0A,0x0B,0xec,0x00,0x01,0x01,0xb0,0x00,0x09,0x79,0x2a,0x6d,0x00,0x00,0x01,…};
BYTE txdata2[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,0xdc,0x20,0xb9,0xff,0x11,0x69,0x56,0xc0,0xa8,0x0A,0x0B,0xec,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,…};
BYTE txdata3[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,…};
BYTE txdata4[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,…};
BYTE txdata5[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,…};
BYTE txdata6[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,…};
BYTE txdata7[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x05,0xdc,0x6a,…};
BYTE txdata8[] = {0x01,0x00,0x5e,0x00,0x01,0x01,0x10,0x6f,0x3f,0x0f,0xd6,0xdd,0x08,0x00,0x45,0x00,0x02,0x09,0x6a,…};


int main(int argc, char** argv)
{
  struct netif net_test;
  ip4_addr_t addr;
  ip4_addr_t netmask;
  ip4_addr_t gw;
  size_t len;

  err_t err;
  struct udp_pcb *pcb1, *pcb2;
  const u16_t port = 2425;
  struct test_udp_rxdata ctr1;
  struct pbuf *p;

  lwip_init();

  IP4_ADDR(&netmask, 0, 0, 0, 0);
  IP4_ADDR(&gw, 192, 168, 10, 1);

  netif_add(&net_test, NULL, NULL, NULL, /*&net_test*/NULL, testif_init, ethernet_input);
 
  IP4_ADDR(&addr, 236, 0, 1, 1);
  igmp_joingroup_netif(&net_test, &addr);

  netif_set_up(&net_test);
  netif_set_link_up(&net_test);

  /* initialize apps */
  pcb1 = udp_new();
  err = udp_bind(pcb1, &test_netif1.ip_addr, port);
  memset(&ctr1, 0, sizeof(ctr1));
  ctr1.pcb = pcb1;

  udp_recv(pcb1, test_recv, &ctr1);

  input_pkts(&net_test, txdata1, sizeof(txdata1));
  input_pkts(&net_test, txdata2, sizeof(txdata2));
  input_pkts(&net_test, txdata3, sizeof(txdata3));
  input_pkts(&net_test, txdata4, sizeof(txdata4));
  input_pkts(&net_test, txdata5, sizeof(txdata5));
  input_pkts(&net_test, txdata6, sizeof(txdata6));
  input_pkts(&net_test, txdata7, sizeof(txdata7));
  input_pkts(&net_test, txdata8, sizeof(txdata8));


  return 0;
}

コード説明

太郎くん
太郎くん

長い!!

フクさん
フクさん

ちなみに、EthernetFrameはBYTE配列でそのまま定義した。
長いんで省略してる。

太郎くん
太郎くん

ポイントだけ説明よろしく!

フクさん
フクさん

まぁポイントはmain関数見てって程度だねー。
main関数の中身は前回までに説明したlwIPのAPIを使ってるだけだ。
あとはinput_pktsって関数にEthernetFrameを渡せば受信したことになる。

太郎くん
太郎くん

まぁあとは実際に動かす感じかなー。

まとめ

フクさん
フクさん

まとめだよ。

  • lwIP疑似受信用のソースコード。
    • 詳細は前回までのlwIPのAPI説明を参照願う。

バックナンバーはこちら。

コメント

タイトルとURLをコピーしました