今回はcでIPアドレスを取得し、
変更までする方法をご紹介します。
NICの情報を操作するには、
ioctlシステムコールを使います。
ioctlをコールするときに、
フラグを引数に指定します。
指定したフラグによって、
操作する情報とその情報をどうするか、
の2点が変わってきます。
IPアドレスの取得には以下のフラグを使います。
SIOCGIFADDR :
指定したインターフェースのIPアドレスを
取得し、その情報をifreq構造体の
ifr_addrメンバに格納する。
SIOCSIFADDR :
ifreq構造体のifr_addrメンバに格納された情報を
指定したインターフェースのIPアドレスとして
書き込む(更新する)。
コードはこちらになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include<stdio.h> #include<sys/ioctl.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<string.h> #include<arpa/inet.h> #include<net/if.h> int main(void){ struct ifreq ifreq; struct sockaddr_in *sin; char buf[INET_ADDRSTRLEN]; int soc=socket(PF_PACKET, SOCK_RAW, 0); if(soc<0){ perror("[-]socket()"); return 0; } //IPアドレスの取得 memset(&ifreq, 0, sizeof(struct ifreq)); strncpy(ifreq.ifr_name, "eth1", sizeof(ifreq.ifr_name)-1); if(ioctl(soc, SIOCGIFADDR, &ifreq)<0){ perror("[-]ioctl(SIOCGIFADDR)"); close(soc); return 0; } //IPアドレスを見やすいように表示する sin = (struct sockaddr_in *)&ifreq.ifr_addr; inet_ntop(AF_INET, &sin->sin_addr.s_addr, buf, sizeof(buf)); printf("[+]Before: %s\n", buf); //IPアドレスの書き換え sin->sin_addr.s_addr = inet_addr("10.24.94.100"); if(ioctl(soc, SIOCSIFADDR, &ifreq)<0){ perror("[-]ioctl(SIOCSIFADDR)"); close(soc); return 0; } else printf("[+]changed IP address\n"); close(soc); return 0; } |
最初にIPアドレスを取得し、
それを標準出力したときに
見やすいように変換しています。
そして最後にIPアドレスを書き換えています。
キャストや似た名前があるので、
どの構造体、どの型の変数を扱っているのか
気を付けて下さい。
sockaddr_in構造体は、IPアドレスの変換、
そして書き換えの際に必要になります。
まずは ifconfig で実行前の状態を確認します。

このようになっています。
IPアドレス : 10.24.94.41
サブネットマスク: 255.255.240.0
ブロードキャストアドレス : 10.24.95.255
それでは、IPアドレスをプログラムで取得し、
プログラムから書き換えてみます。
変更後のIPアドレスは、
10.24.94.100 を指定しました。

ifconfigで実行後の状態を確認します。

IPアドレスはしっかり変更出来ました。
ところがどうでしょうか。
サブネットマスク、ブロードキャストアドレス
この2つのアドレスは、
255.0.0.0 と 10.255.255.255になってしまいました。
どうやらIPアドレスを書き換えたら、
サブネットマスクとブロードキャストアドレス
これらの変更も必要になってきます。
Cのioctlでサブネットマスクとブロードキャストアドレスを変更する方法
ioctlに指定するフラグはこちらです。
SIOCSIFBRDADDR :
ifreq構造体のifr_broadaddrメンバに格納された情報を
指定したインターフェースの
ブロードキャストアドレスとして書き込む(更新する)。
SIOCSIFNETMASK :
ifreq構造体のifr_netmaskメンバに格納された情報を
指定したインターフェースのサブネットマスクとして
書き込む(更新する)。
以下のコードを最後に追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
sin = (struct sockaddr_in *)&ifreq.ifr_broadaddr; sin->sin_addr.s_addr = inet_addr("10.24.95.255"); if(ioctl(soc, SIOCSIFBRDADDR, &ifreq)<0){ perror("[-]ioctl(SIOCSIFBRDADDR)"); close(soc); return 0; }else printf("[+]set broadcast address\n"); sin = (struct sockaddr_in *)&ifreq.ifr_netmask; sin->sin_addr.s_addr = inet_addr("255.255.240.0"); if(ioctl(soc, SIOCSIFNETMASK, &ifreq)<0){ perror("[-]iocrl(SIOCSIFNETMASK)"); close(soc); return 0; }else printf("[+]set network mask\n"); |
これを実行するとこのようになります。

ifconfig で再度、確認してみます。
ばっちり書き換えれていますね。
サブネットマスクもブロードキャストアドレスも
元々のアドレスと同じになりました。
以上です。IPアドレスの取得と書き換えは
以外と簡単だったことが分かったかと思います。
Cを用いたMACアドレスの書き換え方法:
https://wireless-network.net/macaddr-change/
最後まで読んでいただきありがとうございました。