Dockerネットワークで遊ぶ_その3_ARP,IP,ICMP編

## はじめに

[前回記事](https://qiita.com/t13801206/items/0858f2af9c57a9db65aa)では、イーサネットフレームの外側を見た
今回は**ARP, IP, ICMP**パケットの中身をみる

### 連載情報

連載|内容
---|---
[その１](https://qiita.com/t13801206/items/0fd95e85377098f996b3)|〈実践〉同じセグメント内のPING疎通確認
[その2](https://qiita.com/t13801206/items/0858f2af9c57a9db65aa)|〈コード〉イーサネットヘッダの中身をみてみる
[その3](https://qiita.com/t13801206/items/81459f9374bffcd293ec)|〈コード〉ARP,IP,ICMPの中身をみてみる
[その4](https://qiita.com/t13801206/items/478493c1527cbcf0511c)|〈実践〉IP,TCPをキャプチャする
[その5](https://qiita.com/t13801206/items/7fa2f7bf75021899e05e)|〈実践）ルーターを準備する
[その6](https://qiita.com/t13801206/items/0aa1d0f2b762d013e9f8)|〈実践〉別セグメントのWEBへアクセスをする

## ARPパケットのフォーマット

[ARPパケットフォーマット](https://beginners-network.com/supplement/arp_packet_format.html)

```c:cat /usr/include/net/if_arp.h
/* ARP protocol opcodes. */
#define ARPOP_REQUEST   1               /* ARP request.  */
#define ARPOP_REPLY     2               /* ARP reply.  */

struct arphdr
  {
    unsigned short int ar_hrd;          /* Format of hardware address.  */
    unsigned short int ar_pro;          /* Format of protocol address.  */
    unsigned char ar_hln;               /* Length of hardware address.  */
    unsigned char ar_pln;               /* Length of protocol address.  */
    unsigned short int ar_op;           /* ARP opcode (command).  */
  };

/* ARP protocol HARDWARE identifiers. */
#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
```

- ハードウェアアドレスは**MACアドレス**
    - 物理アドレスとも言う
- プロトコルアドレスは**IPアドレス**
- `unsigned char`は1byte, `unsigned short int`は2byte

```c:cat /usr/include/netinet/if_ether.h
#include <net/if_arp.h>

struct  ether_arp {
        struct  arphdr ea_hdr;          /* fixed-size header */
        uint8_t arp_sha[ETH_ALEN];      /* sender hardware address */
        uint8_t arp_spa[4];             /* sender protocol address */
        uint8_t arp_tha[ETH_ALEN];      /* target hardware address */
        uint8_t arp_tpa[4];             /* target protocol address */
};
```

- `struct`の中の1行目で`arphdr`（ARPヘッダー）が書かれている
- 続いて送信元と宛先それぞれの**MACアドレス**、プロトコルアドレス（＝**IPアドレス**）が書かれている

## IPパケット

[IPパケット - ネットワーク入門サイト](https://beginners-network.com/packet.html)

`ip`構造体にTTLや送信元・宛先の32bitが書かれている

```c:cat /usr/include/netinet/ip.h
struct ip
  {
    uint8_t ip_tos;                     /* type of service */
    unsigned short ip_len;              /* total length */
    unsigned short ip_id;               /* identification */
    unsigned short ip_off;              /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
    uint8_t ip_ttl;                     /* time to live */
    uint8_t ip_p;                       /* protocol */
    unsigned short ip_sum;              /* checksum */
    struct in_addr ip_src, ip_dst;      /* source and dest address */
  };

#define IPVERSION       4               /* IP version number */
#define IP_MAXPACKET    65535           /* maximum packet size */

/*
 * Internet implementation parameters.
 */
#define MAXTTL          255             /* maximum time to live (seconds) */
#define IPDEFTTL        64              /* default ttl, from RFC 1340 */
```

## ICMPパケット

[ネットワーク入門サイト - ICMP](https://beginners-network.com/icmp.html)

```c:cat /usr/include/netinet/ip_icmp.h
#include <stdint.h>

struct icmphdr
{
  uint8_t type;         /* message type */
  uint8_t code;         /* type sub-code */
  uint16_t checksum;
};

#define ICMP_ECHOREPLY          0       /* Echo Reply                   */
#define ICMP_DEST_UNREACH       3       /* Destination Unreachable      */
#define ICMP_REDIRECT           5       /* Redirect (change route)      */
#define ICMP_ECHO               8       /* Echo Request                 */

```

## 糸冬了！！