• ベストアンサー

アドレスの比較について

Oh-Orangeの回答

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★アドアイス >inet_ntoa の戻り値を free しないのにメモリリークしないことを不思議に…  ↑  不思議じゃないです。  C言語の標準関数でも内部に static なバッファを使って  戻り値を返す関数が沢山あります。  (strtok、gmtimeなどなど) 正しいサンプル: char srcBuff[ 32 ]; char dstBuff[ 32 ]; strcpy( srcBuff, inet_ntoa(ip->ip_src) ); strcpy( dstBuff, inet_ntoa(ip->ip_dst) ); if ( !strcmp(srcBuff,dstBuff) ){  printf("\nアドレスいっしょ\n");  //↓はアドレスが違っているかどうか確認  printf("src:%s\n", srcBuff );  printf("dst:%s\n", dstBuff ); } else{  printf("\nアドレス違う\n"); } 注意事項: マルチスレッド内で inet_ntoa のような関数を 複数のスレッドから呼び出すときには排他処理を行って下さい。 排他処理をしないと正しく変換(取得)出来ません。 今回の質問は良くある間違いです。 今後、staticな戻り値に注意しましょう。 http://www.geekpage.jp/programming/winsock/tips-inet_ntoa.php http://www.geekpage.jp/programming/winsock/tips-gethostbyname.php

mandly
質問者

お礼

ご回答有難う御座います。 分かりやすいサンプルを添えて頂いた事感謝します。 末尾のサイトも有難く参考にさせて頂きます。

関連するQ&A

  • IPアドレスを配列に代入する方法。

    パケットモニタリング(tcpdumpみたいなもの)でIPアドレスを取得するプログラムがあるのですが、IPアドレスを配列に代入することが出来ません。 パケットモニタリングのソース void print_ip(struct ip *ip) { printf("| Source IP Address: %15s|\n", inet_ntoa(*(struct in_addr *) &(ip->ip_src))); /* ループ */ 実行画面 | Source IP Address: 12.34.56.78 | | Source IP Address: 34.56.78.09 | ・ ・ というふうにどんどん取得、表示していく このIPアドレス inet_ntoa(*(struct in_addr *) &(ip->ip_src))); を配列に代入していきたいのですが上手くいきません。一応自分でやってみたのですが、 void print_ip(struct ip *ip) { int *pa[2048]; static int i = 1; printf("| Source IP Address: %15s|\n", inet_ntoa(*(struct in_addr *) &(ip->ip_src))); i++; pa[i] = (int *)&(ip->ip_src); printf("送信先[%d]%15s\n", i, inet_ntoa(*(struct in_addr *) pa[i])); if (i == 10) { for (i = 1; i < 10; i++) { printf("送信先[%d]%15s\n", i, inet_ntoa(*(struct in_addr *) pa[i])); }} } という風にaddres[1]から順にどんどんIPアドレスを格納しようとしたんですがaddres[1]からaddres[10]まで表示するときに全部addres[10]に代入されているIPアドレスが表示されてしまいます。 おそらく配列にIPアドレスが上手く格納できてないんだと思うのですが。C言語初心者なので誰かご教授していただけないでしょうか? 宜しくお願いします。 OSはLinuxです。

  • for文が機能しません。どなたか原因を指摘して頂けますか。

    こんにちは。質問させて頂きます。 pcap.hで、「リスト構造に格納された送受ID・ポート」と、「キャプチャされたパケットの送受ID・ポート」を順に比較していって、同じであれば同一の通信フローとみなす、といったプログラムを作っています。 しかし、何故かfor文自体が機能せず、for文の中のprintf文が全く表示されないところをみると、for文をスルーしてしまっているようです。for文の中身の記述がおかしいのか、条件記述がおかしいのかのどちらかだとは思うのですが特定できません。 皆さんのお力をお貸し頂けないでしょうか。 以下がプログラムの一部です。 //ID・ポートを含んだリスト構造体作成 struct list { struct in_addr src, dst; u_short sport; u_short dport; struct list *next; }; //キャプチャされるパケットのID・ポート情報を記録する構造体 struct new_capture { struct in_addr new_src, new_dst; u_short new_sport; u_short new_dport; }; ループバック関数(){ //キャプチャされたパケット情報を構造体に写す struct new_capture nc; nc.new_dport = tcp->th_dport; nc.new_sport = tcp->th_sport; nc.new_src = ip->ip_src; nc.new_dst = ip->ip_dst; //リスト構造体の先頭と、ループさせるためのポインタを宣言 struct list flow_head; struct list *looplist; //問題のfor文 //looplistを利用して、キャプチャされたパケット情報と //リスト構造体に格納された情報とを比較する //同一ならばそれでbreak、全ての構造体と相違ならば //構造体の末端に新たに追加する for (looplist = &flow_head; looplist ; looplist = looplist->next) { if (inet_ntoa(looplist->src) == inet_ntoa(nc.new_src)) { if (inet_ntoa(looplist->dst) == inet_ntoa(nc.new_dst)) { if (looplist->sport == nc.new_sport) { if (looplist->dport == nc.new_dport) { printf ("送受アド、送受ポート同一"); break; } } } } else if (looplist->sport == nc.new_dport) { if (looplist->dport == nc.new_sport) { if (inet_ntoa(looplist->dst) == inet_ntoa(nc.new_src)) { if (inet_ntoa(looplist->src) == inet_ntoa(nc.new_dst)) { printf ("送受アド、送受ポート同一逆順"); break; } } } } else { printf ("同一ではない"); } } //通信フロー数を1増やし、リスト構造体にIDとポートを追加する if (looplist == NULL) { flow_counts++; printf ("通信フロー追加:%d\n", flow_counts); looplist = (struct list *) malloc (sizeof (struct list));   looplist->dport = nc.new_dport; looplist->sport = nc.new_sport; looplist->src = nc.new_src; looplist->dst = nc.new_dst; } free(looplist); return; } 上のlooplistにアドレスを代入しているはずなのに、ずぅ~っとNULLになっているらしく、for文が終わった後のif文が常に機能するようになってしまっています。 for文が機能しないのは何故なのか。 looplistがずっとNULLなのは何故なのか。 この二つが解決出来ればなんとか出来ると思うのですが力不足でそれに及びません。何か気が付かれた事等ありましたらご教授頂けないでしょうか。どうぞよろしくお願いします。

  • getaddrinf()で取得したIPアドレス表示

    お世話になります。 C言語でソケット通信の勉強中です。 CentOS6.4を使っています。 LIST1は、 IPアドレスではなくホスト名がコマンド引数で渡されたとき、 getaddrinfo()でIPアドレスを取得して、 sendto()でサーバにメッセージを送信するだけの、 クライアントのプログラムです。 このLIST1のudp通信自体は上手くいくのですが、 終わりの方で、 getaddrinfo()で取得したIPアドレスを inet_ntoa()を使って文字列表示しようとすると、 セグメンテーション違反です (コアダンプ)となってしまいます。 inet_ntoa()の引数が疑わしく、 いろいろ渡し方を変えたり、参照方法を変えたりしてみたのですが、、 なかなか解決しません。 ちゃんと、192.168.12.1とか表示するにはどうすれば良いでしょうか? ■LIST1 #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <errno.h> int main(int argc,char *argv[]){ int sock; struct addrinfo hints,*res; int n; int err; if(argc != 2){ fprintf(stderr,"Usage : %s dst \n",argv[0]); return 1; } /* IP アドレス表記+ホスト名両方に対応 */ memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; /* IPV4 IPV6 両方に対応 */ hints.ai_socktype = SOCK_DGRAM; err = getaddrinfo(argv[1],"12345",&hints,&res); if(err != 0){ perror("getaddrinfo"); printf("getaddrinfo %s\n",strerror(errno)); printf("getaddrinfo : %s \n",gai_strerror(err)); return 1; } sock = socket(res->ai_family,res->ai_socktype,0); if(sock < 0){ perror("socket"); return 1; } { const char *ipverstr; switch (res->ai_family){ case AF_INET: ipverstr = "IPv4"; break; case AF_INET6: ipverstr = "IPv6"; break; default: ipverstr = "unknown"; break; } printf("ipverstr = %s\n ",ipverstr); } n = sendto(sock,"HELLO",5,0,res->ai_addr,res->ai_addrlen); //n = sendto(sock,"HELLO", 5, 0,(struct sockaddr *)addr, sizeof(addr)); if(n<1){ perror("sendto"); { } return 1; } printf("############ finish !! #######\n"); close(sock); freeaddrinfo(res); struct sockaddr_in *addr; addr = (struct sockaddr_in *)res->ai_addr; printf("inet_ntoa(in_addr)sin = %s\n",inet_ntoa((struct in_addr)addr->sin_addr)); return 0; }

  • セグメンテーション違反

    C言語でネットワークを流れるパケットの取得&解析を行っているのですが、実行時にセグメンテーション違反と出てしまい、困っています。デバッグオプションをつけてやってみたところ、プログラムが中断されたところは分かったのですが、どこが悪いのか分かりません。どなたかあやしいところがありましたらお教え下さい。 OSはLinuxでコンパイラはgccです。 void udp_scanport(struct ip *ip, struct udphdr *udp) { static struct in_addr *ipaddr[1024]; static int i = -1; static int udp_count[1024]; struct in_addr *inwk; static u_short udp_port[1024]; int u = 0; int k = 0; i++; inwk = (struct in_addr *)malloc(sizeof(struct in_addr)); memcpy(inwk, &ip->ip_src, sizeof(struct in_addr)); ipaddr[i] = (struct in_addr *)inwk; printf("送信元IPアドレス:%15s\n", inet_ntoa(*(struct in_addr *) ipaddr[i])); udp_port[i] = udp->uh_dport; /*デバッグしたら中断したところ*/ printf("UDP送信先ポート番号:%15u\n", ntohs(udp_port[i])); if (i == 100) free(inwk); }

  • 文字列操作について(winsockの関数を用いています)

    こんばんは。 Winsockを用いてネットワークプログラミングを行っています。 A→Bへパケットを送信し、B側にてinet_ntoa関数(IPアドレスを文字列として表示させる関数)を用いて、以下のif文の条件を記述したのですが、if文内の条件がうまく動作しません。 デバッガを使用し、IPaddr内を見てみたところ、フフフフフフフフ……と言う文字列?が入っている状態です。 IPaddrに例えば、192.168.100.50等のIPアドレスを格納可能でしょうか? IPaddr[256] strcpy(IPaddr,inet_ntoa(from.sin_addr)); if(IPaddr == inet_ntoa(from.sin_addr)){  //別関数へ } よろしくお願い致します。

  • strcmpでIP比較

    お世話になります PHPのstrcmp()を使ってIPアドレスの比較をしているのですが、全く同じIPアドレスなのに0を返してくれません。 何故でしょうか? echo strcmp(999.99.999.999,999.99.999.999); -1が返ってきます。 宜しくお願いします。

    • ベストアンサー
    • PHP
  • IPアドレスを抽出して出力するプログラム

    下記のプログラムはIPアドレスを表示するプログラムです。for文を見てくれたら分かると思いますが、iが0~5まで繰り返し処理されるので、アドレスが5つ表示される結果になります。 このアドレスの先頭の数字(例えば「196.x.x.x」だと196)だけを見て先頭が196から始まるアドレスは表示して、先頭が196以外のアドレスは表示しないようにするにはどう書き加えればうまく実行できますか? OSはWinXPでコンパイラVC++です。 #include <stdio.h> #include <winsock2.h> #include <iphlpapi.h> int main() { DWORD i; PMIB_UDPTABLE pUdpTable; DWORD dwSize = 0; DWORD dwRetVal = 0; char *addr_ptr; if (GetUdpTable(NULL, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { pUdpTable = (MIB_UDPTABLE *) malloc (dwSize); } if ((dwRetVal = GetUdpTable(pUdpTable, &dwSize, 0)) == NO_ERROR) { if (pUdpTable->dwNumEntries > 0) { for (i=0; i<5; i++) { addr_ptr = (char *)&pUdpTable->table[i].dwLocalAddr; printf("Your Address: %s\n", inet_ntoa(*(struct in_addr *)addr_ptr)); } } } else { printf("GetUdpTable failed.\n"); LPVOID lpMsgBuf; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //Default language (LPTSTR) &lpMsgBuf, 0, NULL )) { printf("\tError: %s", lpMsgBuf); } LocalFree( lpMsgBuf ); } return 0; }

  • 文字列の並び替えについて。

    #include<stdio.h> #include<string.h> main() {char name[40][50]; int i; for(i=1;i<=;i++){ printf("名前="); gets(name[i]); } if(strcmp(name[1],name[2])>0){ printf("%s %s \n",name[2],name[1]);} if(strcmp(name[1],name[2])<0){ printf("%s %s \n",name[1],name[2]);} if(strcmp(name[1],name[2])==0){ printf("%s %s \n",name[1]);} } は二人の名前を早い順に並べ替えるものなんですが、これを五人の名前を並べ替えるものにしたいので、どのようなプログラムにしたらいいのか教えてください。

  • C言語 strcmp 半角スペースがあるとだめ?

    C言語 strcmp 半角スペースが文字列に含まれている場合 文字列の比較がうまくいきません。半角スペースがあると比較できないのでしょうか? プログラム //strcmp #include <stdio.h> #include <string.h> int main(void){ char input[256]; char str[] = "HelloWorld!";   //char str[] = "Hello World!";だとうまくいかない。 printf("%s\n>", str); scanf("%s", input); if ( strcmp(input, str) == 0){ printf("同じです。\n"); }else{ printf("違います。\n"); } return 0; }

  • プログラムが動きません。

    プログラムが動きません。 ファイルuniqipにはIPアドレスが書き込まれています。そのファイルからIPアドレスを文字列ipに格納します。 ファイルtmp4には、85.114.143.2 34f4ff4acb18802170a939ae42dcd5ee0eeccda4 のようにIPアドレスとハッシュ値が書き込まれています。 tmp4に現れるIPアドレスで、uniqipに一致するものに対応するハッシュ値を printf("file%d,%s\n",i,hash); の形で出力しようと思いましたが、うまくいきません。 何がまずいのでしょうか? #include <stdio.h> #include <string.h> //ひとつのIPアドレスに現れるユニークなハッシュ値の数をカウントする int main() { FILE *fp,*gp; char ip[269730][16]; char ip2[16]; char hash[42]; int i,j; fp = fopen("uniqip","r"); if(fp == NULL){ printf("can not open the file.\n"); return 1; } for(i=0;i<267930;i++) { fscanf(fp,"%s",ip[i]); //printf("%s\n",ip[i]); } fclose(fp); ////////////////////////////////////////////////////////////////////////////////////////////////////// gp = fopen("tmp4","r"); if(gp == NULL){ printf("can not open the file.\n"); return 1; } for(i=0;i<267930;i++){ for(j=0;j<2470766;j++){ fscanf(gp,"%s %s",ip2,hash); printf("%s\n",ip[i]); if(!strcmp(ip[i],ip2)) { printf("file%d,%s\n",i,hash); } } } return 0; }