メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

データ転送時の欠落しているバイトの並べ替え

ホストとネットワークのエンディアンが異なる

説明

この欠陥は、以下のタイミングでバイト順関数が使用されなかった場合に発生します。

  • ネットワーク ソケットにデータを送信する前。

  • ネットワーク ソケットからデータを受信した後。

リスク

リトル エンディアン バイト順 (最下位バイトが先) を実装しているシステム アーキテクチャもあれば、ビッグ エンディアン バイト順 (最上位バイトが先) を実装しているシステム アーキテクチャもあります。送信データのエンディアンが受信システムのエンディアンと一致しない場合、データ読み取り時に返される値は正しくありません。

修正方法

ソケットからデータを受信した後に、ntohl() などのバイト順関数を使用します。ソケットにデータを送信する前に、htonl() などのバイト順関数を使用します。

すべて展開する

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <byteswap.h>
#include <unistd.h>
#include <string.h>


unsigned int func(int sock, int server)
{
    unsigned int num;   /* assume int is 32-bits */
    if (server)
    {
        /* Server side */
        num = 0x17;
		/* Endianness of server host may not match endianness of network. */
        if (send(sock, (void *)&num, sizeof(num), 0) < (int)sizeof(num)) 
        {
            /* Handle error */
        }
        return 0;
    }
    else {
        /* Endianness of client host may not match endianness of network. */
        if (recv (sock, (void *)&num, sizeof(num), 0) < (int) sizeof(num))  
        {
            /* Handle error */
        }
		
		/* Comparison may be inaccurate */
        if (num> 255)  
        {
            return 255;
        }
        else
        {
            return num;
        }
    }
}
        
      

この例では、変数 num は 16 進数値 0x17 が代入され、ネットワークを経由してサーバーからクライアントに送信されます。サーバー ホストがリトル エンディアンで、ネットワークがビッグ エンディアンの場合、num0x17000000 として転送されます。その後、クライアントでは num の誤った値を読み取って、ローカルの数値と比較します。

修正 — バイト順関数を使用

サーバー ホストから num を送信する前に、htonl() を使用してホストからネットワークへのバイト順を変換します。同様に、クライアント ホストで num を読み取る前に、ntohl() を使用して、ネットワークからホストへのバイト順を変換します。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <byteswap.h>
#include <unistd.h>
#include <string.h>

unsigned int func(int sock, int server)
{
    unsigned int num;   /* assume int is 32-bits */
    if (server)
    {
        /* Server side */
        num = 0x17;
		
		/* Convert to network byte order. */
        num = htonl(num); 
        if (send(sock, (void *)&num, sizeof(num), 0) < (int)sizeof(num)) 
        {
            /* Handle error */
        }
        return 0;
    }
    else {
        if (recv (sock, (void *)&num, sizeof(num), 0) < (int) sizeof(num)) 
        {
            /* Handle error */
        }
		
		/* Convert to host byte order. */
        num = ntohl(num); 
        if (num > 255) 
        {
            return 255;
        }
        else
        {
            return num;
        }
    }
} 

結果情報

グループ: プログラミング
言語: C | C++
既定値: オフ
コマンド ライン構文: MISSING_BYTESWAP
影響度: Medium

バージョン履歴

R2017b で導入