はじめに
前回記事では、Dockerの分離されたネットワークにサーバとクライアントをつくった
今回は、クライアント(ubuntu)にインストールしたgcc
が使用するヘッダーファイル(.h
)の中身を見ていく
レイヤ2のイーサネットヘッダに焦点を当てる
連載情報
連載 | 内容 |
---|---|
その1 | 〈実践〉同じセグメント内のPING疎通確認 |
その2 | 〈コード〉イーサネットヘッダの中身をみてみる |
その3 | 〈コード〉ARP,IP,ICMPの中身をみてみる |
その4 | 〈実践〉IP,TCPをキャプチャする |
その5 | 〈実践)ルーターを準備する |
その6 | 〈実践〉別セグメントのWEBへアクセスをする |
イーサネットフレームのフォーマット
イーサネットを流れるデータの呼称は、OSI参照モデルのレイヤ(層)に応じて、フレームだったりパケットだったりと変化する
が、
瑣末なことなので、変化するということだけ覚えておけばよいと思う(自論)
章タイトルにフレームと書いているので、ここではデータリンク層(OSI第2レイヤ)が対象
フレームの中身がどうなっているのかは、下記参照
参考:Ethernet LAN - イーサネットフレームのフォーマットとMACアドレス
現在、最も使用されているイーサネットフレームはDIX仕様です。
DIX仕様
DECの社名が起源に書かれている
DECといえば、戦うプログラマーの主人公(!?)デヴィッド・カトラーが居た会社
MACアドレスを調べる 6byte
ifconfig
です(Windowsではipconfig
)
またはip addr
です
MACアドレスの最初の3byteはベンダー固有値であるが
02:42:ac
で始まるものはヒットしない
MACアドレス検索
その理由は、stack overflowでも明確な答えはなかった
6バイトすべてを0xFFにすると
ブロードキャストアドレスになります
タイプ/長さ 2byte
dockerからクライアントのターミナルに入ってコマンドを打つ
2byteのタイプETHERTYPE_***
一覧が書かれている箇所がある ※一部抜粋
/* Ethernet protocol ID's */
#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
#define ETHERTYPE_IP 0x0800 /* IP */
#define ETHERTYPE_ARP 0x0806 /* Address resolution */
#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */
#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging */
#define ETHERTYPE_IPV6 0x86dd /* IP protocol version 6 */
#define ETHERTYPE_LOOPBACK 0x9000 /* used to test interfaces */
イーサネットヘッダー
同ヘッダーファイルに、イーサネットヘッダーの構造体が定義されている
送信元と宛先のMACアドレスと、タイプ/長さの2byteの3メンバ構造体
/* 10Mb/s ethernet header */
struct ether_header
{
uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
uint8_t ether_shost[ETH_ALEN]; /* source ether addr */
uint16_t ether_type; /* packet type ID field */
} __attribute__ ((__packed__));
attribute, packedについての説明はこちらのブログが参考になる
余談~MTUに関するIPAの出題例
IPAネスペ令和5年午後2問5において
MTUのサイズ(1500byte)からIPヘッダーTCPヘッダーの合計40byteを引いた値が
フラグメントが起きずにデータを遅れる最大量であるという問題が出た
ここでMACヘッダーが14byteであるのは
送信先MACアドレスと送信元のMACアドレスが各6byteで合計12byte
それに加えてタイプ/長さが2byteあるので、合計14byteとなる