MES3.0はLinuxの下位互換性であり、MES3.0のユーザープログラムは原則としてLinuxでも同じソースコードで動作します。
以下、MES3.0で動作確認されたLinuxとソースコード互換のICMPパケット送受信(ping)の例です。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <time.h>
#include <netdb.h>
static unsigned short ping_checksum(unsigned short *buf, int bufsz) {
unsigned long sum = 0;
while(bufsz > 1) {
sum += *buf;
buf++;
bufsz -= 2;
}
if(bufsz == 1) {
sum += *(unsigned char *)buf;
}
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
return ~sum;
}
#define PING_TIMOUT 7
int main(int argc, char *argv[]) {
static char buf[ETHER_MAX_LEN];
int sock, i, count, size, j, stat, ret;
int n, addrlen, maxsiz, alen;
char *ptr;
time_t t;
struct icmphdr hdr;
struct sockaddr_in addr, saddr;
struct icmphdr *icmphdrptr;
struct iphdr *iphdrptr;
struct timeval tv;
struct hostent *hp;
size = 56;
count = 6;
ret = -1;
for(i = 1;i < argc;i++) {
if(argv[i][0] == '-') {
if((i + 1) >= argc) {
break;
} else {
if(argv[i][1] == 's') {
size = atoi(argv[i + 1]);
} else if(argv[i][1] == 'c') {
count = atoi(argv[i + 1]);
} else {
break;
}
i++;
}
} else {
if((hp = gethostbyname(argv[i])) == NULL) break;
bcopy(hp->h_addr_list[0], &(addr.sin_addr), hp->h_length);
ret = 0;
}
}
if(ret == -1) {
printf("usage : %s [ -c COUNT -s SIZE ] IPADDR\n", argv[0]);
return -1;
}
maxsiz = 548 - sizeof(struct iphdr) - sizeof(struct icmphdr);
if(count > maxsiz) count = maxsiz;
addr.sin_family = AF_INET;
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0) {
printf("socket error\n");
return -1;
}
tv.tv_sec = PING_TIMOUT;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
iphdrptr = (struct iphdr *)buf;
icmphdrptr = (struct icmphdr *)&(buf[sizeof(struct iphdr)]);
for(i = 0;i < count;i++) {
memset(&hdr, 0, sizeof(hdr));
hdr.type = ICMP_ECHO;
hdr.code = 0;
hdr.checksum = 0;
hdr.un.echo.id = htons(100);
hdr.un.echo.sequence = htons(i + 1);
memcpy(buf, (char*)&hdr, sizeof(hdr));
ptr = &(buf[sizeof(hdr)]);
for(j = 0;j < size;j++) ptr[j] = j + 0x10;
hdr.checksum = ping_checksum((unsigned short*)buf, sizeof(hdr) + size);
memcpy(buf, (char*)&hdr, sizeof(hdr));
t = time(NULL);
n = sendto(sock, buf, sizeof(hdr) + size, 0, (struct sockaddr *)&addr, sizeof(addr));
if (n < 1) {
printf("sendto error.\n");
break;
}
for(;;) {
if(time(NULL) > t + PING_TIMOUT) {
printf("recv error.\n");
break;
}
n = recv(sock, buf, sizeof(buf), 0);
if(n < 1) {
printf("recv error.\n");
break;
} else {
if(iphdrptr->protocol == IPPROTO_ICMP &&
iphdrptr->saddr == addr.sin_addr.s_addr &&
hdr.un.echo.id == icmphdrptr->un.echo.id &&
hdr.un.echo.sequence == icmphdrptr->un.echo.sequence) {
printf("%d bytes from %s: icmp_seq=%d ttl=%d\n",
(int)(ntohs(iphdrptr->tot_len) - sizeof(struct iphdr)),
inet_ntoa(addr.sin_addr),
ntohs(hdr.un.echo.sequence), iphdrptr->ttl);
break;
}
}
}
fflush(stdout);
sleep(1);
}
close(sock);
return 0;
}