MES3.0はLinuxの下位互換性であり、MES3.0のユーザープログラムは原則としてLinuxでも同じソースコードで動作します。
以下、MES3.0で動作確認されたLinuxとソースコード互換のEthernetパケット受信の例です。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <net/if.h>
static char buff[ETHER_MAX_LEN];
int main(int argc, char **argv) {
struct ether_header *ether;
struct iphdr *ip;
struct ifreq ifr;
struct sockaddr_ll sa;
char smac[20], dmac[20];
char sip[16], dip[16];
int sockfd, len, proto, i, ret;
unsigned int saddr, daddr, ipsize;
char adrbuf[INET_ADDRSTRLEN + 1];
if(argc != 2) {
printf("Usage : %s dev\r", argv[0]);
return -1;
}
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if(sockfd < 0) {
printf("socket error\r");
return -1;
}
memset(&ifr, 0, sizeof(struct ifreq));
strcpy(ifr.ifr_name, argv[1]);
ret = ioctl(sockfd, SIOCGIFINDEX, &ifr);
if(ret < 0) printf("ioctl error\r");
memset(&sa, 0, sizeof(struct sockaddr_ll));
sa.sll_family = AF_PACKET;
sa.sll_halen = ETH_ALEN;
sa.sll_ifindex = ifr.ifr_ifindex;
bind(sockfd, (struct sockaddr *)&sa, sizeof(struct sockaddr_ll));
for(;;) {
len = recv(sockfd, buff, sizeof(buff), 0);
if(len < 0){
printf("recv error\r");
break;
}
ether = (struct ether_header *)buff;
for(i = 0;i < 6;i++) {
printf("%02x", ether->ether_shost[i]);
if(i < 5) putchar(':');
}
printf(" --> ");
for(i = 0;i < 6;i++) {
printf("%02x", ether->ether_dhost[i]);
if(i < 5) putchar(':');
}
printf(" (%d byte)\r", len);
proto = ntohs(ether->ether_type);
switch(proto) {
case ETHERTYPE_IP:
ip = (struct iphdr *)(buff + sizeof(struct ether_header));
saddr = ip->saddr;
daddr = ip->daddr;
ipsize = ntohs(ip->tot_len);
inet_ntop(AF_INET, &saddr, adrbuf, INET_ADDRSTRLEN);
printf("%s --> ", adrbuf);
inet_ntop(AF_INET, &daddr, adrbuf, INET_ADDRSTRLEN);
printf("%s (%d byte)\r", adrbuf, ipsize);
break;
case ETHERTYPE_ARP:
printf("ARP\r");
break;
case ETHERTYPE_REVARP:
printf("Reverse ARP\r");
break;
default:
printf("other protocol\r");
break;
}
for(i = 0;i < len;i++) {
if((i % 16) == 0) printf("%04x : ", i);
printf("%02x ", buff[i] & 0xff);
if((i % 16) == 15) putchar('\r');
}
putchar('\r');fflush(stdout);
}
close(sockfd);
return 0;
}