Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
/*
* u-ping.c -- UDP通信でメッセージを送信・受信するクライアント
*
* 0.0: Dec. 14, 2021 by Dai ISHIJIMA
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define EOS '\0'
#define NDUMP 16
#define PORT 43210
#define TIMEOUT 5
char *prog;
#define shift --argc; ++argv
/* strerrorを使ってエラー出力 */
void perrno()
{
fprintf(stderr, "%s: [%d] %s\n", prog, errno, strerror(errno));
}
/* 時間切れまで待つ */
int waitfor(int d, int sec)
{
int nfds;
fd_set readfds;
struct timeval timeout;
fcntl(d, F_SETFL, O_NONBLOCK);
FD_ZERO(&readfds);
FD_SET(d, &readfds);
timeout.tv_sec = sec;
timeout.tv_usec = 0;
/* 時間切れになるか、入力があるまで待つ (定型文) */
nfds = select(d + 1, &readfds, NULL, NULL, &timeout);
if ((nfds < 0) && (errno != EINTR)) {
fprintf(stderr, "%s: select failed\n", prog);
perrno();
exit(1);
}
if ((nfds > 0) && (FD_ISSET(d, &readfds))) {
/* 時間切れ前に入力があった */
return(0);
}
/* 時間切れ */
fprintf(stderr, "%s: connection timed out\n", prog);
exit(1);
}
/* 16進でデータを表示する */
void dump(FILE *fp, int len, char *buf)
{
int i, j;
for (j = 0; j < len; j += NDUMP) {
fprintf(fp, "%04x ", j);
for (i = 0; (i < NDUMP) && (i + j < len); i++) {
if (i == NDUMP / 2) {
fprintf(fp, " ");
}
fprintf(fp, "%02x ", buf[i + j]);
}
for (; i < NDUMP; i++) {
if (i == NDUMP / 2) {
fprintf(fp, " ");
}
fprintf(fp, " ");
}
fprintf(fp, " ");
for (i = 0; (i < NDUMP) && (i + j < len); i++) {
if (i == NDUMP / 2) {
fprintf(fp, " ");
}
if ((' ' <= buf[i + j]) && (buf[i + j] < '~')) {
/* isprint(3) 案件 */
fprintf(fp, "%c", buf[i + j]);
}
else {
fprintf(fp, ".");
}
}
fprintf(fp, "\n");
}
}
/* UDPでメッセージを送信して返信を受け取る */
void udping(int d, unsigned long a, unsigned short p,
int len, char *msg, int sec)
{
struct sockaddr_in saddr;
struct in_addr in;
int slen;
char rbuf[BUFSIZ];
/* 宛先に (IPv4 addr:port = a:p) */
in.s_addr = (in_addr_t)a;
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = in.s_addr;
saddr.sin_port = htons(p);
/* メッセージを送る */
if (sendto(d, msg, len, 0,
(struct sockaddr *)&saddr, sizeof(saddr)) != len) {
/* 送れなかった */
fprintf(stderr, "%s: ", prog);
fprintf(stderr, "can't sendto() %d <- %s:%d\n",
d, inet_ntoa(saddr.sin_addr), p);
perrno();
exit(1);
}
if (sec > 0) {
/* 待ち時間指定があれば待つ */
waitfor(d, sec);
}
/* メッセージを受ける */
slen = sizeof(saddr);
if ((len = recvfrom(d, rbuf, BUFSIZ - 1, 0,
(struct sockaddr *)&saddr,
(socklen_t *)&slen)) < 0) {
/* 来なかった */
fprintf(stderr, "%s: empty message from ", prog);
fprintf(stderr, "%d <- %s:%d\n",
d, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
perrno();
exit(1);
}
if (saddr.sin_addr.s_addr != in.s_addr) {
/* 想定外の返信 */
fprintf(stderr, "%s: unknown packet from %s != ",
prog, inet_ntoa(saddr.sin_addr));
fprintf(stderr, "%s, len = %d\n", inet_ntoa(in), len);
dump(stderr, len, rbuf);
exit(1);
}
/* 想定した返信を表示 */
rbuf[len] = EOS;
fwrite(rbuf, 1, len, stdout);
}
/* ソケットを初期化してディスクリプタ (記述子) を返す */
int initsocket(unsigned long a, unsigned short p)
{
int d;
struct sockaddr_in caddr;
/* UDP用のディスクリプタ (エンドポイント) を得る */
if ((d = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
fprintf(stderr, "%s: can't open socket\n", prog);
perrno();
exit(1);
}
/* 自分のIPv4アドレスとポート */
caddr.sin_family = AF_INET;
caddr.sin_addr.s_addr = a;
caddr.sin_port = htons(p);
/* ディスクリプタに紐付け */
if (bind(d, (struct sockaddr *)&caddr, sizeof(caddr)) != 0) {
fprintf(stderr, "%s: can't bind socket, %d <- %s:%d\n",
prog, d, inet_ntoa(caddr.sin_addr), p);
perrno();
exit(1);
}
return(d);
}
/* UDPクライアント */
void uclient(unsigned long a, int p,
unsigned long ha, int hp, int len, char *msg, int sec)
{
int d;
d = initsocket(a, p);
udping(d, ha, hp, len, msg, sec);
close(d);
}
/* ファイルあるいは標準入力 (-) から (送出用) メッセージを読む */
int getmsg(char *file, char *msg)
{
FILE *fp;
int len;
if ((file[0] == '-') && (file[1] == EOS)) {
len = fread(msg, 1, BUFSIZ - 1, stdin);
}
else {
if ((fp = fopen(file, "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", prog, file);
exit(1);
}
len = fread(msg, 1, BUFSIZ - 1, fp);
fclose(fp);
}
if (len <= 0) {
fprintf(stderr, "%s: input message length == 0\n", prog);
exit(1);
}
msg[len] = EOS;
return(len);
}
void usage()
{
fprintf(stderr, "Usage: %s ", prog);
fprintf(stderr, "[-p #] [-a #.#.#.#] [-m message] -|file host [port]\n");
fprintf(stderr, " \t-p \n");
fprintf(stderr, " \t-a \n");
fprintf(stderr, " \t-t