10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ethernetインターフェース(eth0, eth1)を指定してソケットを作成する (Linux, C, Raspberry Pi)

Posted at

#背景
Raspberry Pi+C言語で、2つのEthernetインターフェースで通信したいことがあり、その時に学んだことのメモです。
Ethernetのソケットの作成方法と、Ethernetのソケットの指定方法を記載します。
以下の環境で動作確認しました。
[ハードウェア]Raspberry Pi2 Model B
[OS]Raspbian GNU/Linux8.0(jessie)

#Ethernetのソケット作成
LinuxでEthernetインターフェースを使ってソケット通信する場合、以下のようなコードを書くことでソケット通信の準備ができます.

eth_com.c
     deststr = IP_ADDRESS; //接続先のIPアドレス #define IP_ADRESS ("192.168.0.12")
     /* ソケットを生成 */
     if((*sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
     {
          printf("fail to create socket\n");
          return -1;
     }

     /* 接続先サーバのアドレス構造体の作成 */
     memset(&server, 0, sizeof(server));
     server.sin_family = PF_INET;
     server.sin_addr.s_addr = inet_addr(deststr);
     server.sin_port = htons(PORT);

     /* 接続処理 */
     if(connect (*sock, (struct sockaddr *)&server, sizeof(server)) < 0)
     {
          printf("fail to connect\n");
          return -1;
     }

ただ、このコードだと、複数のEthernetインターフェースある場合、自動で1つのEthernetインターフェースが使われることになります.例えば、"eth0", "eth1"と二つのEthernetインターフェースがあったとき、自動で"eth0"のインターフェースを使ったsokcetが作成されてしまいます.

#"eth1"のsokectを作成したい
ここで、"eth1"のインターフェースを使ったsokcet通信がしたい場合は、setsockopt関数でインターフェースを指定します.setsockopt()はソケットの生成socket()と接続処理connect()の間で呼び出す.

eth_com.c
    deststr = IP_ADDRESS; //Set IP address
     /* ソケットを生成 */
     if((*sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
     {
          printf("fail to create socket\n");
          return -1;
     }

     /** For usb-ehternet converter **/
     char *opt;
     opt = "eth1";
     setsockopt(*sock, SOL_SOCKET, SO_BINDTODEVICE, opt, 4);

     /* 接続先サーバのアドレス構造体の作成 */
     memset(&server, 0, sizeof(server));
     server.sin_family = PF_INET;
     server.sin_addr.s_addr = inet_addr(deststr);
     server.sin_port = htons(PORT);

     /* 接続処理 */
     if(connect (*sock, (struct sockaddr *)&server, sizeof(server)) < 0)
     {
          printf("fail to connect\n");
          return -1;
     }

参考 : http://stackoverflow.com/questions/3998569/how-to-bind-raw-socket-to-specific-interface

#ルートで実行しないとダメ
しかし、上記のコードでも"eth1"のインターフェースで通信できませんでした.
参考に挙げたweb pageをよくよく読んでみると、

SO_BINDTODEVICE only works if you run as root, right? (on Linux at least) –  sep332 Nov 27 '12 at 21:29

とコメントされている.
つまりroot権限で実行しないといけないようです.
sudoで実行することで、無事に"eth1"のインターフェースで通信できるようになりました.

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?