何だかよく分からなかったが、そういうことなのかということが判った。
RC-S380 PASORIを購入、NFC SDKをダウンロードしたが、サンプルプログラムが動かない。felica.libやfelica-nfc.libは動かないようだ。PC/SCというインタフェースがあるようで、ライブラリなどはどうするのかよく分からなかったが、NFC-SDKサンプルのPC/SCのサンプルを順にVS2012でコンパイルしたら動いた。Readmeに書いてある意味が分かった。
RC-S380ではどのサンプルを使うのかちゃんと書いていて欲しいですね。Readmeが良く判らないよ。SONYさん。
PC/SC仕様なのかな。英語だからぱっと見では判らないのが面倒だけど、Part3に少しだけコマンドの記述があるようですね。これ以上の事は判らないのかな。具体的にカードタイプ別のアクセス例とかあればいいのですが。
Interoperability Specification for ICCs and Personal Computer Systems
Part 3. Requirements for PC-Connected Interface Devices
http://www.pcscworkgroup.com/specifications/files/pcsc3_v2.01.09.pdf
Part 5. ICC Resource Manager Definition
http://www.pcscworkgroup.com/specifications/files/pcsc5_v2.01.01.pdf
Part 1. Introduction and Architecture Overview
http://www.pcscworkgroup.com/specifications/files/pcsc1_v2.01.01.pdf
Part 6. ICC Service Provider Interface Definition
http://www.pcscworkgroup.com/specifications/files/pcsc6_v2.01.01.pdf
simple source code for linux. simple question & answers. simple testing tools.
2013年7月8日月曜日
raw パケットの送信
simple raw packet sender source code for testing.
iptablesでDoSのプロテクトテストをしたくても送信できるプログラムの機能が高すぎて、ソースコードをみても面倒な手続きばかりなので、簡単なものを自作した。Linuxなら比較的簡単にrawパケットを投げることができる。
パケット本体は16進ダンプテキストファイルが必要で、簡単に言えば、そのファイルを読んでEthernetPacketとして、指定のインタフェース(eth0)から送信するというもの。オプションで送信MACアドレスの書換、送信IPアドレスの書換、IPヘッダのチェックサムの書換ができます。
パケット本体の16進ダンプの作り方は、、、Wiresharkでパケットをキャプチャーします。1パケットを選択し、右クリックメニュー、copy,bytes,Hex Streamで16進ダンプをクリップボードに入れて、エディタにペーストします。それをファイルに書き込んで、このプログラムのstdinにリダイレクトします。
1パケットは1行で構成してください。/で始まる行はコメント行、;で始まる行もコメント行となります。1行中に 16進文字コード以外の文字は無視されます。 16進は2つで1バイトですので2文字の間に16進文字以外を入れるのはダメです。 例えば
00 81 98 2A 87 88 00 82 99 81 28 c0,c6,01,22
このように空白やカンマは自由に入れて読みやすくしておいて構いません。
コメントは別の行で入れることができます。所謂データの先頭はEthernetHeaderでWiresharkで見えているMACアドレスからです。
ファイルには複数行のパケットが記述できます。指定した間隔で送信します。繰り返し回数を指定すると、それぞれのパケットを回数分送信します。起動指定にかかわらず、入力データストリームで待ち時間、送信回数、インターバル時間を指定できます。
w 1000 1000ミリ秒待ちます。
r 10 10回送信します。
n 0 インターバルを0にします。(待ちを入れないで連続送信します)
あんまりデバッグしていないので、バグがあったらごめんなさい。Wiresharkで動作確認しながら使います。必要に応じてプログラムも改造します。
このプログラムをccでコンパイルします。
$ cc raws.c –o raws
Wiresharkでパケットダンプを取って、それをhexdump.txtに保存したら
# ./raws –i –m –e eth1 < hexdump.txt
などとします。
以下、ソースコード。
/*
* ref = http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/raw.7.html
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#include <linux/if_packet.h>
#include <netdb.h>
char buf[20000];
int sendlen;
extern int h_errno;
const char *filename;
int bIp = 0; // ip check sum
int bUdp = 0; // udp check sum
int bMac = 0; // update own mac
int b4 = 0; // update own ip
int nRep = 1; // repeat count
int nInt = 1000; // interval timer (msec)
const char *pdev = "eth0"; // output device(interface)
int bEOF = 0; // EOF stdin
int nSeq = 0; // text number counter
int bV = 0; // verbos message
char logtimes[128]; // message time-stamp work area
#include <sys/time.h>
#include <time.h>
/*
* YY/MM/DD HH:MM:SS.MMM
*/
const char *logtime()
{
struct timeval tv;
struct tm * tm;
gettimeofday(&tv, 0);
tm = (struct tm *)localtime(&tv.tv_sec);
sprintf(logtimes,"%02d/%02d/%02d %02d:%02d:%02d.%03d ",
tm->tm_year - 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
(int)(tv.tv_usec/ 1000));
return logtimes;
}
/*
* stdin ==> 2 char hex. ---> 1 byte
*/
int getHex(FILE *fin)
{
char c;
while(1)
{
c = getc(stdin);
if (c == EOF)
return c;
if (c == '\n')
return c;
if (c == 'w')
{
/* w 1000\n wait 1sec */
int nW;
char szW[1024];
fgets(szW, 1024, stdin);
nW = atol(szW);
printf("%s... sleep %dmsec. now\n", logtime(), nW);
usleep(nW * 1000);
}
if (c == 'r')
{
/* r 1000\n change repeat 1000 times */
int nW;
char szW[1024];
fgets(szW, 1024, stdin);
nRep = atol(szW);
printf("%s... change repeat counter %d.\n", logtime(), nRep);
}
if (c == 'n')
{
/* n 10\n change interval timer 10msec */
int nW;
char szW[1024];
fgets(szW, 1024, stdin);
nInt = atol(szW);
printf("%s... change interval timer %dmsec.\n", logtime(), nRep);
}
if ((c >= '0') && (c <= '9'))
return c;
if ((c >= 'A') && (c <= 'F'))
return c;
if ((c >= 'a') && (c <= 'f'))
return c;
}
}
/*
* stdin ---> buf (send data)
*/
int LoadSendData(void)
{
int nCnt = 0;
char *pbuf = buf;
sendlen = 0;
while(1)
{
int c[2];
c[0] = getHex(stdin);
if (c[0] == EOF)
{
bEOF = 1;
if (sendlen == 0)
return;
}
if ((c[0] == '/') || /* line comment */
(c[0] == ';'))
{
char szW[1024];
fgets(szW, 1024, stdin);
continue;
}
if (c[0] == '\n')
{
if (sendlen)
{
/* multi text */
/* printf("\n multi text\n"); */
break;
}
continue;
}
c[1] = getHex(stdin);
if (c[1] == EOF)
break;
c[0] = toupper(c[0]);
c[1] = toupper(c[1]);
if (c[0] > '9')
c[0] = c[0] - 'A' + 10;
else
c[0] -= '0';
if (c[1] > '9')
c[1] = c[1] - 'A' + 10;
else
c[1] -= '0';
*pbuf = (c[0] << 4) | c[1];
if (bV) printf("%02X ", *pbuf & 0x0ff);
pbuf++;
sendlen++;
nCnt++;
if (nCnt == 8)
if (bV) printf(" ");
if (nCnt == 16)
{
if (bV) printf("\n");
nCnt = 0;
}
if (sendlen >= sizeof(buf))
return;
}
if (bV) printf("\nsend length %d byte...\n", sendlen);
}
/*
* calculate check-sum for ip-header
*/
unsigned short csum(unsigned short *buf, int nwords)
{
unsigned long sum;
for(sum=0; nwords>0; nwords--)
{
sum += *buf++;
}
sum = (sum >> 16) + (sum &0xffff);
sum = (sum >> 16) + (sum &0xffff);
return (unsigned short)(~sum);
}
/*
* modify data, send data.
* return 1: normal end
* 0: error
*/
int SendRawData(void)
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
struct ifreq if_ip;
struct ether_header *eh = (struct ether_header *) buf;
struct iphdr *iph = (struct iphdr *) (buf + sizeof(struct ether_header));
struct udphdr *udph =
(struct udphdr *) (buf + sizeof(struct iphdr) + sizeof(struct ether_header));
struct sockaddr_ll socket_address;
/* Open RAW socket to send on */
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1)
{
perror("socket error");
return 0;
}
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, pdev, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
{
perror("SIOCGIFINDEX error");
return 0;
}
/* get mac */
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, pdev, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
{
perror("SIOCGIFHWADDR get MAC error");
return 0;
}
/* get ip */
memset(&if_ip, 0, sizeof(struct ifreq));
strncpy(if_ip.ifr_name, pdev, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFADDR, &if_ip) < 0)
{
perror("SIOCGIFADDR get IP error");
return 0;
}
/* OWN mac addr update ? */
if (bMac)
{
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
if (bV)
printf("own MAC=%02x:%02x:%02x:%02x:%02x:%02x \n",
eh->ether_shost[0] & 0x0ff,
eh->ether_shost[1] & 0x0ff,
eh->ether_shost[2] & 0x0ff,
eh->ether_shost[3] & 0x0ff,
eh->ether_shost[4] & 0x0ff,
eh->ether_shost[5] & 0x0ff);
}
/* Own IP addr update ? */
if (b4)
{
iph->saddr = inet_addr(inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
if (bV)
printf("own ip=%d.%d.%d.%d \n",
(htonl(iph->saddr) >> 24) & 0x0ff,
(htonl(iph->saddr) >> 16) & 0x0ff,
(htonl(iph->saddr) >> 8) & 0x0ff,
(htonl(iph->saddr)) & 0x0ff);
}
/* check sum IP calculate ?*/
if (bIp)
{
iph->check = 0;
iph->check = csum((unsigned short *)(buf+sizeof(struct ether_header)), sizeof(struct iphdr)/2);
if (bV) printf("ip check-sum=%04X\n", iph->check);
}
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC copy from send data */
socket_address.sll_addr[0] = eh->ether_dhost[0];
socket_address.sll_addr[1] = eh->ether_dhost[1];
socket_address.sll_addr[2] = eh->ether_dhost[2];
socket_address.sll_addr[3] = eh->ether_dhost[3];
socket_address.sll_addr[4] = eh->ether_dhost[4];
socket_address.sll_addr[5] = eh->ether_dhost[5];
if (sendlen)
{
int i;
int nR = 1;
nSeq++;
printf("--------------\n");
for (i = 0; i < nRep; i++)
{
if (sendto(sockfd, buf, sendlen,
0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
{
printf("Send error \n");
return 0;
}
printf("%4d-(%4d) %s ........ sent %dbyte\n",nSeq, nR++, logtime(), sendlen);
if (nInt)
usleep(nInt * 1000);
}
printf("--------------\n");
}
close(sockfd);
return 1;
}
/*
* raws (raw packet sender) main
*
*/
int main( int argc, char **argv)
{
char c;
while(( c = getopt(argc, argv, "e:ium4n:r:h")) != -1)
{
switch(c)
{
case 'h':
printf(" raws (send raw ip packet from file-stream)\n");
printf(" -e xxx9 : net-interface [eth0]\n");
printf(" -i : update ip check-sum [no-update]\n");
printf(" -m : update own MAC address \n");
printf(" -4 : update own IP address \n");
printf(" -v : verbos \n");
printf(" -n 9999 : interval timer between each text[1000] \n");
printf(" -r 9999 : repead sending count each text[1] \n");
printf(" < filename : hex-dump data from stdin\n");
printf(" -h : this message\n");
printf(" e.g.\n");
printf(" raws -i <abc.dat : send abc.dat to 'eth0' with update c-sum\n");
printf(" e.g.\n");
return 0;
case 'e':
pdev = optarg;
break;
case 'i':
bIp = 1;
break;
case '4':
b4 = 1;
break;
case 'm':
bMac = 1;
break;
case 'v':
bV = 1;
break;
case 'n':
nInt = atol(optarg);
break;
case 'r':
nRep = atol(optarg);
break;
}
}
if (bV)
printf ("e:%s %s %s %s interval=%d repeat=%d stdin\n",
pdev, bIp ? "IP-check-sum": "", bMac ? "Own-MAC" : "", b4 ? "Own-IP": "", nInt, nRep);
// load send data
while(!bEOF)
{
LoadSendData();
if (sendlen)
{
if (!SendRawData())
break;
}
usleep(nInt * 1000);
}
if (bV)
printf(" .... raws program stopped.\n");
return 1;
}
iptablesでDoSのプロテクトテストをしたくても送信できるプログラムの機能が高すぎて、ソースコードをみても面倒な手続きばかりなので、簡単なものを自作した。Linuxなら比較的簡単にrawパケットを投げることができる。
パケット本体は16進ダンプテキストファイルが必要で、簡単に言えば、そのファイルを読んでEthernetPacketとして、指定のインタフェース(eth0)から送信するというもの。オプションで送信MACアドレスの書換、送信IPアドレスの書換、IPヘッダのチェックサムの書換ができます。
パケット本体の16進ダンプの作り方は、、、Wiresharkでパケットをキャプチャーします。1パケットを選択し、右クリックメニュー、copy,bytes,Hex Streamで16進ダンプをクリップボードに入れて、エディタにペーストします。それをファイルに書き込んで、このプログラムのstdinにリダイレクトします。
1パケットは1行で構成してください。/で始まる行はコメント行、;で始まる行もコメント行となります。1行中に 16進文字コード以外の文字は無視されます。 16進は2つで1バイトですので2文字の間に16進文字以外を入れるのはダメです。 例えば
00 81 98 2A 87 88 00 82 99 81 28 c0,c6,01,22
このように空白やカンマは自由に入れて読みやすくしておいて構いません。
コメントは別の行で入れることができます。所謂データの先頭はEthernetHeaderでWiresharkで見えているMACアドレスからです。
ファイルには複数行のパケットが記述できます。指定した間隔で送信します。繰り返し回数を指定すると、それぞれのパケットを回数分送信します。起動指定にかかわらず、入力データストリームで待ち時間、送信回数、インターバル時間を指定できます。
w 1000 1000ミリ秒待ちます。
r 10 10回送信します。
n 0 インターバルを0にします。(待ちを入れないで連続送信します)
あんまりデバッグしていないので、バグがあったらごめんなさい。Wiresharkで動作確認しながら使います。必要に応じてプログラムも改造します。
このプログラムをccでコンパイルします。
$ cc raws.c –o raws
Wiresharkでパケットダンプを取って、それをhexdump.txtに保存したら
# ./raws –i –m –e eth1 < hexdump.txt
などとします。
以下、ソースコード。
/*
* ref = http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/raw.7.html
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#include <linux/if_packet.h>
#include <netdb.h>
char buf[20000];
int sendlen;
extern int h_errno;
const char *filename;
int bIp = 0; // ip check sum
int bUdp = 0; // udp check sum
int bMac = 0; // update own mac
int b4 = 0; // update own ip
int nRep = 1; // repeat count
int nInt = 1000; // interval timer (msec)
const char *pdev = "eth0"; // output device(interface)
int bEOF = 0; // EOF stdin
int nSeq = 0; // text number counter
int bV = 0; // verbos message
char logtimes[128]; // message time-stamp work area
#include <sys/time.h>
#include <time.h>
/*
* YY/MM/DD HH:MM:SS.MMM
*/
const char *logtime()
{
struct timeval tv;
struct tm * tm;
gettimeofday(&tv, 0);
tm = (struct tm *)localtime(&tv.tv_sec);
sprintf(logtimes,"%02d/%02d/%02d %02d:%02d:%02d.%03d ",
tm->tm_year - 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
(int)(tv.tv_usec/ 1000));
return logtimes;
}
/*
* stdin ==> 2 char hex. ---> 1 byte
*/
int getHex(FILE *fin)
{
char c;
while(1)
{
c = getc(stdin);
if (c == EOF)
return c;
if (c == '\n')
return c;
if (c == 'w')
{
/* w 1000\n wait 1sec */
int nW;
char szW[1024];
fgets(szW, 1024, stdin);
nW = atol(szW);
printf("%s... sleep %dmsec. now\n", logtime(), nW);
usleep(nW * 1000);
}
if (c == 'r')
{
/* r 1000\n change repeat 1000 times */
int nW;
char szW[1024];
fgets(szW, 1024, stdin);
nRep = atol(szW);
printf("%s... change repeat counter %d.\n", logtime(), nRep);
}
if (c == 'n')
{
/* n 10\n change interval timer 10msec */
int nW;
char szW[1024];
fgets(szW, 1024, stdin);
nInt = atol(szW);
printf("%s... change interval timer %dmsec.\n", logtime(), nRep);
}
if ((c >= '0') && (c <= '9'))
return c;
if ((c >= 'A') && (c <= 'F'))
return c;
if ((c >= 'a') && (c <= 'f'))
return c;
}
}
/*
* stdin ---> buf (send data)
*/
int LoadSendData(void)
{
int nCnt = 0;
char *pbuf = buf;
sendlen = 0;
while(1)
{
int c[2];
c[0] = getHex(stdin);
if (c[0] == EOF)
{
bEOF = 1;
if (sendlen == 0)
return;
}
if ((c[0] == '/') || /* line comment */
(c[0] == ';'))
{
char szW[1024];
fgets(szW, 1024, stdin);
continue;
}
if (c[0] == '\n')
{
if (sendlen)
{
/* multi text */
/* printf("\n multi text\n"); */
break;
}
continue;
}
c[1] = getHex(stdin);
if (c[1] == EOF)
break;
c[0] = toupper(c[0]);
c[1] = toupper(c[1]);
if (c[0] > '9')
c[0] = c[0] - 'A' + 10;
else
c[0] -= '0';
if (c[1] > '9')
c[1] = c[1] - 'A' + 10;
else
c[1] -= '0';
*pbuf = (c[0] << 4) | c[1];
if (bV) printf("%02X ", *pbuf & 0x0ff);
pbuf++;
sendlen++;
nCnt++;
if (nCnt == 8)
if (bV) printf(" ");
if (nCnt == 16)
{
if (bV) printf("\n");
nCnt = 0;
}
if (sendlen >= sizeof(buf))
return;
}
if (bV) printf("\nsend length %d byte...\n", sendlen);
}
/*
* calculate check-sum for ip-header
*/
unsigned short csum(unsigned short *buf, int nwords)
{
unsigned long sum;
for(sum=0; nwords>0; nwords--)
{
sum += *buf++;
}
sum = (sum >> 16) + (sum &0xffff);
sum = (sum >> 16) + (sum &0xffff);
return (unsigned short)(~sum);
}
/*
* modify data, send data.
* return 1: normal end
* 0: error
*/
int SendRawData(void)
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
struct ifreq if_ip;
struct ether_header *eh = (struct ether_header *) buf;
struct iphdr *iph = (struct iphdr *) (buf + sizeof(struct ether_header));
struct udphdr *udph =
(struct udphdr *) (buf + sizeof(struct iphdr) + sizeof(struct ether_header));
struct sockaddr_ll socket_address;
/* Open RAW socket to send on */
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1)
{
perror("socket error");
return 0;
}
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, pdev, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
{
perror("SIOCGIFINDEX error");
return 0;
}
/* get mac */
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, pdev, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
{
perror("SIOCGIFHWADDR get MAC error");
return 0;
}
/* get ip */
memset(&if_ip, 0, sizeof(struct ifreq));
strncpy(if_ip.ifr_name, pdev, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFADDR, &if_ip) < 0)
{
perror("SIOCGIFADDR get IP error");
return 0;
}
/* OWN mac addr update ? */
if (bMac)
{
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
if (bV)
printf("own MAC=%02x:%02x:%02x:%02x:%02x:%02x \n",
eh->ether_shost[0] & 0x0ff,
eh->ether_shost[1] & 0x0ff,
eh->ether_shost[2] & 0x0ff,
eh->ether_shost[3] & 0x0ff,
eh->ether_shost[4] & 0x0ff,
eh->ether_shost[5] & 0x0ff);
}
/* Own IP addr update ? */
if (b4)
{
iph->saddr = inet_addr(inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
if (bV)
printf("own ip=%d.%d.%d.%d \n",
(htonl(iph->saddr) >> 24) & 0x0ff,
(htonl(iph->saddr) >> 16) & 0x0ff,
(htonl(iph->saddr) >> 8) & 0x0ff,
(htonl(iph->saddr)) & 0x0ff);
}
/* check sum IP calculate ?*/
if (bIp)
{
iph->check = 0;
iph->check = csum((unsigned short *)(buf+sizeof(struct ether_header)), sizeof(struct iphdr)/2);
if (bV) printf("ip check-sum=%04X\n", iph->check);
}
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC copy from send data */
socket_address.sll_addr[0] = eh->ether_dhost[0];
socket_address.sll_addr[1] = eh->ether_dhost[1];
socket_address.sll_addr[2] = eh->ether_dhost[2];
socket_address.sll_addr[3] = eh->ether_dhost[3];
socket_address.sll_addr[4] = eh->ether_dhost[4];
socket_address.sll_addr[5] = eh->ether_dhost[5];
if (sendlen)
{
int i;
int nR = 1;
nSeq++;
printf("--------------\n");
for (i = 0; i < nRep; i++)
{
if (sendto(sockfd, buf, sendlen,
0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
{
printf("Send error \n");
return 0;
}
printf("%4d-(%4d) %s ........ sent %dbyte\n",nSeq, nR++, logtime(), sendlen);
if (nInt)
usleep(nInt * 1000);
}
printf("--------------\n");
}
close(sockfd);
return 1;
}
/*
* raws (raw packet sender) main
*
*/
int main( int argc, char **argv)
{
char c;
while(( c = getopt(argc, argv, "e:ium4n:r:h")) != -1)
{
switch(c)
{
case 'h':
printf(" raws (send raw ip packet from file-stream)\n");
printf(" -e xxx9 : net-interface [eth0]\n");
printf(" -i : update ip check-sum [no-update]\n");
printf(" -m : update own MAC address \n");
printf(" -4 : update own IP address \n");
printf(" -v : verbos \n");
printf(" -n 9999 : interval timer between each text[1000] \n");
printf(" -r 9999 : repead sending count each text[1] \n");
printf(" < filename : hex-dump data from stdin\n");
printf(" -h : this message\n");
printf(" e.g.\n");
printf(" raws -i <abc.dat : send abc.dat to 'eth0' with update c-sum\n");
printf(" e.g.\n");
return 0;
case 'e':
pdev = optarg;
break;
case 'i':
bIp = 1;
break;
case '4':
b4 = 1;
break;
case 'm':
bMac = 1;
break;
case 'v':
bV = 1;
break;
case 'n':
nInt = atol(optarg);
break;
case 'r':
nRep = atol(optarg);
break;
}
}
if (bV)
printf ("e:%s %s %s %s interval=%d repeat=%d stdin\n",
pdev, bIp ? "IP-check-sum": "", bMac ? "Own-MAC" : "", b4 ? "Own-IP": "", nInt, nRep);
// load send data
while(!bEOF)
{
LoadSendData();
if (sendlen)
{
if (!SendRawData())
break;
}
usleep(nInt * 1000);
}
if (bV)
printf(" .... raws program stopped.\n");
return 1;
}
2013年7月7日日曜日
ubuntuでwiresharkを実行すると警告ばかり。
デバッグで使うのだからセキュリティは不要なんだけど、一般利用を考えて、Linuxもセキュリティが厳しくなってきている。で、Wiresharkの使うCAP権限を一般ユーザに入れることで、一般ユーザが起動しても正しく動作してくれる。
以下のコマンドを実行するとWiresharkのCAP権限が一般ユーザに開放される。
$ sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/bin/dumpcap
iptablesの勉強
まずは、以下のドキュメントを読む。
Iptablesチュートリアル 1.2.2
それで、実際にiptablesに何かしら設定して、使ってみる。
PCは2台以上必要。VMwareの VMPlayerでも出来る。
このブログのUDPS,UDPR,TCPS,TCPRを使うとUDPとTCPのフィルター確認が簡単にできる。
Iptablesチュートリアル 1.2.2
それで、実際にiptablesに何かしら設定して、使ってみる。
PCは2台以上必要。VMwareの VMPlayerでも出来る。
このブログのUDPS,UDPR,TCPS,TCPRを使うとUDPとTCPのフィルター確認が簡単にできる。
TCP サーバー Linux用
simple tcp server source code for testing.
TCPサーバーです。TCPクライアントと対で使います。サーバーを立ち上げておいて、クライアントから通信します。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
char buf[20000];
extern int h_errno;
int main( int argc, char **argv)
{
int total = 0;
int c;
int i;
int sock;
struct sockaddr_in addr;
char senderstr[512];
char *ips = ""; // server IP
char *ipd = "0.0.0.0"; // no use
int nPort = 12345; // server port
int nCount = 10; // reply times (10)
int nInt = 100; // interval 100ms
int bReply = 0; // no use
int datalen = 1024; // send data length (max sizeof(buf))
int ses = 0; // session seq number
opterr = 0;
while(( c = getopt(argc, argv, "s:d:p:n:t:rhl:")) != -1)
{
switch(c)
{
case 'l':
datalen = atol(optarg);
case 'h':
printf(" tcpr (server for 1 client only)\n");
printf(" -s xxx.xxx.xxx.xxx : server IP [INETADDR_ANY]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -n 999 : count of repeat send data [10] (for no-req)\n");
printf(" -t 999 : interval time of sending [100]msec (for no-req)\n");
printf(" -l 9999 : replay data length [1024]byte (for no-req)\n");
printf(" \n");
return 0;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
break;
case 'r':
bReply = 1;
break;
}
}
if (datalen > sizeof(buf))
datalen = sizeof(buf);
printf("\n tcpr (server)\n");
printf(" Src = %s, Dst = %s, Port=%d, Count=%d, Interval=%dmsec len=%d\n",
ips, ipd, nPort, nCount, nInt, datalen);
sock = socket(AF_INET,SOCK_STREAM, 0);
if (1)
{
int ret;
int on = 1;
ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
if (ret)
{
close(sock);
printf("setsockopt error %d \n", h_errno);
return 0;
}
}
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
if (strlen(ips))
addr.sin_addr.s_addr = inet_addr(ips);
else
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
{
close(sock);
printf("bind error %d\n", h_errno);
return 0;
}
printf("--- bind port=%d \n", ntohs(addr.sin_port));
if (listen(sock, 2))
{
close(sock);
printf(" listen error %d\n", h_errno);
return 0;
}
i = 0;
while (1)
{
int i;
int addrlen;
int reclen;
int sockC;
int rlen = datalen;
int rcnt = nCount;
int rint = nInt;
char *pPos;
memset(buf, 0, sizeof(buf));
addrlen = sizeof(addr);
sockC = accept(sock, (struct sockaddr *)&addr, &addrlen);
if (sockC < 0)
{
printf("accept error %d\n", h_errno);
break;
}
total = 0;
ses++;
printf("start session .... [%d]\n", ses);
memset(buf, 0, sizeof(buf));
reclen = recv(sockC, buf, sizeof(buf) - 1, 0);
if (reclen <= 0)
{
printf("recv error %d\n", h_errno);
close(sockC);
continue;
}
inet_ntop(AF_INET, &addr.sin_addr, senderstr, sizeof(senderstr));
printf("RCV<<<%s", buf);
printf("... %s %d len=%d... ", senderstr, ntohs(addr.sin_port), reclen);
printf("\n");
pPos = strstr(buf, "-L");
if (pPos)
{
int n = atol(pPos + 2);
if (n)
rlen = n;
}
pPos = strstr(buf, "-C");
if (pPos)
{
int n= atol(pPos + 2);
if (n)
rcnt = n;
}
pPos = strstr(buf, "-T");
if (pPos)
{
int n= atol(pPos + 2);
if (n)
rint = n;
}
printf(" reply length=[%d], [%d]times, interval [%d]msec\n",
rlen, rcnt, rint);
for ( i = 0; i < rcnt; i++)
{
/// reply
memset(buf, i & 0xf | '0', rlen);
sprintf(buf, "Reply %04d", i);
sendto(sockC, buf, rlen, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("SND>>>%s", buf);
printf("... %d\n", rlen);
usleep(rint * 1000); // nInt msec
total += datalen;
}
close(sockC);
printf("..... close session [%d], total send length=%d\n", ses, total);
total = 0;
}
close(sock);
return 1;
}
TCPサーバーです。TCPクライアントと対で使います。サーバーを立ち上げておいて、クライアントから通信します。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
char buf[20000];
extern int h_errno;
int main( int argc, char **argv)
{
int total = 0;
int c;
int i;
int sock;
struct sockaddr_in addr;
char senderstr[512];
char *ips = ""; // server IP
char *ipd = "0.0.0.0"; // no use
int nPort = 12345; // server port
int nCount = 10; // reply times (10)
int nInt = 100; // interval 100ms
int bReply = 0; // no use
int datalen = 1024; // send data length (max sizeof(buf))
int ses = 0; // session seq number
opterr = 0;
while(( c = getopt(argc, argv, "s:d:p:n:t:rhl:")) != -1)
{
switch(c)
{
case 'l':
datalen = atol(optarg);
case 'h':
printf(" tcpr (server for 1 client only)\n");
printf(" -s xxx.xxx.xxx.xxx : server IP [INETADDR_ANY]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -n 999 : count of repeat send data [10] (for no-req)\n");
printf(" -t 999 : interval time of sending [100]msec (for no-req)\n");
printf(" -l 9999 : replay data length [1024]byte (for no-req)\n");
printf(" \n");
return 0;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
break;
case 'r':
bReply = 1;
break;
}
}
if (datalen > sizeof(buf))
datalen = sizeof(buf);
printf("\n tcpr (server)\n");
printf(" Src = %s, Dst = %s, Port=%d, Count=%d, Interval=%dmsec len=%d\n",
ips, ipd, nPort, nCount, nInt, datalen);
sock = socket(AF_INET,SOCK_STREAM, 0);
if (1)
{
int ret;
int on = 1;
ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
if (ret)
{
close(sock);
printf("setsockopt error %d \n", h_errno);
return 0;
}
}
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
if (strlen(ips))
addr.sin_addr.s_addr = inet_addr(ips);
else
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
{
close(sock);
printf("bind error %d\n", h_errno);
return 0;
}
printf("--- bind port=%d \n", ntohs(addr.sin_port));
if (listen(sock, 2))
{
close(sock);
printf(" listen error %d\n", h_errno);
return 0;
}
i = 0;
while (1)
{
int i;
int addrlen;
int reclen;
int sockC;
int rlen = datalen;
int rcnt = nCount;
int rint = nInt;
char *pPos;
memset(buf, 0, sizeof(buf));
addrlen = sizeof(addr);
sockC = accept(sock, (struct sockaddr *)&addr, &addrlen);
if (sockC < 0)
{
printf("accept error %d\n", h_errno);
break;
}
total = 0;
ses++;
printf("start session .... [%d]\n", ses);
memset(buf, 0, sizeof(buf));
reclen = recv(sockC, buf, sizeof(buf) - 1, 0);
if (reclen <= 0)
{
printf("recv error %d\n", h_errno);
close(sockC);
continue;
}
inet_ntop(AF_INET, &addr.sin_addr, senderstr, sizeof(senderstr));
printf("RCV<<<%s", buf);
printf("... %s %d len=%d... ", senderstr, ntohs(addr.sin_port), reclen);
printf("\n");
pPos = strstr(buf, "-L");
if (pPos)
{
int n = atol(pPos + 2);
if (n)
rlen = n;
}
pPos = strstr(buf, "-C");
if (pPos)
{
int n= atol(pPos + 2);
if (n)
rcnt = n;
}
pPos = strstr(buf, "-T");
if (pPos)
{
int n= atol(pPos + 2);
if (n)
rint = n;
}
printf(" reply length=[%d], [%d]times, interval [%d]msec\n",
rlen, rcnt, rint);
for ( i = 0; i < rcnt; i++)
{
/// reply
memset(buf, i & 0xf | '0', rlen);
sprintf(buf, "Reply %04d", i);
sendto(sockC, buf, rlen, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("SND>>>%s", buf);
printf("... %d\n", rlen);
usleep(rint * 1000); // nInt msec
total += datalen;
}
close(sockC);
printf("..... close session [%d], total send length=%d\n", ses, total);
total = 0;
}
close(sock);
return 1;
}
TCP クライアント Linux用
simple tcp client source code for testing.
TCPパケットを送信して、受信を待つというプログラムです。 このブログのTCPサーバーと対で使います。クライアント側から受信すべきデータのサイズと送信インターバルを指定できます。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
extern int h_errno;
char buf[20000];
char logtimes[128];
#include <sys/time.h>
#include <time.h>
const char *logtime()
{
struct timeval tv;
struct tm * tm;
gettimeofday(&tv, 0);
tm = (struct tm *)localtime(&tv.tv_sec);
sprintf(logtimes,"%02d/%02d/%02d %02d:%02d:%02d.%03d ",
tm->tm_year - 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
(int)(tv.tv_usec/ 1000));
return logtimes;
}
int main(int argc, char *argv[])
{
int total = 0;
int i;
int sock;
struct sockaddr_in addr;
char *ips = "0.0.0.0";
char *ipd = "0.0.0.0";
int nPort = 12345;
int nCount = 0;
int nInt = 0;
int rlen = 0;
int c;
int bWait = 1;
int datalen = 1024;
opterr = 0;
i = time(0) % 10000;
while(( c = getopt(argc, argv, "s:d:p:n:t:w:l:hr:")) != -1)
{
switch(c)
{
case 'l':
datalen = atol(optarg);
break;
case 'h':
printf(" tcps (client) \n");
printf(" -d xxx.xxx.xxx.xxx : server IP [0.0.0.0]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -l 9999 : send packet size [1500]\n");
printf(" -w [0|1] : wait reply data [1:Wait]\n");
printf(" -n 9999 : request reply count [no-request]\n");
printf(" -t 9999 : request reply interval milli-sec. [no-request]\n");
printf(" -r 9999 : request reply length byte. [no-request]\n");
printf(" \n");
return 0;
break;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
if (nInt <= 0)
nInt = 1;
break;
case 'w':
bWait = atol(optarg);
break;
case 'r':
rlen = atol(optarg);
break;
}
}
if (datalen > sizeof(buf))
datalen = sizeof(buf)+
printf("\n tcps (client)\n");
printf(" Src = %s, Dst = %s, Port=%d, send datalen=%d %s\n",
ips, ipd, nPort, datalen, bWait ? "Wait" : "Not-Wait");
printf(" Request legnth=%d, count=%d, interval=%dmsec\n",
rlen, nCount, nInt);
sock = socket(AF_INET,SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
addr.sin_addr.s_addr = inet_addr(ipd);
if (connect(sock, (struct sockaddr *)&addr,sizeof(addr)) != 0)
{
printf("connect error %d\n", h_errno);
close(sock);
return 0;
}
memset(buf, i & 0x07f, sizeof(buf));
sprintf(buf, "P%04d-L%d-C%d-T%d", i,
rlen, nCount, nInt);
sendto(sock, buf, datalen, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("%sSND>>>%s",logtime(), buf);
printf("... %d\n", datalen);
while(bWait)
{
int addrlen;
char senderstr[256];
int reclen;
memset(buf, 0, sizeof(buf));
reclen = read(sock, buf, sizeof(buf) - 1);
if (reclen <= 0) // if host is closed ?
break;
total += reclen;
printf("%sRCV<<<%s",logtime(), buf);
printf("... len=%d... ", reclen);
printf("\n");
usleep(10);
}
printf(" total length=%d\n", total);
printf(" ... end.\n");
close(sock);
return 1;
}
TCPパケットを送信して、受信を待つというプログラムです。 このブログのTCPサーバーと対で使います。クライアント側から受信すべきデータのサイズと送信インターバルを指定できます。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
extern int h_errno;
char buf[20000];
char logtimes[128];
#include <sys/time.h>
#include <time.h>
const char *logtime()
{
struct timeval tv;
struct tm * tm;
gettimeofday(&tv, 0);
tm = (struct tm *)localtime(&tv.tv_sec);
sprintf(logtimes,"%02d/%02d/%02d %02d:%02d:%02d.%03d ",
tm->tm_year - 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
(int)(tv.tv_usec/ 1000));
return logtimes;
}
int main(int argc, char *argv[])
{
int total = 0;
int i;
int sock;
struct sockaddr_in addr;
char *ips = "0.0.0.0";
char *ipd = "0.0.0.0";
int nPort = 12345;
int nCount = 0;
int nInt = 0;
int rlen = 0;
int c;
int bWait = 1;
int datalen = 1024;
opterr = 0;
i = time(0) % 10000;
while(( c = getopt(argc, argv, "s:d:p:n:t:w:l:hr:")) != -1)
{
switch(c)
{
case 'l':
datalen = atol(optarg);
break;
case 'h':
printf(" tcps (client) \n");
printf(" -d xxx.xxx.xxx.xxx : server IP [0.0.0.0]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -l 9999 : send packet size [1500]\n");
printf(" -w [0|1] : wait reply data [1:Wait]\n");
printf(" -n 9999 : request reply count [no-request]\n");
printf(" -t 9999 : request reply interval milli-sec. [no-request]\n");
printf(" -r 9999 : request reply length byte. [no-request]\n");
printf(" \n");
return 0;
break;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
if (nInt <= 0)
nInt = 1;
break;
case 'w':
bWait = atol(optarg);
break;
case 'r':
rlen = atol(optarg);
break;
}
}
if (datalen > sizeof(buf))
datalen = sizeof(buf)+
printf("\n tcps (client)\n");
printf(" Src = %s, Dst = %s, Port=%d, send datalen=%d %s\n",
ips, ipd, nPort, datalen, bWait ? "Wait" : "Not-Wait");
printf(" Request legnth=%d, count=%d, interval=%dmsec\n",
rlen, nCount, nInt);
sock = socket(AF_INET,SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
addr.sin_addr.s_addr = inet_addr(ipd);
if (connect(sock, (struct sockaddr *)&addr,sizeof(addr)) != 0)
{
printf("connect error %d\n", h_errno);
close(sock);
return 0;
}
memset(buf, i & 0x07f, sizeof(buf));
sprintf(buf, "P%04d-L%d-C%d-T%d", i,
rlen, nCount, nInt);
sendto(sock, buf, datalen, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("%sSND>>>%s",logtime(), buf);
printf("... %d\n", datalen);
while(bWait)
{
int addrlen;
char senderstr[256];
int reclen;
memset(buf, 0, sizeof(buf));
reclen = read(sock, buf, sizeof(buf) - 1);
if (reclen <= 0) // if host is closed ?
break;
total += reclen;
printf("%sRCV<<<%s",logtime(), buf);
printf("... len=%d... ", reclen);
printf("\n");
usleep(10);
}
printf(" total length=%d\n", total);
printf(" ... end.\n");
close(sock);
return 1;
}
UDP サーバー Linux用
simple udp server source code for testing.
指定のUDPポートを開いてUDPパケットの受信を待ちます。UDPパケットを受信したら、送信元に対してUDPパケットで応答します。簡単なUDPサーバーです。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char **argv)
{
int c;
int i;
int sock;
struct sockaddr_in addr;
char buf[1000];
char senderstr[512];
char *ips = "";
char *ipd = "0.0.0.0";
int nPort = 12345;
int nCount = 10;
int nInt = 1000;
int bReply = 0;
opterr = 0;
while(( c = getopt(argc, argv, "s:d:p:n:t:rh")) != -1)
{
switch(c)
{
case 'h':
printf(" udpr \n");
printf(" -s xxx.xxx.xxx.xxx : server IP [INETADDR_ANY]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -r : Reply packet [No-Reply]\n");
printf(" \n");
return 0;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
break;
case 'r':
bReply = 1;
break;
}
}
printf("\n udpr\n");
printf(" Src = %s, Dst = %s, Port=%d, Count=%d, Interval=%dmsec %s\n", ips, ipd, nPort, nCount, nInt, bReply ? "Reply": " No-Reply");
sock = socket(AF_INET,SOCK_DGRAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
if (strlen(ips))
addr.sin_addr.s_addr = inet_addr(ips);
else
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
{
close(sock);
printf("bind error \n");
return 0;
}
printf("--- bind port=%d \n", ntohs(addr.sin_port));
i = 0;
while (1)
{
int addrlen;
int reclen;
memset(buf, 0, sizeof(buf));
addrlen = sizeof(addr);
reclen = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&addr, &addrlen);
inet_ntop(AF_INET, &addr.sin_addr, senderstr, sizeof(senderstr));
printf("RCV<<<%s", buf);
printf("... %s %d len=%d... ", senderstr, ntohs(addr.sin_port), reclen);
printf("\n");
if (buf[0] == 'E')
break;
if (bReply)
{
sprintf(buf, "Reply %04d", i);
sendto(sock, buf, 256, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("SND>>>%s", buf);
printf("... %d\n", 256);
}
i++;
}
close(sock);
return 1;
}
指定のUDPポートを開いてUDPパケットの受信を待ちます。UDPパケットを受信したら、送信元に対してUDPパケットで応答します。簡単なUDPサーバーです。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char **argv)
{
int c;
int i;
int sock;
struct sockaddr_in addr;
char buf[1000];
char senderstr[512];
char *ips = "";
char *ipd = "0.0.0.0";
int nPort = 12345;
int nCount = 10;
int nInt = 1000;
int bReply = 0;
opterr = 0;
while(( c = getopt(argc, argv, "s:d:p:n:t:rh")) != -1)
{
switch(c)
{
case 'h':
printf(" udpr \n");
printf(" -s xxx.xxx.xxx.xxx : server IP [INETADDR_ANY]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -r : Reply packet [No-Reply]\n");
printf(" \n");
return 0;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
break;
case 'r':
bReply = 1;
break;
}
}
printf("\n udpr\n");
printf(" Src = %s, Dst = %s, Port=%d, Count=%d, Interval=%dmsec %s\n", ips, ipd, nPort, nCount, nInt, bReply ? "Reply": " No-Reply");
sock = socket(AF_INET,SOCK_DGRAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
if (strlen(ips))
addr.sin_addr.s_addr = inet_addr(ips);
else
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
{
close(sock);
printf("bind error \n");
return 0;
}
printf("--- bind port=%d \n", ntohs(addr.sin_port));
i = 0;
while (1)
{
int addrlen;
int reclen;
memset(buf, 0, sizeof(buf));
addrlen = sizeof(addr);
reclen = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&addr, &addrlen);
inet_ntop(AF_INET, &addr.sin_addr, senderstr, sizeof(senderstr));
printf("RCV<<<%s", buf);
printf("... %s %d len=%d... ", senderstr, ntohs(addr.sin_port), reclen);
printf("\n");
if (buf[0] == 'E')
break;
if (bReply)
{
sprintf(buf, "Reply %04d", i);
sendto(sock, buf, 256, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("SND>>>%s", buf);
printf("... %d\n", 256);
}
i++;
}
close(sock);
return 1;
}
UDP クライアント Linux用
simple udp client source code for testing.
簡単に言えば、固定フォーマットデータをUDPパケットとして指定のアドレス、ポートに投げるだけのプログラム。あちこちに転がっているものと同じ。
常にWiresharkでパケット内容を確認する必要があります。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int i;
int sock;
struct sockaddr_in addr;
char *ips = "0.0.0.0";
char *ipd = "0.0.0.0";
int nPort = 12345;
int nCount = 10;
int nInt = 1000;
int c;
int bWait = 0;
opterr = 0;
while(( c = getopt(argc, argv, "s:d:p:n:t:wh")) != -1)
{
switch(c)
{
case 'h':
printf(" udps \n");
printf(" -d xxx.xxx.xxx.xxx : server IP [0.0.0.0]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -n 99999 : send packet count [10]\n");
printf(" -t 9999 : interval time [1000]msec\n");
printf(" -w : wait reply data [Not-Wait]\n");
printf(" \n");
return 0;
break;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
if (nInt <= 0)
nInt = 1;
break;
case 'w':
bWait = 1;
break;
}
}
printf("\n udps\n");
printf(" Src = %s, Dst = %s, Port=%d, Count=%d, Interval=%dmsec %s\n", ips, ipd, nPort, nCount, nInt, bWait ? "Wait" : "Not-Wait");
sock = socket(AF_INET,SOCK_DGRAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
addr.sin_addr.s_addr = inet_addr(ipd);
for (i = 0; i < nCount; i++)
{
char szWk[257];
memset(szWk, i & 0x07f, sizeof(szWk));
sprintf(szWk, "H%04d", i);
sendto(sock,szWk, 256, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("SND>>>%s", szWk);
printf("... %d\n", 256);
usleep(nInt * 1000);
if (bWait)
{
char buf[1000];
int addrlen;
char senderstr[256];
int reclen;
struct sockaddr_in r_addr;
memset(buf, 0, sizeof(buf));
addrlen = sizeof(r_addr);
reclen = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&r_addr, &addrlen);
inet_ntop(AF_INET, &r_addr.sin_addr, senderstr, sizeof(senderstr));
printf("RCV<<<%s", buf);
printf("... %s %d len=%d... ", senderstr, ntohs(addr.sin_port), reclen);
printf("\n");
}
}
sendto(sock,"END", 3, 0, (struct sockaddr *)&addr, sizeof(addr));
close(sock);
return 1;
}
簡単に言えば、固定フォーマットデータをUDPパケットとして指定のアドレス、ポートに投げるだけのプログラム。あちこちに転がっているものと同じ。
常にWiresharkでパケット内容を確認する必要があります。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int i;
int sock;
struct sockaddr_in addr;
char *ips = "0.0.0.0";
char *ipd = "0.0.0.0";
int nPort = 12345;
int nCount = 10;
int nInt = 1000;
int c;
int bWait = 0;
opterr = 0;
while(( c = getopt(argc, argv, "s:d:p:n:t:wh")) != -1)
{
switch(c)
{
case 'h':
printf(" udps \n");
printf(" -d xxx.xxx.xxx.xxx : server IP [0.0.0.0]\n");
printf(" -p 9999 : server port [12345]\n");
printf(" -n 99999 : send packet count [10]\n");
printf(" -t 9999 : interval time [1000]msec\n");
printf(" -w : wait reply data [Not-Wait]\n");
printf(" \n");
return 0;
break;
case 's':
ips = optarg;
break;
case 'd':
ipd = optarg;
break;
case 'p':
printf("-p %p\n", optarg);
if (optarg)
nPort = atol(optarg);
break;
case 'n':
if (optarg)
nCount = atol(optarg);
break;
case 't':
if (optarg)
nInt = atol(optarg);
if (nInt <= 0)
nInt = 1;
break;
case 'w':
bWait = 1;
break;
}
}
printf("\n udps\n");
printf(" Src = %s, Dst = %s, Port=%d, Count=%d, Interval=%dmsec %s\n", ips, ipd, nPort, nCount, nInt, bWait ? "Wait" : "Not-Wait");
sock = socket(AF_INET,SOCK_DGRAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
addr.sin_addr.s_addr = inet_addr(ipd);
for (i = 0; i < nCount; i++)
{
char szWk[257];
memset(szWk, i & 0x07f, sizeof(szWk));
sprintf(szWk, "H%04d", i);
sendto(sock,szWk, 256, 0, (struct sockaddr *)&addr, sizeof(addr));
printf("SND>>>%s", szWk);
printf("... %d\n", 256);
usleep(nInt * 1000);
if (bWait)
{
char buf[1000];
int addrlen;
char senderstr[256];
int reclen;
struct sockaddr_in r_addr;
memset(buf, 0, sizeof(buf));
addrlen = sizeof(r_addr);
reclen = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&r_addr, &addrlen);
inet_ntop(AF_INET, &r_addr.sin_addr, senderstr, sizeof(senderstr));
printf("RCV<<<%s", buf);
printf("... %s %d len=%d... ", senderstr, ntohs(addr.sin_port), reclen);
printf("\n");
}
}
sendto(sock,"END", 3, 0, (struct sockaddr *)&addr, sizeof(addr));
close(sock);
return 1;
}
はじめまして。
今更ながら、自作のツール(ゴミプロ)を保存しておくためのブログです。Evernoteにも書込んでいるのですが、shareするのがいちいち面倒なためにここを使います。
個人的なメモですので、ここで示された内容を元に何かしらの操作を行う場合、それは全て自己責任でお願いいたします。無闇にマネしないで下さい。また無闇にプログラムを実行しないでください。責任はとれません。
個人的なメモですので、ここで示された内容を元に何かしらの操作を行う場合、それは全て自己責任でお願いいたします。無闇にマネしないで下さい。また無闇にプログラムを実行しないでください。責任はとれません。
登録:
投稿 (Atom)