編集部からのお知らせ
「ZDNet Japan Summit」参加登録受付中! 
新着記事集:「負荷分散」

自作PINGプログラムで特定の機器のみプログラムが止まってしまうのはなぜ?

OKWave

2007-11-19 16:00

自作PINGプログラムで特定の機器のみプログラムが止まる

はじめまして、よろしくお願いいたします。

現在私はFreeBSD6.2上でPINGを送信するプログラムを作成していますが、
特定の機器に対してPINGを送信した場合プログラムが
n = recv(sock, buf, sizeof(buf), 0);
の部分で止まってしまいます。

特定の機器とは、現在私が把握している限りではAlliedTelesisのL3スイッチに
割り当てられているIPアドレスに対してPINGを送信した場合に再現します。(CentreCOM8624XL、CentreCOM8724XL)

ためしにAlliedTelesisのL3スイッチにミラーポートを設定し、ICMPパケットを観察
しましたが、プログラムを動かしているPCからのICMPパケットが一切到達していませんでした。

ネットワークの設定に問題があるのではないかと考え、BSDに標準搭載のPINGではきちんと
AlliedTelesisのL3スイッチへのPINGが成功しているので、やはりプログラムに問題があるとしか思えません。

どうか、お力をお貸しください。

コンパイル環境
Thread model: posix
gcc version 3.4.6 [FreeBSD] 20060305

ソースコードは
http://www.geekpage.jp/programming/linux-network/simple-ping.php
よりFreeBSD上で動くように改良しました。


#include 
#include 
#include 
#include 
#include 
#include 
#include 

unsigned short int checksum(unsigned short *buf, int bufsz)
{
unsigned long int sum = 0;

while (bufsz > 1) {
sum += *buf;
buf++;
bufsz -= 2;
}

if (bufsz == 1) {
sum += *(unsigned char *)buf;
}

sum = (sum & 0xff) + (sum >> 16);
sum = (sum & 0xff) + (sum >> 16);

return ~sum;
}



int main(int argc, char *argv[])
{
int sock;
struct icmp hdr; // netinet/ip_icmp.h
struct sockaddr_in addr;
int n;

char buf[2000];
struct icmp *icmphdrptr; // netinet/ip_icmp.h
struct ip *iphdrptr; // netinet/ip.h

if (argc != 2) {
printf("usage : %s IPADDR\n", argv[0]);
return 1;
}

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);

sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0) {
perror("socket");
return 1;
}

memset(&hdr, 0, sizeof(hdr));

hdr.icmp_type = ICMP_ECHO;
hdr.icmp_code = 0;
hdr.icmp_cksum = 0;
hdr.icmp_id = 0; 
hdr.icmp_seq = 0;

hdr.icmp_cksum = checksum((unsigned short *)&hdr, sizeof(hdr));

n = sendto(sock, (char *)&hdr, sizeof(hdr), 0, (struct sockaddr *)&addr, sizeof(addr));
if (n < 1) {
perror("sendto");
}

memset(buf, 0, sizeof(buf));

n = recv(sock, buf, sizeof(buf), 0);
if (n < 1) {
perror("recv");
}

iphdrptr = (struct ip *)buf;

icmphdrptr = (struct ip *)(buf + (iphdrptr->ip_hl * 4));

if (icmphdrptr->icmp_type == ICMP_ECHOREPLY) {
printf("received ICMP ECHO REPLY\n");
} else {
printf("received ICMP %d\n", icmphdrptr->icmp_type);
}

close(sock);

return 0;
}
回答

特定の機器で応答を返したり、返さなかったりという問題はさておいて・・

checksum()で返るICMPのチェックサムの値は正しいでしょうか?
単純にチェックサムを「0xf7ff」にすると正しく応答しませんか?

#大雑把ですみません

ZDNet Japan 記事を毎朝メールでまとめ読み(登録無料)

特集

CIO

モバイル

セキュリティ

スペシャル

ホワイトペーパー

新着

ランキング

  1. クラウドコンピューティング

    Google Cloudセキュリティ基盤ガイド、設計から運用までのポイントを網羅

  2. セキュリティ

    仮想化・自動化を活用して次世代データセンターを構築したJR東日本情報システム

  3. ビジネスアプリケーション

    スモールスタート思考で業務を改善! 「社内DX」推進のためのキホンを知る

  4. セキュリティ

    Emotetへの感染を導く攻撃メールが多数報告!侵入を前提に対応するEDRの導入が有力な解決策に

  5. セキュリティ

    偽装ウイルスを見抜けず水際対策の重要性を痛感!竹中工務店が実施した2万台のPCを守る方法とは

NEWSLETTERS

エンタープライズ・コンピューティングの最前線を配信

ZDNet Japanは、CIOとITマネージャーを対象に、ビジネス課題の解決とITを活用した新たな価値創造を支援します。
ITビジネス全般については、CNET Japanをご覧ください。

このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]