いつもお世話になっております。
件名の事について質問があります。
現在ARPパケットを取得するプログラムを作成しています。
ARPパケットの通信を行いたいのですが上手くいきません。
上手くいきませんと言うかよく分かりません。
ネット上のサンプルを見るとC言語でARPを実現させるには
C
1if((iSock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0 ){ 2 perror("socket"); 3 exit(0); 4}
とか
C
1if((sockA = socket((AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP))) < 0 ){ 2 perror("socket"); 3 exit(0); 4}
など書かれていますが、そもそも低レイヤーを扱うAF_PACKET(PF_PACKET)の定義がどこにもありません。
自分でマクロ定義しようとしましたが AF_PACKET(PF_PACKET) の値の情報もありません。
第一引数を AF_INET にしてみましたがエラーになります。
環境
- Windows7 Professional x64
- Cygwin 2.0.1
- clang version 3.5.1
ソース
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> /* for strncpy */ 4 5#include <net/if.h> 6#include <sys/socket.h> 7#include <netinet/in.h> 8#include <arpa/inet.h> 9#include <errno.h> 10 11#include <sys/types.h> 12#include <sys/ioctl.h> 13 14#define ARPHRD_ETHER (1) /* Ethernet 10Mbps */ 15#define ETH_P_IP (0x800) 16#define ETH_P_ARP (0x0806) 17#define ETH_HLEN (6) /* MACアドレス長 */ 18#define ETH_PLEN (4) /* IPv4アドレス長 */ 19#define ARPOP_REQUEST (1) 20 21typedef unsigned char u_int8_t; // ISO C にあるらしい 22 23struct arphdr { 24 unsigned short int ar_hrd; /* Format of hardware address. */ 25 unsigned short int ar_pro; /* Format of protocol address. */ 26 unsigned char ar_hln; /* Length of hardware address. */ 27 unsigned char ar_pln; /* Length of protocol address. */ 28 unsigned short int ar_op; /* ARP opcode (command). */ 29}; 30 31struct ether_arp { 32 struct arphdr ea_hdr; /* fixed-size header */ 33 u_int8_t arp_sha[ETH_HLEN]; /* sender hardware address */// 送信元MACアドレス 34 u_int8_t arp_spa[ETH_PLEN]; /* sender protocol address */// 送信元IPアドレス 35 u_int8_t arp_tha[ETH_HLEN]; /* target hardware address */// 宛先MACアドレス( All 0 ) 36 u_int8_t arp_tpa[ETH_PLEN]; /* target protocol address */// 宛先IPアドレス(取得したIPv4アドレス) 37}; 38 39int send_arp() 40{ 41 struct ether_arp arpbody; 42 struct sockaddr_in sockaddr; 43 int arp_sock = 0; 44 long lReturn = 0; 45 struct ifreq ifr; 46 printf("send arp!!\n"); 47 48 // デバイスソケットを作成する 49// if ((arp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 50 if ((arp_sock = socket(AF_INET, SOCK_RAW, htons(ETH_P_IP))) < 0) { 51 printf("ioctl socket creation"); 52 exit(1); 53 } 54 55 ifr.ifr_addr.sa_family = AF_INET; 56 strncpy(ifr.ifr_name, "{E1205058-1BF3-4591-AA26-936B4AF08E1F}", IFNAMSIZ-1); 57 58 // 送信元MACアドレス 59 lReturn = ioctl(arp_sock, SIOCGIFHWADDR, &ifr); 60 memcpy(arpbody.arp_sha, ifr.ifr_hwaddr.sa_data, ETH_HLEN); 61 62 // 送信元プロトコルアドレス 63 lReturn = ioctl(arp_sock, SIOCGIFADDR, &ifr); 64 memcpy(&sockaddr, &(ifr.ifr_addr), sizeof(sockaddr)); 65 memcpy(arpbody.arp_spa, &(sockaddr.sin_addr), 4); 66 67 68 69 70 // 作成したソケットにread/writeして送受信する。 71 arpbody.ea_hdr.ar_hrd = htons(ARPHRD_ETHER); 72 arpbody.ea_hdr.ar_pro = htons(ETH_P_IP); /* ARP Protocol Number */ 73 74 arpbody.ea_hdr.ar_hln = ETH_HLEN; 75 arpbody.ea_hdr.ar_pln = ETH_PLEN; 76 arpbody.ea_hdr.ar_op = htons(ARPOP_REQUEST); 77 78 // 宛先MACアドレス 79 memset(arpbody.arp_tha, 0x00, ETH_HLEN); //arpbody.arp_tha 80 // 宛先IPアドレス 81 //inet_ntop(AF_INET, &tFromAddr.sin_addr, arpbody.arp_tpa, sizeof(arpbody.arp_tpa)); 82 inet_aton( "192.168.10.4", &arpbody.arp_tpa ); 83 84 85 memset(&sockaddr, 0x0, sizeof(sockaddr)); 86 sockaddr.sin_family = AF_INET; // AF_PACKET 87 sockaddr.sin_port = htons(ETH_P_ARP); 88 memset(&sockaddr.sin_addr, 0xff, ETH_HLEN); 89 90 lReturn = sendto(arp_sock, (char *)&arpbody, sizeof(arpbody), 0, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr_in)); 91 if(lReturn < 0){ 92 printf("Error! sendto %d\n", errno); 93 close(arp_sock); 94 return -1; 95 } 96 97 98 99 /* recv */ 100 while(1) { 101 char buf[256]; 102 memset(buf,0x0,sizeof(buf)); 103 int arp_size = recvfrom(arp_sock, buf, sizeof(buf), 0, NULL, NULL); 104 if(arp_size < 0) { 105 printf("errno: %d\n",errno); 106 if (errno == EAGAIN) { 107 /* まだ来ない。*/ 108 printf("MADA KONAI\n"); 109 } else { 110 perror("recv"); 111 break; 112 } 113 }else{ 114 115 /* 受信したデータはARPパケットなので、その形にキャストして情報にアクセスする */ 116 struct ether_arp *arppack = (struct ether_arp*) buf; 117 118 printf("arppack->arp_tha[0]:%x\n", arppack->arp_tha[0]); 119 printf("arppack->arp_tha[1]:%x\n", arppack->arp_tha[1]); 120 printf("arppack->arp_tha[2]:%x\n", arppack->arp_tha[2]); 121 printf("arppack->arp_tha[3]:%x\n", arppack->arp_tha[3]); 122 printf("arppack->arp_tha[4]:%x\n", arppack->arp_tha[4]); 123 printf("arppack->arp_tha[5]:%x\n", arppack->arp_tha[5]); 124 } 125 } 126 close(arp_sock); 127} 128 129 130 131 132int main(int argc, char **argv){ 133 printf("main start\n"); 134 send_arp(); 135 return 0; 136 137}
取り急ぎこんな感じのソースを書いてみましたが、ちょっと自分でももう一度推敲し直そうと思います。
質問の内容とは乖離しますが、低レイア層の通信の仕方を教えてください。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/11/17 13:30