LoT ラブオーティー

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

スポンサーリンク

プログラミング

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

更新日:

普通にifconfigで調べられますが、ソケットプログラミングの勉強として、指定したインターフェースのMACアドレスを取得してみました。


インタフェースを操作するには、基本的にはifreq構造体とioctlシステムコールの2つを使います。なお、ioctlシステムコールを使うためには、ソケットを用意する必要があります。


コードはこちらです。



まずはifreq構造体に操作対象とするインターフェース名を入れます。
ifreq構造体は、インタフェース情報を格納しておくためのプログラム上の格納場所です。このとき、存在しないインターフェースを指定すると、エラーになりますので注意です。今回私は"enp0s3"を指定しましたが、指定するときはインタフェース名をifconfigコマンドで確認しましょう。


インターフェース名を入れたら、次はioctlでMACアドレスを取得します。
ioctlはネットワークインタフェースを操作するシステムコールです。


今回は、ioctlの"SIOCGIFHWADDR"というフラグを使って、MACアドレスを取得します。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アドレスと同じか確認してみてください。一致していることが確認できるかと思います!

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

スポンサーリンク

-プログラミング

Copyright© LoT ラブオーティー , 2019 All Rights Reserved Powered by STINGER.