低レイヤーネットワークプログラミングに関する雑多な知識
[History] [Last Modified] (2016/05/07 08:54:19)
Recent posts
Qoosky について
プログラミング情報を投稿、有料販売するためのサービスをご利用いただけます。詳細は こちら をご参照ください。
Popular pages

概要

TCP/IP モデルのうちトランスポート層ではなく、インターネット層およびネットワークインターフェイス層のパケット (正確には PDU) を扱う低レイヤープログラミングの雑多なテクニックをまとめます。『ルーター自作でわかるパケットの流れ』などを参考にしています。バックアップ目的で書籍のサンプルコードをホスティングしました。

検証環境

  • CentOS 6.6
  • gcc 4.4.7

定義ファイルまとめ

イーサネットヘッダ

タイプ部

/usr/include/net/ethernet.h

/* Ethernet protocol ID's */
#define ETHERTYPE_PUP       0x0200    /* Xerox PUP */
#define ETHERTYPE_SPRITE    0x0500    /* Sprite */
#define ETHERTYPE_IP        0x0800    /* IP */
#define ETHERTYPE_ARP       0x0806    /* Address resolution */
#define ETHERTYPE_REVARP    0x8035    /* Reverse ARP */
#define ETHERTYPE_AT        0x809B    /* AppleTalk protocol */
#define ETHERTYPE_AARP      0x80F3    /* AppleTalk ARP */
#define ETHERTYPE_VLAN      0x8100    /* IEEE 802.1Q VLAN tagging */
#define ETHERTYPE_IPX       0x8137    /* IPX */
#define ETHERTYPE_IPV6      0x86dd    /* IP protocol version 6 */
#define ETHERTYPE_LOOPBACK  0x9000    /* used to test interfaces */

構造体

/usr/include/net/ethernet.h

struct ether_header
{
  u_int8_t  ether_dhost[ETH_ALEN];   /* destination eth addr */
  u_int8_t  ether_shost[ETH_ALEN];   /* source ether addr */
  u_int16_t ether_type;              /* packet type ID field */
} __attribute__ ((__packed__));

ARP パケット

オペレーション部

/usr/include/net/if_arp.h

/* ARP protocol opcodes. */
#define ARPOP_REQUEST    1    /* ARP request. */
#define ARPOP_REPLY      2    /* ARP reply. */
#define ARPOP_RREQUEST   3    /* RARP request. */
#define ARPOP_RREPLY     4    /* RARP reply. */
#define ARPOP_InREQUEST  8    /* InARP request. */
#define ARPOP_InREPLY    9    /* InARP reply. */
#define ARPOP_NAK        10   /* (ATM)ARP NAK. */

ハードウェアタイプ部

本 ARP パケットが下位層でどのようにカプセル化されるのか。イーサネットであれば ARPHRD_ETHER となります。ちなみに、ARP パケットのプロトコルタイプ部には、本 ARP パケットがカプセル化している上位層のプロトコルの識別子が記載されます。先程紹介した /usr/include/net/ethernet.h の ETHERTYPE_IP などが該当します。

/usr/include/net/if_arp.h

/* ARP protocol HARDWARE identifiers. */
#define ARPHRD_NETROM     0      /* From KA9Q: NET/ROM pseudo. */
#define ARPHRD_ETHER      1      /* Ethernet 10/100Mbps. */
#define ARPHRD_EETHER     2      /* Experimental Ethernet. */
#define ARPHRD_AX25       3      /* AX.25 Level 2. */
#define ARPHRD_PRONET     4      /* PROnet token ring. */
#define ARPHRD_CHAOS      5      /* Chaosnet. */
#define ARPHRD_IEEE802    6      /* IEEE 802.2 Ethernet/TR/TB. */
#define ARPHRD_ARCNET     7      /* ARCnet. */
#define ARPHRD_APPLETLK   8      /* APPLEtalk. */
#define ARPHRD_DLCI       15     /* Frame Relay DLCI. */
#define ARPHRD_ATM        19     /* ATM. */
#define ARPHRD_METRICOM   23     /* Metricom STRIP (new IANA id). */
#define ARPHRD_IEEE1394   24     /* IEEE 1394 IPv4 - RFC 2734. */
#define ARPHRD_EUI64      27     /* EUI-64. */
#define ARPHRD_INFINIBAND 32     /* InfiniBand. */

構造体

上位層および下位層のプロトコル次第で ARP パケット全体のサイズが変化するため、不変部分と可変部分に分けて定義されています。#if 0 の部分はスキップされるため定義されていないことに注意してください。

/usr/include/net/if_arp.h

/* See RFC 826 for protocol description.  ARP packets are variable
   in size; the arphdr structure defines the fixed-length portion.
   Protocol type values are the same as those for 10 Mb/s Ethernet.
   It is followed by the variable-sized fields ar_sha, arp_spa,
   arp_tha and arp_tpa in that order, according to the lengths
   specified.  Field names used correspond to RFC 826. */

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). */
#if 0
  /* Ethernet looks like this : This bit is variable sized
     however... */
  unsigned char __ar_sha[ETH_ALEN]; /* Sender hardware address. */
  unsigned char __ar_sip[4];        /* Sender IP address. */
  unsigned char __ar_tha[ETH_ALEN]; /* Target hardware address. */
  unsigned char __ar_tip[4];        /* Target IP address. */
#endif
};

/usr/include/netinet/if_ether.h

/*
 * Ethernet Address Resolution Protocol.
 *
 * See RFC 826 for protocol description.  Structure below is adapted
 * to resolving internet addresses.  Field names used correspond to
 * RFC 826.
 */
struct ether_arp {
    struct   arphdr ea_hdr;     /* fixed-size header */
    u_int8_t arp_sha[ETH_ALEN]; /* sender hardware address */
    u_int8_t arp_spa[4];        /* sender protocol address */
    u_int8_t arp_tha[ETH_ALEN]; /* target hardware address */
    u_int8_t arp_tpa[4];        /* target protocol address */
};
#define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln
#define arp_pln ea_hdr.ar_pln
#define arp_op  ea_hdr.ar_op

IP ヘッダ

DSCP および ECN 部

/usr/include/netinet/ip.h

/*
 * Definitions for Explicit Congestion Notification (ECN)
 *
 * Taken from RFC-3168, Section 5.
 */
#define IPTOS_ECN_MASK      0x03
#define IPTOS_ECN(x)        ((x) & IPTOS_ECN_MASK)
#define IPTOS_ECN_NOT_ECT   0x00
#define IPTOS_ECN_ECT1      0x01
#define IPTOS_ECN_ECT0      0x02
#define IPTOS_ECN_CE        0x03

/*
 * Definitions for IP differentiated services code points (DSCP)
 *
 * Taken from RFC-2597, Section 6 and RFC-2598, Section 2.3.
 */
#define IPTOS_DSCP_MASK     0xfc
#define IPTOS_DSCP(x)       ((x) & IPTOS_DSCP_MASK)
#define IPTOS_DSCP_AF11     0x28
#define IPTOS_DSCP_AF12     0x30
#define IPTOS_DSCP_AF13     0x38
#define IPTOS_DSCP_AF21     0x48
#define IPTOS_DSCP_AF22     0x50
#define IPTOS_DSCP_AF23     0x58
#define IPTOS_DSCP_AF31     0x68
#define IPTOS_DSCP_AF32     0x70
#define IPTOS_DSCP_AF33     0x78
#define IPTOS_DSCP_AF41     0x88
#define IPTOS_DSCP_AF42     0x90
#define IPTOS_DSCP_AF43     0x98
#define IPTOS_DSCP_EF       0xb8

これは同ファイルで定義されているサービス種別部に代わるものです。

/*
 * Definitions for IP type of service (ip_tos) [deprecated; use DSCP
 * and CS definitions above instead.]
 */
#define IPTOS_TOS_MASK      0x1E
#define IPTOS_TOS(tos)      ((tos) & IPTOS_TOS_MASK)
#define IPTOS_LOWDELAY      0x10
#define IPTOS_THROUGHPUT    0x08
#define IPTOS_RELIABILITY   0x04
#define IPTOS_LOWCOST       0x02
#define IPTOS_MINCOST       IPTOS_LOWCOST

パケット分割の制御フラグ

/usr/include/netinet/ip.h

#define IP_RF 0x8000  /* reserved fragment flag */
#define IP_DF 0x4000  /* dont fragment flag */
#define IP_MF 0x2000  /* more fragments flag */

フラグメンテーションが発生したときのマスク

/usr/include/netinet/ip.h

#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */

TTL 関連

/usr/include/netinet/ip.h

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

IP ヘッダとは直接関係ありませんが /usr/include/netinet/ip.h には MSS の最大値も定義されています。

#define IP_MSS      576    /* default maximum segment size */

上位層のプロトコル

/usr/include/netinet/in.h
(ip.h ではなく in.h であることに注意)

enum
{
  IPPROTO_IP = 0,        /* Dummy protocol for TCP. */
  IPPROTO_HOPOPTS = 0,   /* IPv6 Hop-by-Hop options. */
  IPPROTO_ICMP = 1,      /* Internet Control Message Protocol. */
  IPPROTO_IGMP = 2,      /* Internet Group Management Protocol. */
  IPPROTO_IPIP = 4,      /* IPIP tunnels (older KA9Q tunnels use 94). */
  IPPROTO_TCP = 6,       /* Transmission Control Protocol. */
  IPPROTO_EGP = 8,       /* Exterior Gateway Protocol. */
  IPPROTO_PUP = 12,      /* PUP protocol. */
  IPPROTO_UDP = 17,      /* User Datagram Protocol. */
  IPPROTO_IDP = 22,      /* XNS IDP protocol. */
  IPPROTO_TP = 29,       /* SO Transport Protocol Class 4. */
  IPPROTO_DCCP = 33,     /* Datagram Congestion Control Protocol. */
  IPPROTO_IPV6 = 41,     /* IPv6 header. */
  IPPROTO_ROUTING = 43,  /* IPv6 routing header. */
  IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */
  IPPROTO_RSVP = 46,     /* Reservation Protocol. */
  IPPROTO_GRE = 47,      /* General Routing Encapsulation. */
  IPPROTO_ESP = 50,      /* encapsulating security payload. */
  IPPROTO_AH = 51,       /* authentication header. */
  IPPROTO_ICMPV6 = 58,   /* ICMPv6. */
  IPPROTO_NONE = 59,     /* IPv6 no next header. */
  IPPROTO_DSTOPTS = 60,  /* IPv6 destination options. */
  IPPROTO_MTP = 92,      /* Multicast Transport Protocol. */
  IPPROTO_ENCAP = 98,    /* Encapsulation Header. */
  IPPROTO_PIM = 103,     /* Protocol Independent Multicast. */
  IPPROTO_COMP = 108,    /* Compression Header Protocol. */
  IPPROTO_SCTP = 132,    /* Stream Control Transmission Protocol. */
  IPPROTO_UDPLITE = 136, /* UDP-Lite protocol. */
  IPPROTO_RAW = 255,     /* Raw IP packets. */
  IPPROTO_MAX
};

構造体

/usr/include/netinet/ip.h

struct iphdr
{
#if __BYTE_ORDER == _LITTLE_ENDIAN
  unsigned int ihl:4;
  unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
  unsigned int version:4;
  unsigned int ihl:4;
#else
# error    "Please fix <bits/endian.h>"
#endif
  u_int8_t tos;
  u_int16_t tot_len;
  u_int16_t id;
  u_int16_t frag_off;
  u_int8_t ttl;
  u_int8_t protocol;
  u_int16_t check;
  u_int32_t saddr;
  u_int32_t daddr;
  /*The options start here. */
};

ICMP

大まかな通知の種類

/usr/include/netinet/ip_icmp.h

#define ICMP_ECHOREPLY       0    /* Echo Reply */
#define ICMP_DEST_UNREACH    3    /* Destination Unreachable */
#define ICMP_SOURCE_QUENCH   4    /* Source Quench */
#define ICMP_REDIRECT        5    /* Redirect (change route) */
#define ICMP_ECHO            8    /* Echo Request */
#define ICMP_TIME_EXCEEDED   11   /* Time Exceeded */
#define ICMP_PARAMETERPROB   12   /* Parameter Problem */
#define ICMP_TIMESTAMP       13   /* Timestamp Request */
#define ICMP_TIMESTAMPREPLY  14   /* Timestamp Reply */
#define ICMP_INFO_REQUEST    15   /* Information Request */
#define ICMP_INFO_REPLY      16   /* Information Reply */
#define ICMP_ADDRESS         17   /* Address Mask Request */
#define ICMP_ADDRESSREPLY    18   /* Address Mask Reply */
#define NR_ICMP_TYPES        18

詳細な通知種別コード

/usr/include/netinet/ip_icmp.h

/* Codes for UNREACH. */
#define ICMP_NET_UNREACH    0    /* Network Unreachable */
#define ICMP_HOST_UNREACH   1    /* Host Unreachable */
#define ICMP_PROT_UNREACH   2    /* Protocol Unreachable */
#define ICMP_PORT_UNREACH   3    /* Port Unreachable */
#define ICMP_FRAG_NEEDED    4    /* Fragmentation Needed/DF set */
#define ICMP_SR_FAILED      5    /* Source Route failed */
#define ICMP_NET_UNKNOWN    6
#define ICMP_HOST_UNKNOWN   7
#define ICMP_HOST_ISOLATED  8
#define ICMP_NET_ANO        9
#define ICMP_HOST_ANO       10
#define ICMP_NET_UNR_TOS    11
#define ICMP_HOST_UNR_TOS   12
#define ICMP_PKT_FILTERED   13   /* Packet filtered */
#define ICMP_PREC_VIOLATION 14   /* Precedence violation */
#define ICMP_PREC_CUTOFF    15   /* Precedence cut off */
#define NR_ICMP_UNREACH     15   /* instead of hardcoding immediate value */

/* Codes for REDIRECT. */
#define ICMP_REDIR_NET      0    /* Redirect Net */
#define ICMP_REDIR_HOST     1    /* Redirect Host */
#define ICMP_REDIR_NETTOS   2    /* Redirect Net for TOS */
#define ICMP_REDIR_HOSTTOS  3    /* Redirect Host for TOS */

/* Codes for TIME_EXCEEDED. */
#define ICMP_EXC_TTL        0    /* TTL count exceeded */
#define ICMP_EXC_FRAGTIME   1    /* Fragment Reass time exceeded */

構造体

/usr/include/netinet/ip_icmp.h

struct icmphdr
{
  u_int8_t type;        /* message type */
  u_int8_t code;        /* type sub-code */
  u_int16_t checksum;
  ...
};

または

struct icmp
{
  u_int8_t  icmp_type;  /* type of message, see below */
  u_int8_t  icmp_code;  /* type sub code */
  u_int16_t icmp_cksum; /* ones complement checksum of struct */
  ...
};

雑多な知識

サンプルコードを理解するための雑学です。

main 関数の引数 envp には環境変数がセットされる

#include <stdio.h>
int main(int argc, char *argv[], char *envp[]) {
    int i;
    for(i = 0; envp[i] != NULL; ++i) {
        printf("%d: [%s]\n", i, envp[i]);
    }
    return(0);
}

などとすると以下のように出力されます。

0: [HOSTNAME=vagrant]
1: [TERM=xterm]
2: [SHELL=/bin/bash]
3: [HISTSIZE=1000]
4: [SSH_CLIENT=10.0.2.2 8153 22]
5: [SSH_TTY=/dev/pts/0]
6: [S_TIME_DEF_TIME=UTC]
7: [USER=vagrant]
...

インクルードパス

標準インクルードパスには /usr/include が含まれています。そのため

/usr/include/net/ethernet.h

は以下のようにして読み込めます。

#include <net/ethernet.h>

ifreq の定義

#include <linux/if.h> とすると以下の内容が定義されます。

/*
 * Interface request structure used for socket
 * ioctl's.  All interface ioctl's must have parameter
 * definitions which begin with ifr_name.  The
 * remainder may be interface specific.
 */

struct ifreq 
{
#define IFHWADDRLEN     6
    union
    {
        char    ifrn_name[IFNAMSIZ];   /* if name, e.g. "en0" */
    } ifr_ifrn;

    union {
        struct  sockaddr ifru_addr;
        struct  sockaddr ifru_dstaddr;
        struct  sockaddr ifru_broadaddr;
        struct  sockaddr ifru_netmask;
        struct  sockaddr ifru_hwaddr;
        short   ifru_flags;
        int     ifru_ivalue;
        int     ifru_mtu;
        struct  ifmap ifru_map;
        char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
        char    ifru_newname[IFNAMSIZ];
        void *  ifru_data;
        struct  if_settings ifru_settings;
    } ifr_ifru;
};

#define ifr_name        ifr_ifrn.ifrn_name      /* interface name       */
#define ifr_hwaddr      ifr_ifru.ifru_hwaddr    /* MAC address          */
#define ifr_addr        ifr_ifru.ifru_addr      /* address              */
#define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-p lnk */
#define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address    */
#define ifr_netmask     ifr_ifru.ifru_netmask   /* interface net mask   */
#define ifr_flags       ifr_ifru.ifru_flags     /* flags                */
#define ifr_metric      ifr_ifru.ifru_ivalue    /* metric               */
#define ifr_mtu         ifr_ifru.ifru_mtu       /* mtu                  */
#define ifr_map         ifr_ifru.ifru_map       /* device map           */
#define ifr_slave       ifr_ifru.ifru_slave     /* slave device         */
#define ifr_data        ifr_ifru.ifru_data      /* for use by interface */
#define ifr_ifindex     ifr_ifru.ifru_ivalue    /* interface index      */
#define ifr_bandwidth   ifr_ifru.ifru_ivalue    /* link bandwidth       */
#define ifr_qlen        ifr_ifru.ifru_ivalue    /* Queue length         */
#define ifr_newname     ifr_ifru.ifru_newname   /* New name             */
#define ifr_settings    ifr_ifru.ifru_settings  /* Device/proto settings*/

sockaddr の定義

#include <netpacket/packet.h> とすると以下の内容が定義されます。

struct sockaddr_ll
{
  unsigned short int sll_family;
  unsigned short int sll_protocol;
  int sll_ifindex;
  unsigned short int sll_hatype;
  unsigned char sll_pkttype;
  unsigned char sll_halen;
  unsigned char sll_addr[8];
};

socket 関数の引数

#include <sys/socket.h> とすると #include <bits/socket.h> が間接的に実行されて以下の内容が定義されます。

/* Protocol families. */
#define PF_INET    2     /* IP protocol family. */
#define PF_INET6   10    /* IP version 6. */
#define PF_PACKET  17    /* Packet family. */

/* Types of sockets. */
SOCK_STREAM = 1,         /* Sequenced, reliable, connection-based
                            byte streams. */
SOCK_DGRAM = 2,          /* Connectionless, unreliable datagrams
                            of fixed maximum length. */
SOCK_RAW = 3,            /* Raw protocol interface. */

#include <net/ethernet.h> とすると #include <linux/if_ether.h> が間接的に実行されて以下の内容が定義されます。

#define ETH_P_IP        0x0800          /* Internet Protocol packet     */
#define ETH_P_ALL       0x0003          /* Every packet (be careful!!!) */

#include <sys/ioctl.h> とすると #include <bits/ioctls.h> が間接的に実行されて以下の内容が定義されます。

/* Socket configuration controls. */
#define SIOCGIFFLAGS    0x8913          /* get flags                    */
#define SIOCSIFFLAGS    0x8914          /* set flags                    */

htons および ntohs について

多バイトデータをやりとりする際にはバイトオーダが問題になります。例えばビッグエンディアンのマシンとリトルエンディアンのマシンはそのまま多バイトデータを扱う通信ができません。そこでネットワーク通信のパケットに含めるデータはすべてビッグエンディアンに変換して送信するという決まりがあります。この場合のビッグエンディアンを特にネットワークバイトオーダとよびます。変換前のマシンのエンディアンをホストバイトオーダとよびます。#include <arpa/inet.h> には以下の変換用関数が定義されています。

ホストバイトオーダ → ネットワークバイトオーダ

  • htonl(): Long (4バイト)
  • htons(): Short (2バイト)

ネットワークバイトオーダ → ホストバイトオーダ

  • ntohl(): Long (4バイト)
  • ntohs(): Short (2バイト)

例えば ETH_P_IPETH_P_ALL は 2 バイトなので htons および ntohs を使用します。

ioctl について

#include <sys/ioctl.h> とすると間接的に #include <bits/ioctls.h> が実行されて以下の内容が定義されます。

/* Socket configuration controls. */
#define SIOCGIFNAME     0x8910          /* get iface name               */
#define SIOCSIFLINK     0x8911          /* set iface channel            */
#define SIOCGIFCONF     0x8912          /* get iface list               */
#define SIOCGIFFLAGS    0x8913          /* get flags                    */
#define SIOCSIFFLAGS    0x8914          /* set flags                    */
#define SIOCGIFADDR     0x8915          /* get PA address               */
#define SIOCSIFADDR     0x8916          /* set PA address               */
#define SIOCGIFDSTADDR  0x8917          /* get remote PA address        */
#define SIOCSIFDSTADDR  0x8918          /* set remote PA address        */
#define SIOCGIFBRDADDR  0x8919          /* get broadcast PA address     */
#define SIOCSIFBRDADDR  0x891a          /* set broadcast PA address     */
#define SIOCGIFNETMASK  0x891b          /* get network PA mask          */
#define SIOCSIFNETMASK  0x891c          /* set network PA mask          */
#define SIOCGIFMETRIC   0x891d          /* get metric                   */
#define SIOCSIFMETRIC   0x891e          /* set metric                   */
#define SIOCGIFMEM      0x891f          /* get memory address (BSD)     */
#define SIOCSIFMEM      0x8920          /* set memory address (BSD)     */
#define SIOCGIFMTU      0x8921          /* get MTU size                 */
#define SIOCSIFMTU      0x8922          /* set MTU size                 */
#define SIOCSIFNAME     0x8923          /* set interface name           */
#define SIOCSIFHWADDR   0x8924          /* set hardware address         */
#define SIOCGIFENCAP    0x8925          /* get/set encapsulations       */
#define SIOCSIFENCAP    0x8926
#define SIOCGIFHWADDR   0x8927          /* Get hardware address         */
#define SIOCGIFSLAVE    0x8929          /* Driver slaving support       */
#define SIOCSIFSLAVE    0x8930
#define SIOCADDMULTI    0x8931          /* Multicast address lists      */
#define SIOCDELMULTI    0x8932
#define SIOCGIFINDEX    0x8933          /* name -> if_index mapping     */
#define SIOGIFINDEX     SIOCGIFINDEX    /* misprint compatibility :-)   */
#define SIOCSIFPFLAGS   0x8934          /* set/get extended flags set   */
#define SIOCGIFPFLAGS   0x8935
#define SIOCDIFADDR     0x8936          /* delete PA address            */
#define SIOCSIFHWBROADCAST      0x8937  /* set hardware broadcast addr  */
#define SIOCGIFCOUNT    0x8938          /* get number of devices */

これらは #include <sys/ioctl.h> で定義されるデバイスを操作する関数 ioctl の第二引数として使用されます。

  • Socket I/O Configuration Get: SIOCG
  • Socket I/O Configuration Set: SIOCS

という意味があります。デバイスの情報を取得する場合は Get で設定する場合は Set を使用します。例えば

int soc;
soc = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

で取得した soc および

struct ifreq ifreq;

として定義した結果格納用の変数を用いて ioctl は以下のように使用します。

ioctl(soc, SIOCGIFINDEX, &ifreq)

bind について

#include <sys/socket.h> で定義される bind 関数はソケットにデバイスを割り当てるために使用します。ちなみに TCP および UDP のソケットに対して bind を使用すると IP やポートを割り当てることができます。

int soc;
soc = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

struct sockaddr_ll sa;
sa.sll_family = PF_PACKET; // プロトコルファミリー
sa.sll_protocol = htons(ETH_P_ALL); // プロトコル
sa.sll_ifindex = ifreq.ifr_ifindex; // インターフェースのインデックス

bind(soc, (struct sockaddr *)&sa, sizeof(sa))

インターフェースフラグの変更

#include <linux/if.h> で以下の内容が定義されます。

/* Standard interface flags (netdevice->flags). */
#define IFF_UP          0x1             /* interface is up              */
#define IFF_BROADCAST   0x2             /* broadcast address valid      */
#define IFF_DEBUG       0x4             /* turn on debugging            */
#define IFF_LOOPBACK    0x8             /* is a loopback net            */
#define IFF_POINTOPOINT 0x10            /* interface is has p-p link    */
#define IFF_NOTRAILERS  0x20            /* avoid use of trailers        */
#define IFF_RUNNING     0x40            /* interface RFC2863 OPER_UP    */
#define IFF_NOARP       0x80            /* no ARP protocol              */
#define IFF_PROMISC     0x100           /* receive all packets          */
#define IFF_ALLMULTI    0x200           /* receive all multicast packets*/

ioctl を利用してビットフラグを操作するために利用します。

ioctl(soc, SIOCGIFFLAGS, &ifreq);
ifreq.ifr_flags = ifreq.ifr_flags|IFF_PROMISC;
ioctl(soc, SIOCSIFFLAGS, &ifreq);
Related pages
    概要 TCP/IP ソケットプログラミングについて、C 言語を用いた TCP クライアントの基本的なサンプルコードを記載します。 サンプルコード #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> // ソケット API を利用するため。 #include <unistd.h> //
    概要 よく使う python ライブラリのサンプルコード集です。 JSON #!/usr/bin/python # -*- coding: utf-8 -*- import json arr = [1, 2, {'xxx': 3}] # オブジェクト ←→ JSON 文字列 jsonStr = json.dumps(arr) arr2 = json.loads(jsonStr) # オ