|
to 68userさん さっそくですが、IPv6 のアドレス省略について 双方のプログラム(resolver-1.pl, 1058.txt)に バグがあるかも知れないのでご報告します。 一例として、 198.41.0.4 www.yahoo.co.jpと入力して、 {A, B, C, D, E, F}.DNS.jpを表示させたとき、 追加情報の F.DNS.jp の出力結果は下記のとおりになります。 resolver-1.pl 2001:2F8::100::153 私の出力結果 2001:2f8::100:0:0:0:153 ちなみにEtherealの出力結果は下記のとおりです。 2001:2f8:0:100::153 IPv6 のアドレス省略表記に関する説明を下記のサイトで拝見したのですが、 http://www.soi.wide.ad.jp/iw2001/slides/04/04-1/53.html そこには IPv6 のアドレス表記に関して2つの原則が書かれていました。 1,【連続する】0 のブロックは省略できる。 2,省略できるのは【1ヶ所】だけ。 そして出力結果から推察するに、 resolver-1.pl では、原則の1, 2共に満たしてないように見受けられます。 perl が分からないので想像ですが、 resolver-1.pl では 0 を見つけたら即座に :: に置き換え、 何回でも省略が使用できるように組んであるのかなと思われます。 私の方では、一度省略を使用したら、二度と使えないようには組んでいるのですが、 0 は即座に :: に置き換えております。 そのため 0 を見つけたら、次の場所を見て、 ・次の場所も 0 なら :: に置き換える ・次の場所が 0 で無ければ、 0 を出力する。 というコードを追加しないといけないかもしれません。 勘違いでしたらすいません。 |
|
>>4393 DNS勉強中 ありがとうございます。 とりあえず TYPE=TXT の件と IPv6 の件を bugid20・21 として登録しました。 http://x68000.q-e-d.net/~68user/bugnote/bugindex.php?projectid=1 ちなみになぜわたしが web を更新しないのは、解説文からソースへの リンク方法が http://x68000.q-e-d.net/~68user/cgi-bin/cvsweb.cgi/public_html/net/org/resolver-3.html?rev=1.11&content-type=text/x-cvsweb-markup のように :preinclude 21-106 などと行番号で指定しているため、修正が非常に面倒であるからです (まぁただの言い訳なのですが)。 +10 などの相対指定にしようかとか、 m/bind\(/ などと文字列で引っ掛けようかとか迷いつつここまで来てしまいました。 ご指摘を頂いたことについては大変感謝しておりますが、修正が遅いのは なにとぞご容赦ください。 |
|
>>4392 DNS勉強中 > ただし、 void class_print(int class) を用いた共用の記述の仕方が > 分からなかったので、 > codelist_t {class, type}_list[] = { ... };をグローバル化して共用しています。 一般的には、codelist_t を扱う関数を別ソースにし、ソース先頭で static codelist_t class_list[] = { ... }; と配列を宣言して、conv_class()・class_print() でその配列を使用 します。static をつければ外部ソースからアクセスできないので、 隠蔽できます。 ただ、複数ファイルに分けると、ヘッダファイルが必要だったり Makefile を 書きたくなったりするので、サンプルであれば分ける必要はないかもしれません。 それはそれとして複数のソースから構成される場合に、グローバル変数の 宣言をヘッダファイルで一元管理する方法をご存知なければ、一度書いて みるとよいでしょう。 --- var.h ---- #ifdef THIS_IS_MAIN #define GLOBAL #else #define GLOBAL extern #endif GLOBAL class_list[] = {...}; --- main.c --- #define THIS_IS_MAIN #include "var.h" --- sub.c --- #include "var.h" こんな感じです。 |
|
>>4394 68user 修正の件了解致しました。 その後修正したもの ・教えていただいた >struct DNS_Response { > char data[10000]; > int int_data[10000]; > int pos; >}; の構造体を下記のような感じに少し修正し、流用しました。 /* DNSサーバへの質問 */ struct DNS_Query { char data[10000]; int length; }; /* DNSサーバからの応答 */ struct DNS_Response { int int_data[10000]; int pos; }; 今まで int_data と pos の 2 つの引数を渡していたところが、 struct DNS_Response だけを渡せばよくなったので、 分かりやすくなったかなと思います。 ・ linux 版の warning を解消しました。 てっきり netdb.h を include したら sys/socket.h なども include してくれるものだと勘違いしておりました。 そのため、いままでの作ってきた他のソースでも warning がたくさん出ておりました。 大変勉強になりましたm(__)m。 ・ AAAA の表示を仕様に添った形に変更しました。 そんな感じに修正を施した現状のソースをアップロードしておきます(linux版)。 http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1091.txt 後、指摘された部分で残っている修正点は ・ hoge_print 関数の書き方 ・ >>4395 全般 くらいかなと思います。 直したつもりで、意図に沿っていない修正をしている箇所はあるかもしれませんが(^^;。 他には、個人的に「フラグを構成する各要素」を resolver-1.pl のように簡単に設定出来た方が良いかなと思ってます。 私のソースでは、下記一行で設定してしまってるのがいまいちかなと。 DNS_packet->flag = 0x0100; ビットフィールドあたりで記述してうまく動作すれば良いのですが。 もっともここ自体は今回のソースでは変更することはなさそうなので、 このままでも良いのかもと思ったりも…。 |
|
>>4395 68user 今まで一つのソースで完結するものばかり書いていたので、 static の付いたグローバル変数(内部結合グローバル変数)を 使った事はありませんでした。 大変勉強になりました。 後、グローバル変数の宣言を一元管理する方法は存じてなかったので、試してみました。 http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1093.txt ただ上記は意図に沿った記述かどうか自信がありません。 それと、この件は今回のソースとは直接関係ないという認識で宜しいでしょうか? 仮に提示どおりソースを分割しても class_list[] は sub.c でしか必要ないのかなと思ったので。 その後修正したもの ・ ソースを main.c, sub.c, var.h に分割しました。 ・ 「フラグを構成する各要素」を resolver-1.pl のような感じに変更しました。 main.c(linux版) http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1094.c Makefile(linux版) http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1095.txt sub.c(linux版) http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1096.txt var.c(linux版) http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1097.txt |
|
>>4397 DNS勉強中 > http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1093.txt > ただ上記は意図に沿った記述かどうか自信がありません。 そういえばわたしには、複数ファイルから参照されるグローバル変数で、 宣言と初期化を同時に行った経験がありませんでした (わたしはこういう 場合は init_hoge() という関数を作るので)。 要は main.c で codelist_t class_list[]; codelist_t class_list[] = { {"INTERNET", 1}, ... }; となるわけですが、これはコンパイル通りますか? 少なくとも警告くらいは 出そうな気がします。 普通はどう書くんでしょうね>どなたか > それと、この件は今回のソースとは直接関係ないという認識で宜しいでしょうか? その通りです。 その他ソースについて。 > int soa_record_print(struct DNS_Response *DNS_response, char *print, int i) 引数が i というのはかなりいただけないので、record_num あたりで。 > for (i=0; type[i]!='\0'; i++) > /* 照会タイプの文字の中に英小文字があれば英大文字に変換 */ > type[i] = toupper(type[i]); そういえば strcasecmp(3) というライブラリ関数があるのを思い出しました (使ったことはないですが)。 > void qr_print(int qr){ > codelist_t qr_list[] = { > ... > }; 動作的には問題ありませんが、関数呼び出しのたびにスタックに qr_list の値が 積まれるのは無駄なので、一般的には static codelist_t qr_list[] = { ... }; とします。これだとスタックではなくヒープに置かれ、初期化は一度しか行われません。 > Makefile(linux版) > http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1095.txt わたしなら以下のように書きますが、あまり Makefile に詳しくないので怪しげです。 TARGET= domain_to_ip OBJS = main.o sub.o CFLAGS = -Wall $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) .c.o: sub.h $(CC) $(CFLAGS) -c $< clean: rm -f *.o *~ core $(TARGET) $(OBJS) あと、main がとても長くて汚い関数に見えますので、 make_query(); send_receive(); parse_response(); の 3行か+エラー処理か、あるいは make_query(); send_query(); receive_response(); parse_response(); の 4行+エラー処理くらいになるとよいかも、と思いました。 続く。 |