ブロードキャストは IPv6 ではサポートされません。ブロードキャストがサポートされるのは IPv4 のみです。
データグラムソケットにより送信されたメッセージは、接続されているネットワークのすべてのホストに届くようにブロードキャストを行うことができます。システムはブロードキャストのシミュレーションをソフトウェアで行わないため、ネットワークがブロードキャストをサポートする必要があります。ブロードキャストメッセージを使用すると、ネットワーク上のすべてのホストがブロードキャストメッセージをサービスする必要があるので、ブロードキャストメッセージはネットワークに大きな負荷をかける可能性があります。ブロードキャストは主に次の 2 つの目的に使用されます。
アドレスが不明なローカルネットワーク上の資源の検索
アクセス可能なすべての隣接ホストに情報を送信する必要がある機能
ブロードキャストメッセージを送信するには、次のようにインターネットデータグラムソケットを作成します。
s = socket(AF_INET, SOCK_DGRAM, 0);
次に、ポート番号をソケットにバインドします。
sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(MYPORT); bind(s, (struct sockaddr *) &sin, sizeof sin);
ネットワークのブロードキャストアドレスに送信することにより、データグラムは 1 つのネットワーク上のみでブロードキャストを行うことができます。また、netinet/in.h 内で定義されている特別なアドレス INADDR_BROADCAST に送信することにより、接続されているすべてのネットワークに対して、データグラムのブロードキャストを行うことができます。
システムは、システム上のネットワークインタフェースについての情報の数を判断するメカニズムを提供します。この情報には、IP アドレスおよびブロードキャストアドレスが含まれます。SIOCGIFCONF ioctl(2) 呼び出しはホストのインタフェース構成を単一の ifconf 構造体で返します。この構造体には ifreq 構造体の配列が含まれます。ifreq 構造体は、ホストに接続されているすべてのネットワークインタフェースがサポートするアドレスファミリごとに 1 つずつ存在します。
次の例では、net/if.h で定義されている ifreq 構造体を示します。
struct ifreq { #define IFNAMSIZ 16 char ifr_name[IFNAMSIZ]; /* たとえば名前が 「en0」 */ union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; char ifru_oname[IFNAMSIZ]; /* 名前の場合、その他 */ struct sockaddr ifru_broadaddr; short ifru_flags; int ifru_metric; char ifru_data[1]; /* インタフェース依存データ */ char ifru_enaddr[6]; } ifr_ifru; #define ifr_addr ifr_ifru.ifru_addr #define ifr_dstaddr ifr_ifru.ifru_dstaddr #define ifr_oname ifr_ifru.ifru_oname #define ifr_broadaddr ifr_ifru.ifru_broadaddr #define ifr_flags ifr_ifru.ifru_flags #define ifr_metric ifr_ifru.ifru_metric #define ifr_data ifr_ifru.ifru_data #define ifr_enaddr ifr_ifru.ifru_enaddr };
インタフェース構成を取得する呼び出しは以下の通りです。
/* * インタフェースの数を検索するため SIOCGIFNUM ioctl を実行。 * * 検索されたインタフェースの数に相当する空間を割り当て。 * * 割り当てられたバッファーに対し SIOCGIFCONF を実行。 * */ if (ioctl(s, SIOCGIFNUM, (char *)&numifs) == -1) { numifs = MAXIFS; } bufsize = numifs * sizeof(struct ifreq); reqbuf = (struct ifreq *)malloc(bufsize); if (reqbuf == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } ifc.ifc_buf = (caddr_t)&reqbuf[0]; ifc.ifc_len = bufsize; if (ioctl(s, SIOCGIFCONF, (char *)&ifc) == -1) { perror("ioctl(SIOCGIFCONF)"); exit(1); } ... }
この呼び出しの後、buf には ifreq 構造体の配列が含まれます。ifreq 構造体は、ホストに接続されているすべてのネットワークごとに 1 つずつ存在します。これらの構造体のソート順は次のとおりです。
インタフェース名のアルファベット順
サポートされるアドレスファミリの番号順
ifc.ifc_len の値は ifreq 構造体が使用したバイト数に設定されます。
各構造体は、対応するネットワークが稼働または停止しているか、ポイントツーポイントまたはブロードキャストのどちらであるか、などを示すインタフェースフラグセットを持ちます。次の例では、ifreq 構造体が指定するインタフェース用の SIOCGIFFLAGS フラグを返す ioctl(2) を示します。
struct ifreq *ifr; ifr = ifc.ifc_req; for (n = ifc.ifc_len/sizeof (struct ifreq); --n>= 0; ifr++) { /* * 別の目的でアドレスファミリ用に使用されているインタフェースを * 使用しないよう注意する */ if (ifr->ifr_addr.sa_family != AF_INET) continue; if (ioctl(s, SIOCGIFFLAGS, (char *) ifr) < 0) { ... } if ((ifr->ifr_flags & IFF_UP) == 0 || (ifr->ifr_flags & IFF_LOOPBACK) || (ifr->ifr_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) == 0) continue; }
次の例では、インタフェースのブロードキャストアドレスを取得するための SIOGGIFBRDADDR ioctl(2) コマンドを示します。
if (ioctl(s, SIOCGIFBRDADDR, (char *) ifr) < 0) { ... } memcpy((char *) &dst, (char *) &ifr->ifr_broadaddr, sizeof ifr->ifr_broadaddr);
また、SIOGGIFBRDADDR ioctl(2) を使用すると、ポイントツーポイントインタフェースの宛先アドレスを取得できます。
インタフェースのブロードキャストアドレスを取得したあと、sendto(3SOCKET) を使用してブロードキャストデータグラムを送信します。
sendto(s, buf, buflen, 0, (struct sockaddr *)&dst, sizeof dst);
ホストのインタフェースがブロードキャストまたはポイントツーポイントアドレスをサポートする場合、そのホストが接続されているインタフェースごとに 1 つの sendto(3SOCKET) を使用します。