LinuxでRouterを作る - IPアドレスの変化をDBに記録する

Last Modified: 2004.02.18

12. IPアドレスの変化を記録する
以前は、ADSL RouterのHTMLファイルを解析するスクリプトを10分に1回cronで実行することにより、IPの変化をMySQLに蓄積していた

今回はLinuxがRouterなので自由が利く。
IPアドレスをMySQLに記録するコマンドを作成し、そのコマンドをLinux Router上で実行させることにより、IPアドレスの変化を他のマシンのMySQLデータベースに蓄積する。

1. DBの準備

MySQLが動いているLinux Server上に以下のテーブルを作成し、ADSL Routerからアクセス可能にする。
(grantでアクセス権を与え、必要なら/etc/hosts.allowにmysqldのエントリを記述する)。
DB名、ユーザ名、パスワードはコマンドから指定可能にするので、何でも良い。

 mysql> show fields from iplog;
 +-----------+----------+------+-----+---------+----------------+
 | Field     | Type     | Null | Key | Default | Extra          |
 +-----------+----------+------+-----+---------+----------------+
 | id        | int(11)  |      | PRI | NULL    | auto_increment |
 | adate     | date     | YES  | MUL | NULL    |                |
 | atime     | time     | YES  | MUL | NULL    |                |
 | ip        | tinytext | YES  |     | NULL    |                |
 +-----------+----------+------+-----+---------+----------------+

2. adslip.c

ppp0のIPアドレスが、MySQLに記録してある以前のIPと異なるなら、新しいIPをDBに記録する。

 #include <stdio.h>
 #include <mysql.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
  
 #define	IP_BUFFER_SIZE    16
 #define	ERR_BUFFER_SIZE   1024
 #define	SQL_COMMAND_SIZE  1024
 #define	SUCCESS           0
 #define	ERROR             -1
 
 int	main(int argc, char **argv);
 int	getDB_IP(char *myhost, char *mydb, char *myuser, char *mypasswd, char *ip, char *err_msg);
 int	putDB_IP(char *myhost, char *mydb, char *myuser, char *mypasswd, char *ip, char *err_msg);
 int	getPPP0_IP(char *ip);
 void	usage(void);
 
 int
 main(int argc, char **argv)
 {
 	char	db_ip[IP_BUFFER_SIZE];
 	char	ppp0_ip[IP_BUFFER_SIZE];
 	char	err_msg[ERR_BUFFER_SIZE];
	int	ret = SUCCESS;
 
 	if( argc == 5 )
 	{
 		if( getDB_IP(argv[1],argv[2],argv[3],argv[4],db_ip, err_msg) )
 		{
 			fprintf(stderr, "getDB_IP() Error : %s\n", err_msg);
 			ret = ERROR;
 		}
 		else
 		{
 			getPPP0_IP(ppp0_ip);
 			if( strcmp(db_ip, ppp0_ip) )
 			{
 				if( putDB_IP(argv[1],argv[2],argv[3],argv[4],ppp0_ip, err_msg) )
 				{
 					fprintf(stderr, "putDB_IP() Error : %s\n", err_msg);
 					ret = ERROR;
 				}
 			}
 		}
 	}
 	else
 	{
 		usage();
 		ret = ERROR;
 	}
 	
 	return(ret);
 }
 
 
 int
 getPPP0_IP(char *ip)
 {
 	struct ifreq	ifr;
 	int		s;
 
 	*ip = (char)NULL;
 
 	if( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 	{
 		
 		perror("Socket Error!! ");
 		return(ERROR);
 	}
 
 	strcpy(ifr.ifr_name, "ppp0");
 	if( ioctl(s, SIOCGIFADDR, &ifr) )
 	{
 		perror("Socket Error!! ");
 		close(s);
 		return(ERROR);
 	}
 
 	strncpy(ip, inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr), IP_BUFFER_SIZE);
 	close(s);
 
 	return(SUCCESS);
 }
 

 int
 getDB_IP(char *myhost, char *mydb, char *myuser, char *mypasswd, char *ip, char *err_msg)
 {
 	MYSQL		mysql;
 	MYSQL_RES		*result;
 	MYSQL_ROW		row;
 	int		ret = SUCCESS;
 
 	mysql_init(&mysql);
 	if( mysql_real_connect(&mysql, myhost, myuser, mypasswd, mydb, 0, NULL, 0) )
 	{
 		if( mysql_query(&mysql,"select ip from iplog order by adate desc,atime desc limit 0,1") )
 		{
 			strncpy(err_msg, mysql_error(&mysql), ERR_BUFFER_SIZE);
 			ret = ERROR;
 		}
 		else
 		{
 			if( (result = mysql_store_result(&mysql)) )
 			{
 				row = mysql_fetch_row(result);
 				strncpy(ip, row[0], IP_BUFFER_SIZE);
 			}
 			else
 			{
 				strncpy(err_msg, mysql_error(&mysql), ERR_BUFFER_SIZE);
 				ret = ERROR;
 			}
 			mysql_free_result(result);
 		}
 	}
 	else
 	{
 		strncpy(err_msg, mysql_error(&mysql), ERR_BUFFER_SIZE);
 		ret = ERROR;
 	}
 	mysql_close(&mysql);
 
 	return(ret);
 }
 
 
 int
 putDB_IP(char *myhost, char *mydb, char *myuser, char *mypasswd, char *ip, char *err_msg)
 {
 	MYSQL		mysql;
 	char		sqlcommand[SQL_COMMAND_SIZE];
 	int		ret = SUCCESS;
 
 	sprintf(sqlcommand, "insert into iplog (adate,atime,ip) values (CURDATE(),CURTIME(),'%s')", ip);
 
 	mysql_init(&mysql);
 	if( mysql_real_connect(&mysql, myhost, myuser, mypasswd, mydb, 0, NULL, 0) )
 	{
 		if( mysql_query(&mysql, sqlcommand) )
 		{
 			strncpy(err_msg, mysql_error(&mysql), ERR_BUFFER_SIZE);
 			ret = ERROR;
 		}
 	}
 	else
 	{
 		strncpy(err_msg, mysql_error(&mysql), ERR_BUFFER_SIZE);
 		ret = ERROR;
 	}
 	mysql_close(&mysql);
 
 	return(ret);
 }
 
 
 void
 usage(void)
 {
 	printf("usage : adslip host db user passwd\n");
 }

3. Makefile


 MYSQLLIBDIR=/usr/lib/mysql
 MYSQLINCLUDEDIR=/usr/include/mysql
 BASENAME=adslip
 
 all: $(BASENAME)
 
 $(BASENAME): $(BASENAME).o
 	gcc $(BASENAME).o -o $(BASENAME) -lmysqlclient -lz -L$(MYSQLLIBDIR)
 
 $(BASENAME).o: $(BASENAME).c
 	gcc -c $(BASENAME).c -I$(MYSQLINCLUDEDIR)

4. makeと必要なライブラリの調査

上記のadslip.cをmakeし、lddで必要なライブラリを調査する。
adslipと不足しているライブラリをLinux Routerにコピーしたら、ldconfig -vを忘れずに実行する。

 $ make
 gcc -c adslip.c -I/usr/include/mysql
 gcc adslip.o -o adslip -lmysqlclient -lz -L/usr/lib/mysql
 $ ldd adslip
         libmysqlclient.so.10 => /usr/lib/libmysqlclient.so.10 (0x40020000)  <-- これが不足しているはず
         libz.so.1 => /usr/lib/libz.so.1 (0x40057000)
         libc.so.6 => /lib/libc.so.6 (0x40064000)
         libcrypt.so.1 => /lib/libcrypt.so.1 (0x4018b000)
         libnsl.so.1 => /lib/libnsl.so.1 (0x401b8000)
         libm.so.6 => /lib/libm.so.6 (0x401ce000)
         /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

5. /etc/ppp/ip-up.local, /etc/ppp/ip-down.localの作成

PPP接続が確立すると自動的に呼ばれる/etc/ppp/ip-up.local、
PPP接続が切断されると自動的に呼ばれる /etc/ppp/ip-down.localファイルを作成する。
中身は、両方とも同じ。
実行権限を付けるのを忘れずに。

 #!/bin/bash

 /usr/local/bin/adslip MySQLホスト MySQLDB MySQLユーザ MySQLパスワード

<Prev Top Home
Copyright(C) 2001-2003 Katsuyuki Kobayashi.
このサイトへのリンクや引用時はメール頂戴
webmaster@kkoba.com