こんにちは。質問させてもらいます。
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文の中身を変えたいです。
ご助力お願いできますか。
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- …
http://www.geekpage.jp/programming/winsock/tips- …
No.4
- 回答日時:
>>inet_ntoa の戻り値を free しないのにメモリリークしないことを不思議に…
> 不思議じゃないです。
ちょっと話が難しすぎたかな・・・。
今回の質問者は、関数を呼び出したら毎回違うアドレスが返ってくる、と思ってプログラムを組んでいたわけですよね。それなら、free する責任は普通に考えて呼び出し側にあることになります。ところが自分では free してないのですから、メモリリークの可能性があることにすぐに気がつかなければなりません。
逆に、ちゃんとわかっている人なら「戻り値を返す関数が沢山あります」と言えるでしょう。こういう人は、ご指摘のように「排他処理をしないと正しく変換(取得)出来ません」というところまで、先回りして考えることができるわけです。あるべき姿ですね。
こういうベテランの人が「不思議じゃない」と思うことと、質問者が自身のプログラムを疑問に思わないことはまったくレベルが違う話です。
呼び出された関数がその内部で領域確保してくれてそのポインタを返す仕様は誤りではありませんが、呼び出した側がなにも考えずにそのポインタを捨てるのは誤り(要するに「よろしくない」)です。今回、質問者は前者の仕様だと考えて関数を呼び出し、後者のようにプログラムを組んでいるわけで、一貫性がありません。指摘されないとこの祖語に気がつかないようでは先が思いやられる、という意味です。
「サンプルなので free は省略しました」ということなら、仕様を誤って理解していますし、「free は忘れていました」ということなら、「誰が free するのか常に考えてプログラムしましょう」ということになります。どちらにしても、問題ですよね。
No.2
- 回答日時:
すでに正しい回答が出ているようですね。
inet_ntoa の戻り値が char * になっていて、呼び出し側からはリターン用のアドレスを引き渡していないことに気がつけば、こういう間違いはしないはずです。
というか、inet_ntoa の戻り値を free しないのにメモリリークしないことを不思議に思わないようでは、この先、「気分しだいで動いたり動かなかったり」のプログラムを量産することになるでしょう。この種のバグはデバッガでもなかなかとれないですよ。
これは指摘しなくても気が付いていると信じたいですが
> アドレスは同じと判断してしまいます
アドレスを比較しても文字列が等しいかどうかは判定できないと思います。
さらに余談ですが
> if ( strcmp(inet_ntoa(ip->ip_src),inet_ntoa(ip->ip_dst)) == 0)
今回はあまり関係ありませんが、この書き方だとコンパイラが変わると動作が変わるかもしれませんね。
No.1
- 回答日時:
inet_ntoa関数は内部的に持っているchar型配列の先頭ポインタを返すような
仕様になっているのではないでしょうか?
(inet_ntoaの戻り値をfreeするような記述があれば違いますが。)
となると当然どんな引数を与えても同じ値が返ってきてしまいます。
また、strcmpを使う場合必ず同じになってしまうでしょう。
よって、戻り値の値をそのまま比較せず、一度char型配列に格納してから
strcmpで比較するようにすれば良いでしょう。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 固定IP スマホやPCのIPアドレスについて教えてください。 5 2023/07/07 19:53
- VPN 接続のたびにIPが変わるVPNサービスが知りたい 2 2022/06/27 02:34
- Wi-Fi・無線LAN 無線ルーターのIPアドレスは、iPhoneのように簡単に変更できる??? 2 2022/04/02 19:00
- ネットワーク 外部からローカルIPアドレスはわかる? 3 2022/07/05 00:53
- SoftBank(ソフトバンク) スマホ ipアドレス 4 2022/08/24 01:26
- ネットワーク 一台のサーバーに複数個のIPアドレスを追加出来る事は知っていますが、具体的にどうやるのでしょうか? 4 2022/11/03 20:12
- Wi-Fi・無線LAN iPhoneのIPアドレスは機内モードをオンで変わるように、無線ルーターも何かの方法で変更できる? 2 2022/04/02 14:37
- Windows 10 インストールしたてのVirtualBoxの仮想マシンにDHCPで割り振られるIPアドレスにつきまして 1 2023/05/03 14:46
- その他(プログラミング・Web制作) このプログラミング誰か教えてくれませんか 4 2022/04/29 15:56
- FTTH・光回線 グローバルIPアドレスの変更について 1 2022/04/23 05:32
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
既約分数の表示プログラム
-
10個出力で改行したいのですが...
-
printf で二進表示を行いたい。
-
Cのdoubleの浮動小数点表示につ...
-
万年カレンダーのC言語プログラ...
-
ホームページをC言語で作りたい...
-
(C言語)西暦年月日を入力して...
-
コマンドラインに出力した文字...
-
質問ですが
-
4の倍数を論理演算で表す。。
-
printfの出力内の文字をdefine...
-
C言語 プログラミング
-
strcmp
-
C言語での、年複利の計算方法...
-
コンパイルエラーについて
-
アドレスの比較について
-
入力したお金の金額からお札の...
-
3つの整数を画面から入力して...
-
C言語について
-
プログラミング言語C
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語について
-
printf で二進表示を行いたい。
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
テキストカーソル位置の取得
-
strcmp
-
unsigned int型について
-
c言語でAからZまでを表示する...
-
printf( " %2d", p * q );
-
コマンドラインに出力した文字...
-
printfの出力内の文字をdefine...
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
小数点切捨て表示
-
【C言語教えてください】sin波...
-
switch分のケースを範囲数?に...
-
二つの整数値の大小比較
-
4の倍数を論理演算で表す。。
-
defineで定数が置き換えられな...
おすすめ情報