MES3.0はLinuxの下位互換性であり、MES3.0のユーザープログラムは原則としてLinuxでも同じソースコードで動作します。
以下、MES3.0で動作確認されたLinuxとソースコード互換のEthernetパケット送信の例です。
#include <netpacket/packet.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#define IP_ALEN 4
static char buff[sizeof(struct ether_header) + sizeof(struct arphdr) + (ETH_ALEN + IP_ALEN) * 2];
int main(int argc, char **argv) {
struct ether_header *ether;
struct arphdr *arp;
struct ifreq ifr;
struct sockaddr_in *s_in;
struct sockaddr_in addr;
struct sockaddr_ll sa;
unsigned int saddr;
int i, sock, size, len, ret;
char *smac, *dmac, *sip, *dip, mac[ETH_ALEN];
if(argc != 3) {
printf("Usage : %s dev IPaddress\n", argv[0]);
return -1;
}
inet_pton(AF_INET, argv[2], &saddr);
sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0) {
printf("socket1 error\n");
return -1;
}
strncpy(ifr.ifr_name, argv[1], IFNAMSIZ-1);
ifr.ifr_addr.sa_family = AF_INET;
ioctl(sock, SIOCGIFHWADDR, &ifr);
memcpy(mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
ioctl(sock, SIOCGIFADDR, &ifr);
s_in = (struct sockaddr_in *)&ifr.ifr_addr;
close(sock);
ether = (struct ether_header *)&(buff[0]);
arp = (struct arphdr *)(buff + sizeof(struct ether_header));
smac = buff + sizeof(struct ether_header) + sizeof(struct arphdr);
dmac = buff + sizeof(struct ether_header) + sizeof(struct arphdr) + ETH_ALEN + IP_ALEN;
sip = buff + sizeof(struct ether_header) + sizeof(struct arphdr) + ETH_ALEN;
dip = buff + sizeof(struct ether_header) + sizeof(struct arphdr) + ETH_ALEN + IP_ALEN + ETH_ALEN;
size = sizeof(buff);
memset(ether->ether_dhost, 0xff, ETH_ALEN);
memcpy(ether->ether_shost, mac, ETH_ALEN);
ether->ether_type = htons(ETHERTYPE_ARP);
arp->ar_hrd = htons(ARPHRD_ETHER);
arp->ar_pro = htons(ETHERTYPE_IP);
arp->ar_hln = ETH_ALEN;
arp->ar_pln = IP_ALEN;
arp->ar_op = htons(ARPOP_REQUEST);
memset(dmac, 0, ETH_ALEN);
memcpy(smac, mac, ETH_ALEN);
memcpy(sip, (char*)&(s_in->sin_addr.s_addr), IP_ALEN);
memcpy(dip, (char*)&saddr, IP_ALEN);
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if(sock < 0) {
printf("socket2 error\n");
return -1;
}
memset(&ifr, 0, sizeof(struct ifreq));
strcpy(ifr.ifr_name, argv[1]);
ret = ioctl(sock, SIOCGIFINDEX, &ifr);
if(ret < 0) printf("ioctl error\n");
memset(&sa, 0, sizeof(struct sockaddr_ll));
sa.sll_family = AF_PACKET;
sa.sll_halen = ETH_ALEN;
sa.sll_ifindex = ifr.ifr_ifindex;
len = sendto(sock, &buff, sizeof(buff), 0, (struct sockaddr *)&sa, sizeof(struct sockaddr_ll));
if(len <= 0) {
printf("sendto error\n");
}
close(sock);
return 0;
}