LoT ラブオンテック

非モテ男の、非モテ男による、【女の子にモテたい】非モテ男のためIT活用ブログ

プログラミング

【C】ioctlでMACアドレスを取得し表示させてみた!(ソケットプログラミング)

更新日:


普通にifconfigで調べられますが、

ソケットプログラミングの勉強として、

指定したインターフェースの

MACアドレスを取得してみました。



インタフェースを操作するには、

基本的にはifreq構造体と

ioctlシステムコールの2つを使います。



なおioctlシステムコールを使うためには、

ソケットを用意する必要があります。



コードはこちらです。



まずはifreq構造体に操作対象とする

インターフェース名を入れます。



ifreq構造体はインタフェース情報を格納

しておくためのプログラム上の格納場所です。

存在しないインターフェースを指定すると、

エラーになりますので注意です。



今回私は"enp0s3"を指定しましたが、

指定するときはインタフェース名を

ifconfigコマンドで確認しましょう。

eth0やeth1が多いかと思います。



インターフェース名を入れたら、

次はioctlでMACアドレスを取得します。

ioctlはネットワークインタフェースを操作

するためのシステムコールです。



ioctlを呼ぶときに様々なフラグを

引数に指定することが可能です。



今回はその中でも"SIOCGIFHWADDR"

というフラグを使って、インタフェースの

MACアドレスを取得します。



SIOCGIFHWADDRを指定したioctlは、

ifreq構造体のifr_hwaddrというメンバに

アドレスを格納してれくれます。



なおioctlを使うためには、

事前にリンクレイヤを扱うrawソケットを

生成しておかなければいけません。




参考までにifreq構造体は/usr/include/linux/if.hで定義されています。


ifreq構造体のメンバを見ていくと、

ifr_hwaddrがあります。



厳密にはifru_hwaddrとして宣言されていますが、

下の方にある#defineのところで

「ifr_ifru.ifru_hwaddrをifr_hwaddrとする」と

定義されています。



なので実際は、ifreq構造体の

ifr_hwaddrとしてメンバに

アクセスできるようになります。



しかし少し複雑なことに、

このMACアドレスを格納するifr_hwaddrは

sockaddr構造体として宣言されています。



つまり構造体の中に、メンバとして

さらに構造体が宣言されています。

初見だと分かりにくいですね。



なのでMACアドレスを操る際は、

さらにsockaddr構造体のメンバに

アクセスしなければいけません。



sockaddr構造体は、

/usr/include/bits/socket.hに定義されています。


sockaddr構造体は、

アドレス情報をひとまとめに格納した構造体です。



char型の配列として、

sa_data[14]と宣言されています。

これの[0]から[5]のところに

MACアドレスが入っています。



printfで表示してみると分かりますが、

[6]~[13]は0が入っています。



MACアドレスはifr_hwaddrのsa_dataに格納

されていることが分かったので、

最後にそれを出力するだけです。



実行結果とifconfigで表示された

MACアドレスと同じかどうか

確認してみてください。



一致していることが確認できるかと思います!




最後まで読んでいただきありがとうございました。



MACアドレスを表示出来れば、
書き換えることも可能です。
https://wireless-network.net/macaddr-change/


-プログラミング

Copyright© LoT ラブオンテック , 2020 All Rights Reserved Powered by STINGER.