スポンサーリンク

このドキュメントの内容は、以下の通りです。

はじめに

インターネットでは、 TCP/IP というプロトコルが使われています。インターネットにおいて通信プログラムを書く場合、ソケット(socket)を利用してプログラミングします。

LinuxやFreeBSDなどのUNIXC言語でのsocketプログラミングでよく使う構造体struct sockaddr_inの アドレスを格納するin_addrとは何かについて説明します。

対象は、もともとはIPv4でしたが、IPv6時代が到来したため、IPv6についても記載致します。

struct sockaddr_inの定義について

まずは、ソケットプログラミングでよく使われる構造体の1つの struct sockaddr_inの定義です。
FreeBSD の場合は、 struct sockaddr_in は、 /usr/include/netinet/in.hに定義されています。
struct sockaddr_in {
	uint8_t sin_len;
	sa_family_t     sin_family;
	in_port_t       sin_port;
	struct  in_addr sin_addr;
	char    sin_zero[8];
};

Linux (Ubuntu) の場合も /usr/include/netinet/in.h に struct sockaddr_in が定義されています。
/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
			   __SOCKADDR_COMMON_SIZE -
			   sizeof (in_port_t) -
			   sizeof (struct in_addr)];
  };

__SOCKADDR_COMMON は、 /usr/include/x86_64-linux-gnu/bits/sockaddr.h に define (定義) されています。

struct in_addrの定義について

アドレスを格納するのは、メンバ変数の struct in_addrのsin_addrです。 struct in_addrについて調べます。

struct sin_addr は、 /usr/include/netinet/in.hで定義されています。
struct in_addr {
	in_addr_t s_addr;
};

in_addr構造体は、in_addr_tのs_addrしかメンバに持たない構造体です。

Linux の場合も定義は同じです。
/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };

in_addr_tの定義について

in_addr_tの型を調べます。 in_addr_t は、 /usr/include/netinet/in.hに定義されています。

in_addr_tは、32bitの整数のIPアドレスを格納するだけなので、ただのuint32_tです。
typedef uint32_t                in_addr_t;

すなおに in_addr_t をメンバにしてくれれば、調べるのが簡単です。 汎用性のためにそうもいかないのでしょう。

uint32_t の範囲は、 0 から4294967295 (2^32 - 1) になります。
桁数が多いので、分かりにくいかもしれませんが、4,294,967,295は、だいたい43億です。つまり、IPv4のIPアドレスの総数は、約43億アドレスということになります。

in_port_tの定義について

in_port_tはuint16_tです。
typedef uint16_t                in_port_t;

uint16_tの型の値の取りうる範囲は、0 から 65535 ( 2^16 - 1 ) の範囲です。
TCPポートの範囲は、1から65535です。

IPv6アドレスの場合


IPv6 アドレスの場合は、 struct sockaddr_in6 の構造体が利用されます。 Linux では netinet/in.h に以下の定義があります。
#if !__USE_KERNEL_IPV6_DEFS
/* Ditto, for IPv6.  */
struct sockaddr_in6
  {
    __SOCKADDR_COMMON (sin6_);
    in_port_t sin6_port;	/* Transport layer port # */
    uint32_t sin6_flowinfo;	/* IPv6 flow information */
    struct in6_addr sin6_addr;	/* IPv6 address */
    uint32_t sin6_scope_id;	/* IPv6 scope-id */
  };
#endif /* !__USE_KERNEL_IPV6_DEFS */

IPv6アドレスは struct in6_addr に保持されます。 IPv6 アドレスは、128ビットです。 struct in6_addr は、メンバ union です。 unionは、共用体です。共用体は、1亭の範囲のメモリを複数の異なる型で共有します。uint32_t が配列で4つ確保されています。uint32_tが4個ということは、つまり1つが32ビットなので、4つで128ビットということになります。

/* IPv6 address */
struct in6_addr
  {
    union
      {
	uint8_t	__u6_addr8[16];
	uint16_t __u6_addr16[8];
	uint32_t __u6_addr32[4];
      } __in6_u;

関連

[2008-07-01-1] socketプログラミング struct sockaddr_inのin_addrとは?
[2008-06-16-2] Socketプログラミング gethostbyname()
[2008-06-16-1] Socketプログラミング inet_pton

ソケットプログラミングの書籍を探す



参照しているページ (サイト内): [2008-08-21-1]

スポンサーリンク
スポンサーリンク
 
いつもシェア、ありがとうございます!


もっと情報を探しませんか?

関連記事

最近の記事

人気のページ

スポンサーリンク
 

過去ログ

2020 : 01 02 03 04 05 06 07 08 09 10 11 12
2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12

サイト

Vim入門

C言語入門

C++入門

JavaScript/Node.js入門

Python入門

FreeBSD入門

Ubuntu入門

セキュリティ入門

パソコン自作入門

ブログ

トップ


プライバシーポリシー