Lantronix XPORTをよく使うのだが、いつもDHCPでIPアドレスを取得した時に、どのIPを取得したのか分からない。WindowsのDeviceInstallerをいちいち起動するのも面倒。なので、そういう時に使うプログラム。
UDP ブロードキャストで探すようになっている。
コンパイルは
gcc -O2 -o seekxport seekxport.c -lpthread
※-O2は必須。無いと正しく動かない。
使い方は
./seekxport
1秒まつ。待ち時間を変えたい場合は
./seekxport 10
とかやると10秒まってくれる。
だれかこれを元にWeb BrowserでXPORT探すプログラムを作ってくれるとありがたい。UDP通信しないとなのでむつかしいか?
以下、プログラム
seekxport.c
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <arpa/inet.h>
const int rport = 30718;
int sock;
struct sockaddr_in saddr, caddr;
int mkbroadsend(int port, struct sockaddr_in *caddr){
int sock = 0;
int sockopt = 1;
if((sock = socket(AF_INET, SOCK_DGRAM,0)) < 0){
perror("mkbroadsend: Can't make udp socket.\n");
return 0;
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST,
&sockopt, sizeof(sockopt));
caddr->sin_family = AF_INET;
caddr->sin_port = htons(port);
caddr->sin_addr.s_addr = inet_addr("255.255.255.255");
return sock;
}
void getipfromsockaddr(struct sockaddr_in caddr, unsigned char *ip){
unsigned int v;
v = caddr.sin_addr.s_addr;
ip[0] = v & 0xff;
ip[1] = (v >> 8) & 0xff;
ip[2] = (v >> 16) & 0xff;
ip[3] = (v >> 24) & 0xff;
}
void udprecv(void){
unsigned char data[256];
int magic;
unsigned char ip[4];
int clen, sz;
struct sockaddr_in caddr;
struct hostent *host;
while(1){
sz = recvfrom(sock, (char *)data, sizeof(data), 0,
(struct sockaddr *)&caddr, (socklen_t*)&clen);
getipfromsockaddr(caddr, ip);
memcpy((char *)&magic, data, 4);
if(magic == 0xf7000000){
printf("------------------\n");
printf("IP = %u.%u.%u.%u\n", ip[0],ip[1],ip[2],ip[3]);
printf("Ver = %c%c\n", data[8],data[9]);
printf("MAC = %02X-%02X-%02X-%02X-%02X-%02X\n",
data[24],data[25],data[26],data[27],
data[28],data[29]);
host = gethostbyaddr(&caddr.sin_addr.s_addr,
sizeof(caddr.sin_addr.s_addr), AF_INET);
printf("Host = %s\n", host->h_name);
printf("------------------\n\n");
}
}
}
int main(int argc, char *argv[]){
pthread_t udpthread;
char com[4];
unsigned int t = 1;
sock = mkbroadsend(rport, &saddr);
pthread_create(&udpthread, NULL, (void *)udprecv, NULL);
pthread_detach(udpthread);
com[0] = 0x00;
com[1] = 0x00;
com[2] = 0x00;
com[3] = 0xf6;
sendto(sock, com, 4, 0, (struct sockaddr *)&saddr, sizeof(saddr));
if(argc > 1){
t = strtoul(argv[1], NULL, 0);
printf("Wait %u seconds\n", t);
}
sleep(t);
return 0;
}