質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

FreeBSD

FreeBSDは、Unix系のオープンソースのOSです。PC/AT互換機用ですが、他のプラットフォームにも移植されています。優れたネットワーク・セキュリティ・ストレージ機能で人気のOSです。ソースコードと共に無償で公開されており、多くの コミュニティによって長年に渡って開発されています。

Q&A

解決済

1回答

1356閲覧

bind()の引数が無効であるというエラーについて

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

FreeBSD

FreeBSDは、Unix系のオープンソースのOSです。PC/AT互換機用ですが、他のプラットフォームにも移植されています。優れたネットワーク・セキュリティ・ストレージ機能で人気のOSです。ソースコードと共に無償で公開されており、多くの コミュニティによって長年に渡って開発されています。

0グッド

1クリップ

投稿2018/01/22 07:06

編集2018/01/22 07:11

「ルータ自作でわかるパケットの流れ」小俣光之著を参考にパケットキャプチャを作成しています。この本ではLinux(CentOS 5.5)を使用しているみたいなのですが、私はFreeBSDを用いています。そのため、変更箇所が多数あり、やっとエラーメッセージが出なくなり実行する段階まで進みました。
ソースコードは以下の4つありますが、ここではpcap.c、analyze.c、print.cの3つを掲載します。また、字数の関係で、この質問に無関係な関数等は端折って掲載します。
・pcap.c(キャプチャのメイン処理)
・analyze.c(パケットを解析する)
・print.c(内容表用関数を記述)
・checksum.c(チェックサムをチェックする)

C

1/* pcap.c */ 2int InitRawSocket(char *device, int promiscFlag, int ipOnly) 3{ 4struct ifreq ifreq; 5struct sockaddr_ll sa; 6int soc; 7 if(ipOnly){ 8 if((soc=socket(AF_INET6,SOCK_RAW,ETHERTYPE_IP)) < 0){ 9 perror("socket"); 10 return(-1); 11 } 12 } 13 else{ 14 if((soc=socket(AF_INET6,SOCK_RAW,0)) < 0){ 15 perror("socket"); 16 return(-1); 17 } 18 } 19 20 memset(&ifreq,0,sizeof(struct ifreq)); 21 strncpy(ifreq.ifr_name,device,sizeof(ifreq.ifr_name)-1); 22 if(ioctl(soc,SIOCGIFINDEX,&ifreq) < 0){ 23 perror("ioctl"); 24 close(soc); 25 return(-1); 26 } 27 sa.sll_protocol=0; 28 if(ipOnly){ 29 sa.sll_protocol=ETHERTYPE_IP; 30 } 31 else{ 32 sa.sll_protocol=0; 33 } 34 sa.sll_ifindex=ifreq.ifr_index; 35 if(bind(soc,(struct sockaddr *)&sa,sizeof(sa)) < 0){ 36 perror("bind"); 37 close(soc); 38 return(-1); 39 } 40 41 if(promiscFlag){ 42 if(ioctl(soc,SIOCGIFFLAGS,&ifreq) < 0){ 43 perror("ioctl"); 44 close(soc); 45 return(-1); 46} 47 ifreq.ifr_flags=ifreq.ifr_flags|IFF_PROMISC; 48 if(ioctl(soc,SIOCSIFFLAGS,&ifreq) < 0){ 49 perror("ioctl"); 50 close(soc); 51 return(-1); 52 } 53 } 54 return(soc); 55} 56 57int main(int argc,char *argv[],char *envp[]) 58{ 59int soc,size; 60u_char buf[65535]; 61 62 if(argc <= 1){ 63 fprintf(stderr,"pcap device-name\n"); 64 return(1); 65 } 66 67 if((soc=InitRawSocket(argv[1],0,0)) == -1){ 68 fprintf(stderr,"InitRawSocket:error:%s\n",argv[1]); 69 return(-1); 70 } 71 72 while(1){ 73 if((size=read(soc,buf,sizeof(buf))) <= 0){ 74 perror("read"); 75 }else{ 76 AnalyzePacket(buf,size); 77 } 78 } 79 close(soc); 80 return(0); 81} 82

C

1/* analyze.c */ 2#ifndef ETHERTYPE_IPV6 3#define ETHERTYPE_IPV6 0x86dd 4#endif 5 6int AnalyzePacket(u_char *data,int size) 7{ 8u_char *ptr; 9int lest; 10struct ether_header *eh; 11 12 ptr=data; 13 lest=size; 14 15 if(lest<sizeof(struct ether_header)){ 16 fprintf(stderr,"lest(%d)<sizeof(struct ether_header)\n",lest); 17 return(-1); 18 } 19 eh=(struct ether_header *)ptr; 20 ptr+=sizeof(struct ether_header); 21 lest-=sizeof(struct ether_header); 22 23 if(ntohs(eh->ether_type) == ETHERTYPE_ARP){ 24 fprintf(stderr,"Packet[%dbytes]\n",size); 25 PrintEtherHeader(eh,stdout); 26 AnalyzeArp(ptr,lest); 27 }else if(ntohs(eh->ether_type) == ETHERTYPE_IP){ 28 fprintf(stderr,"Packet[%dbytes]\n",size); 29 PrintEtherHeader(eh,stdout); 30 AnalyzeIp(ptr,lest); 31 }else if(ntohs(eh->ether_type) == ETHERTYPE_IPV6){ 32 fprintf(stderr,"Packet[%dbytes]\n",size); 33 PrintEtherHeader(eh,stdout); 34 AnalyzeIpv6(ptr,lest); 35 } 36 return(0); 37}

C

1/* print.c */ 2#ifndef ETHERTYPE_IPV6 3#define ETHERTYPE_IPV6 0x86dd 4#endif 5 6char *my_ether_ntoa_r(u_char *hwaddr,char *buf,socklen_t size) 7{ 8 snprintf(buf,size,"%02x:%02x:%02x:%02x:%02x:%02x",hwaddr[0],hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]); 9 return(buf); 10} 11 12char *arp_ip2str(uint8_t *ip,char *buf,socklen_t size) 13{ 14 snprintf(buf,size,"%u.%u.%u.%u",ip[0],ip[1],ip[2],ip[3]); 15 return(buf); 16} 17 18char *ip_ip2str(uint32_t ip,char *buf,socklen_t size) 19{ 20struct in_addr *addr; 21 22 addr = (struct in_addr *)&ip; 23 inet_ntop(AF_INET,addr,buf,size); 24 25 return(buf); 26} 27 28int PrintEtherHeader(struct ether_header *eh,FILE *fp) 29{ 30char buf[80]; 31 fprintf(fp,"ether_header *------------------------------\n"); 32 fprintf(fp,"ether_dhost=%s\n",my_ether_ntoa_r(eh->ether_dhost,buf,sizeof(buf))); 33 fprintf(fp,"ether_shost=%s\n",my_ether_ntoa_r(eh->ether_shost,buf,sizeof(buf))); 34 fprintf(fp,"ether_type=%02X",ntohs(eh->ether_type)); 35 switch(ntohs(eh->ether_type)){ 36 case ETHERTYPE_IP: 37 fprintf(fp,"(IP)\n"); 38 break; 39 case ETHERTYPE_IPV6: 40 fprintf(fp,"(IPv6)\n"); 41 break; 42 case ETHERTYPE_ARP: 43 fprintf(fp,"(ARP)\n"); 44 break; 45 default: 46 fprintf(fp,"(unknown)\n"); 47 break; 48 } 49 50 return(0); 51} 52 53int PrintArp(struct ether_arp *arp,FILE *fp) 54{ 55static char *hrd[]={ 56 "From KA9Q: NET/ROM pseudo", 57 "Ethernet 10/100Mbps.", 58 "Experimental Ethernet.", 59 "AX.25 Level 2.", 60 "PROnet token ring.", 61 "Chaosnet.", 62 "IEEE 802.2 Ethernet/TR/TB.", 63 "ARCnet.", 64 "APPLEtalk.", 65 "undefine", 66 "undefine", 67 "undefine", 68 "undefine", 69 "undefine", 70 "undefine", 71 "Frame Relay DLCI.", 72 "undefine", 73 "undefine", 74 "undefine", 75 "ATM.", 76 "undefine", 77 "undefine", 78 "undefine", 79 "Metricom STRIP (new IANA id)." 80}; 81 82static char *op[]={ 83 "undefined", 84 "ARP request.", 85 "ARP reply.", 86 "RARP request.", 87 "RARP reply.", 88 "undefined", 89 "undefined", 90 "undefined", 91 "Metricom STRIP (new IANA id)" 92}; 93 94char buf[80]; 95 96 fprintf(fp,"arp------------------------------\n"); 97 fprintf(fp,"arp_hrd=%u",ntohs(arp->arp_hrd)); 98 if(ntohs(arp->arp_hrd)<=23){ 99 fprintf(fp,"(%s),",hrd[ntohs(arp->arp_hrd)]); 100 } 101 else{ 102 fprintf(fp,"(undefined),"); 103 } 104 fprintf(fp,"arp_pro=%u",ntohs(arp->arp_pro)); 105 switch(ntohs(arp->arp_pro)){ 106 case ETHERTYPE_IP: 107 fprintf(fp,"(IP)\n"); 108 break; 109 case ETHERTYPE_ARP: 110 fprintf(fp,"(Address resolution)\n"); 111 break; 112 case ETHERTYPE_REVARP: 113 fprintf(fp,"(Reverse ARP)\n"); 114 break; 115 case ETHERTYPE_IPV6: 116 fprintf(fp,"(IPv6)\n"); 117 break; 118 default: 119 fprintf(fp,"(unknown)\n"); 120 break; 121 } 122 fprintf(fp,"arp_hln=%u,",arp->arp_hln); 123 fprintf(fp,"arp_pln=%u,",arp->arp_pln); 124 fprintf(fp,"arp_op=%u",ntohs(arp->arp_op)); 125 if(ntohs(arp->arp_op)<=10){ 126 fprintf(fp,"(%s)\n",op[ntohs(arp->arp_op)]); 127 } 128 else{ 129 fprintf(fp,"(undefine)\n"); 130 } 131 fprintf(fp,"arp_sha=%s\n", 132               my_ether_ntoa_r(arp->arp_sha,buf,sizeof(buf))); 133 fprintf(fp,"arp_spa=%s\n",arp_ip2str(arp->arp_spa,buf,sizeof(buf))); 134 fprintf(fp,"arp_tha=%s\n", 135               my_ether_ntoa_r(arp->arp_tha,buf,sizeof(buf))); 136 fprintf(fp,"arp_tpa=%s\n",arp_ip2str(arp->arp_tpa,buf,sizeof(buf))); 137 return(0); 138} 139 140int PrintIpHeader(struct ip *iphdr,u_char *option,int optionLen,FILE *fp) 141{ 142int i; 143char buf[80]; 144 145 fprintf(fp,"ip------------------------------\n"); 146 fprintf(fp,"version=%u,",iphdr->ip_v); 147 fprintf(fp,"ihl=%u,",iphdr->ip_hl); 148 fprintf(fp,"tos=%x,",ntohs(iphdr->ip_tos)); 149 fprintf(fp,"tot_len=%u,",ntohs(iphdr->ip_len)); 150 fprintf(fp,"id=%u\n",ntohs(iphdr->ip_id)); 151 fprintf(fp,"frag_off=%x,%u,", 152        (ntohs(iphdr->ip_off)>>13)&0x07,ntohs(iphdr->ip_off)&0x1FFF); 153 fprintf(fp,"ttl=%u,",iphdr->ip_ttl); 154 fprintf(fp,"protocol=%u",iphdr->ip_p); 155 if(iphdr->ip_p<=17){ 156 fprintf(fp,"(%s),",Proto[iphdr->ip_p]); 157 } 158 else{ 159 fprintf(fp,"(undefined),"); 160 } 161 fprintf(fp,"check=%x\n",iphdr->ip_sum); 162 fprintf(fp,"SourceAddress=%s,", 163             ip_ip2str(iphdr->ip_src.s_addr,buf,sizeof(buf))); 164 fprintf(fp,"DesrAddress=%s\n", 165             ip_ip2str(iphdr->ip_dst.s_addr,buf,sizeof(buf))); 166 if(optionLen>0){ 167 fprintf(fp,"option:"); 168 for(i=0;i<optionLen;i++){ 169 if(i!=0){ 170 fprintf(fp,":%02x",option[i]); 171 } 172 else{ 173 fprintf(fp,"%02x",option[i]); 174 } 175 } 176 } 177 178 return(0); 179}

そして現在プログラムを実行した結果が以下のようになっています。

% ./pcap em0
bind: Invalid argument
InitRawSocket:error:em0

pcap.cファイルのInitRawSocket()関数内でsocket()関数を使用している箇所があるのですが、元は第1引数に'PF_PACKET'と指定されていたのですが、FreeBSDでは定義されていなかったため、とりあえず'AF_INET6'に変更しました。ここが原因であるかは不明ですが、もし違っていればご指摘願います。
その他諸々、間違い箇所があれば一緒にご指摘宜しくお願いいたします。

※checksum.cはあまり関係ないかなと思い、省略しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

c

1struct ifreq ifreq; 2struct sockaddr_ll sa; 3int soc; 4 if(ipOnly){ 5 if((soc=socket(AF_INET6,SOCK_RAW,ETHERTYPE_IP)) < 0){ 6 perror("socket"); 7 return(-1); 8 } 9 } 10 else{ 11 if((soc=socket(AF_INET6,SOCK_RAW,0)) < 0){ 12 perror("socket"); 13 return(-1); 14 } 15 }

 で「AF_INET6」を使用するのは IPv6 です。
IPv6 を使用するのであれば sockaddr_ll も sockaddr_in6 になるかと思います。

 とりあえずは AF_INET6 は間違いと思われます。

/usr/include/pcap

 というディレクトリがありますので、その下の .h を熟読されてはいかがでしょうか。

補足)
下記のページに Linux と BSD の違いについての記載があります。
BSD 系では socket ではなくopen、read、write を使うようです。

BPFとLinuxでのL2インターフェースを扱うネットワークプログラミングでの違いについて

投稿2018/01/22 08:04

編集2018/01/22 23:30
showkit

総合スコア1638

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/01/22 12:44 編集

回答ありがとうございます。 質問なのですが、Linuxで使用される’PF_PACKET’と同じような働きをするものはFreeBSDでは存在しないのでしょうか? ディレクトリの方、参考にして見たいと思います!教えていただきありがとうございます。
showkit

2018/01/22 23:30

参考になりそうなサイトを補足で書いておきました。
退会済みユーザー

退会済みユーザー

2018/01/23 02:05

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問