for文が機能せず、looplistが常にNULLになる原因を指摘してください

このQ&Aのポイント
  • プログラム内のfor文が機能せず、ループをスキップしてしまっている可能性があります。
  • looplistが常にNULLになる原因として、ループの条件記述がおかしい可能性があります。
  • 解決策として、ループの条件を正しく設定し、ループの中でのアクションを適切に行う必要があります。
回答を見る
  • ベストアンサー

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なのは何故なのか。 この二つが解決出来ればなんとか出来ると思うのですが力不足でそれに及びません。何か気が付かれた事等ありましたらご教授頂けないでしょうか。どうぞよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

ざっと見た感じですが…… ・flow_headがローカル変数なので関数呼び出しごとに初期化される ・if()の構成が間違っている(どのprintf()にも到達しないパターンがある) ・リストが構築されてない(malloc()で確保したメモリのアドレスをnextに入れる処理がない) ・追加で確保した要素のnextをNULLにしてない(このままリストに入れたら終端判定ができなくなる) ・関数脱出直前のfree(looplist)は不要というかここでやってはいけない(ヒットした要素、もしくは作ったばかりの新要素を壊してしまうことになる) とりあえずこんなところで。 ループは一回は入ってると思いますが、ステップ実行で追ってみましたか?

arlstumia
質問者

お礼

上で言った事は忘れてください・・。 助かりました。有難う御座いました。

arlstumia
質問者

補足

ご回答有難う御座います。 >・if()の構成が間違っている(どのprintf()にも到達しないパターンがある) 私の力不足でどんなパターンがあるのか予測がつきません。 お手数ですが、どんなパターンがあるのか教えて頂いてもよろしいでしょうか。if文の最後にelse文をつけているのでいずれかのprintf()には辿り着くのではと思えてしまうのですが・・。

その他の回答 (2)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

>for (looplist = &flow_head; looplist ; looplist = looplist->next) >{ ここのすぐ下でlooplistの値をprintf()で出力してみましたか? いわゆる「printfデバッグ」の基本です。

arlstumia
質問者

お礼

ご回答有難うございました。

  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.1

>for (looplist = &flow_head; looplist ; looplist = looplist->next) ・・・ ループ条件 *looplist って書いたらどうなる?

関連するQ&A

  • アドレスの比較について

    こんにちは。質問させてもらいます。 pcap.hを使って、取得したパケットの送信元アドレスと送信先アドレスを比較させて、違うアドか同じアドかを判断したいと考えています。 しかし、送信元アドレスと送信先アドレスが明らかに違うのに、同一だと判断してしまいます。原因を教えてもらえないでしょうか。 ipアドレスを格納する構造体は struct ip { struct in_addr ip_src, ip_dst; }; としました。 ↓が試した方法です。 1.inet_ntoaの値をそのまま比較 if ( inet_ntoa(ip->ip_src) == inet_ntoa(ip->ip_dst) ) { printf("\nアドレスいっしょ\n"); //↓はアドレスが違っているかどうか確認 printf("src:%s\n",inet_ntoa(ip->ip_src)); printf("dst:%s\n",inet_ntoa(ip->ip_dst)); } else { printf("\nアドレス違う\n"); } 2.strcmpを使う if ( strcmp(inet_ntoa(ip->ip_src),inet_ntoa(ip->ip_dst)) == 0) { printf("\nアドレスいっしょ\n"); printf("src:%s\n",inet_ntoa(ip->ip_src)); printf("dst:%s\n",inet_ntoa(ip->ip_dst)); } else { printf("\nアドレス違う\n"); } どちらでやってもアドレスは同じと判断してしまいます。printfで確認するときっちり違うアドが表示されるのに・・何故? きちんとアドレスを比較してくれるようにif文の中身を変えたいです。 ご助力お願いできますか。

  • ログの見方

    ルータのログに次のようなものが残っています。 これらは不正アクセスがあったということでしょうか? また、それぞれの用語がわからないのでぜひ教えてください。 ****の部分はIPアドレスです。 2001/12/01 20:14:23 Refused NATe P:6(TCP) SRC:**** DST:**** SPORT:2419 (unknown) DPORT:80 (HTTP) 2001/12/01 23:34:56 Refused NATe P:6(TCP) SRC:**** DST:****  SPORT:80 (HTTP) DPORT:63606 (unknown) 2001/12/02 00:29:47 Refused NATe P:6(TCP) SRC:**** DST:****     SPORT:1161 (unknown) DPORT:21 (FTP)

  • コンパイルエラーの原因がわからず困っています。

    こんにちわ。いつもお世話になっております。 自分で構造体を定義して、それを使ってみたのですがコンパイルエラーが出てしまいます。何がいけないのでしょうか。 以下がそのプログラムです。 struct list { struct list *prev; struct in_addr ip_src, ip_dst; u_short th_sport; u_short th_dport; struct list *next; }; void main (u_char * args, const struct pcap_pkthdr *header, const u_char * packet) { static int count = 1; const sturct list *flow; return; } 以上です。 エラー内容は test.c: In function ‘main’: test.c:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘list’ test.c:17: error: ‘list’ undeclared (first use in this function) test.c:17: error: (Each undeclared identifier is reported only once test.c:17: error: for each function it appears in.) test.c:17: error: ‘flow’ undeclared (first use in this function) 以上です。 どんな些細な意見でも構いませんので、何か気が付かれたら教えて頂けないでしょうか。どうぞよろしくお願いします。

  • 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です。

  • Firewallについて教えて!

    初めて質問させていたいただきます。 McAfeeのPersonal Firewallをインストールしています。 イベントログを見ていると「~をブロックしました」というのがたくさん表示されます。何をブロックしているのか良く解りません。 例えば自宅では   ダイヤルアップアダプタ[Unkown Traffic]は発信TCPをブロックしてい   ます:src=211,135,208,67,dst=210,145,117,90,sport=1069,dport=80(306) または   ダイヤルアップアダプタ[ICMP]は発信ICMPをブロックしてい   ます:src=211,135,208,67,dst=224,0,0,2,タイプ10(306) または   着信フラグメント:ブロック済みです 職場では   Intel〔R〕PRO/100+minipcl[Unkown Traffic]は着信UDPをブロックして   います:src=192,168,0,11,dst=192,168,0,255,sport=2869,dport=2869 (307) 質問1 これらは何を意味しているのでしょうか? 質問2 TCP,src,dst,sport,dport,UDPとは何でしょうか? 質問3 着信フラグメントとは何でしょうか? 質問4 最初の窓に「McAfee.com Personal Firewallが検出し、ブロックしたパケットは3パケットです」と表示されることがあります。これって不正アクセスですか? 質問5 ログの中のどの部分に注目していれば不正アクセスを防げますか? 以上5点、初心者の私にも解るように平易なことばでお教えいただければありがたいです。 御願いします。

  • javaのfor文が機能してないみたいなんですが・・

    javaプログラミングを始めて間もないものなんですが、for文にA~Bの文をいれるとループしなくなります。もしも、A~Bの文がなかったらループするんですが・・ A~Bの文をいれてループさせるにはどのようにすればよいのでしょうか?? String a[] = dir.list(); //dirはディレクトリ for( int i=0; i<a.length; i++ ) { File g = new File(dir,a[i]);     if( g.isDirectory() ) { System.out.println(i + ": " + a[i] + "(ディレクトリ)"); } if( g.isFile() ) { System.out.println(i + ": " + a[i] + "(ファイル)"); } File f =new File(a[i]);             //A InputStreamReader reader = new InputStreamReader (new FileInputStream (f), "jis"); BufferedReader breader = new BufferedReader (reader); OutputStreamWriter writer = new OutputStreamWriter (new FileOutputStream(t), "sjis"); BufferedWriter bwriter = new BufferedWriter(writer); int c; StringBuffer sb = new StringBuffer(); while ((c = breader.read()) != -1){ sb.append((char)c); } String mail = sb.toString(); String crlf2 = ""; int pos = mail.indexOf(crlf2) + crlf2.length(); bwriter.write (mail,pos,mail.length() -pos); bwriter.close(); breader.close();           //B }

    • ベストアンサー
    • Java
  • 文字列操作について(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)){  //別関数へ } よろしくお願い致します。

  • 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++のif文についてです。

    webカメラを使って肌色の面積を求めて、現在より1フレーム前の値と比較したいのですが、そのif文の部分がどのように書けば良いのかわかりません。 printf関数を使ってwebカメラで取得した肌色部分のピクセル数の前後を比較する場合(例えば、前のあたいより10倍以上大きかったら等)のif文の書き方をどなたかご教授お願いします。 以下ソースコードです。 #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <time.h> #include <math.h> #include <string> int hsv=0; IplImage*mask = 0; CvSeq* contour = 0; void GetMaskHSV(IplImage* src, IplImage* mask,int erosions, int dilations) { int x = 0, y = 0; uchar H, S, V; uchar minH, minS, minV, maxH, maxS, maxV; CvPixelPosition8u pos_src, pos_dst; uchar* p_src; uchar* p_dst; IplImage* tmp; tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3); cvCvtColor(src, tmp, CV_RGB2HSV); CV_INIT_PIXEL_POS(pos_src, (unsigned char*) tmp->imageData, tmp->widthStep,cvGetSize(tmp), x, y, tmp->origin); CV_INIT_PIXEL_POS(pos_dst, (unsigned char*) mask->imageData, mask->widthStep, cvGetSize(mask), x, y, mask->origin); minH = 100; maxH = 120; minS = 70; maxS = 255; minV = 70; maxV = 255; for(y = 0; y < tmp->height; y++) { for(x = 0; x < tmp->width; x++) { p_src = CV_MOVE_TO(pos_src, x, y, 3); p_dst = CV_MOVE_TO(pos_dst, x, y, 3); H = p_src[0]; S = p_src[1]; V = p_src[2]; if( minH <= H && H <= maxH && minS <= S && S <= maxS && minV <= V && V <= maxV ) { p_dst[0] = 255; p_dst[1] = 255; p_dst[2] = 255; hsv++; } else { p_dst[0] = 0; p_dst[1] = 0; p_dst[2] = 0; } } } if(erosions > 0) cvErode(mask, mask, 0, erosions); if(dilations > 0) cvDilate(mask, mask, 0, dilations); printf("%d\n",hsv); if(){}←ここのif文がわかりません cvReleaseImage(&tmp); } int _tmain(int argc, _TCHAR* argv[]) { int key; CvCapture* src; IplImage* frame; cvNamedWindow("カメラ映像表示"); src = cvCaptureFromCAM(0); if(src == NULL){ printf("映像が取得できません。\n"); cvWaitKey(0); return -1; } frame = cvQueryFrame(src); mask = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3); while(1){ frame = cvQueryFrame(src); cvShowImage("カメラ映像表示", frame); GetMaskHSV(frame,mask,1,1); cvDrawContours(frame, contour, CV_RGB (255, 255, 0), CV_RGB (0, 0, 0), 1, 1, CV_AA, cvPoint (0, 0)); key = cvWaitKey(33); if(key == 27) break; } cvDestroyWindow("カメラ映像表示"); cvReleaseCapture(&src); return 0; } 1フレーム前の値を変数に記憶して、その前の状態を記憶しておいた変数と hsv とを比較すればよいというアルゴリズムは想像できるのですが、その“1フレーム前の値”というのを、どのように表現していいかわからないのです・・

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

    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); }

専門家に質問してみよう