ネットワーク

Contents:

TIPS

色々なTIPS

AS番号と組織名のCSVファイルの作り方

AS番号からASの組織名を引くためのリストを作ります. .. code-block:

curl 'http://bgp.potaroo.net/cidr/autnums.html' |
nkf -e | cut -d '>' -f 2,3- | sed -e 's/^AS//' -e 's/<\/a>/,/' |
sed -e 's/ ,/,/' -e 's/, /,/'

MACアドレスを正規化する

FreeBSDではarpでは08:00:10:01:01:01と表示されるMACアドレスに対してndpでは8:0:10:1:1:1と表示される。 これをすべてのフィールドで2桁に表示するには、

printf '%02x:%02x:%02x:%02x:%02x:%02x' `echo 8:0:10:1:1:1 | sed -e 's/^/:/' -e 's/:/ 0x/g'`
08:00:10:01:01:01
printf '%02x:%02x:%02x:%02x:%02x:%02x' `echo 8:0:10:1:1:1 | sed -e 's/^/:/' -e 's/:/ 0x/g'` | tr -d ':'
080010010101

とする。

IPアドレスでソート

cat /etc/hosts | sort -t'.' -k1,1 -k2,2 -k3,3 -k4,4 -n

ICMPv6チェックサムの計算方法(mixi日記より) 2007年07月09日00:51

  • icmpv6の3,4バイト目がチェックサム
  • 最初は0x0000突っ込む(IPとかと一緒ですね)
  • まず,val1 = icmpv6のtypeから最後までを1の補数和とる
sum = (sum % 0x10000) + sum - (sum - 0x10000 * (sum % 0x10000))な感じ

Note

これは要検討だけど、 checksum = (checksum >>16) + (checksum << 16 >> 16); でいいんじゃない?

  • 次に,val2 = ipv6{src,dst}ipの総和 + ipv6のpayload length + 58(oct)を1の補数和で計算
  • 0x10000 - val1 + val2を突っ込む

Note

ちなみに,ぜんぶu_int16で計算 疑似ヘッダの扱い方が最初わからず,少しハマりました.

> The Next Header field in the pseudo-header for ICMP contains the value 58

10進数ですね.0x58をaddしてましたorz

コード

/*
* RA PACKET STRUCTURE
*/
struct ra_packet
{
 u_int8_t  type;                        /* 134(0x86) */
 u_int8_t  code;                        /* 0 */
 u_int16_t checksum;                    /* 0 */
 u_int8_t  hoplimit;                    /* 64(0x40) */
 u_int8_t  flag;                        /* 0 */
 u_int16_t lifetime;                    /* 1800(0x0708) */
 u_int32_t reachabletime;               /* 0 */
 u_int32_t retranstime;                 /* 0 */
 u_int8_t  opt_type;                    /* 1 */
 u_int8_t  opt_src_len;                 /* 1(8byte) */
 u_int8_t  opt_src_mac[ETHER_ADDR_LEN]; /* */
 u_int8_t  opt_prefix_type;             /* 3 */
 u_int8_t  opt_prefix_len;              /* 4(32byte) */
 u_int8_t  opt_prefix_prefixlen;        /* 64(0x40) */
 u_int8_t  opt_prefix_flag;             /* 0xc0 */
 u_int32_t opt_prefix_validtime;        /* 30days = (0x00278d00) */
 u_int32_t opt_prefix_preferredtime;    /* 7days = (0x00093a80) */
 u_int32_t opt_prefix_NULL;             /* 0 */
 u_int8_t  opt_prefix_prefix[16];       /* */
 };  u_int32_t checksum;
 struct ra_packet ra_packet;
   /* Calc Pseudo Header Checksum */
   checksum = 0;
   for(i = 0; i < 8; i++) {
     checksum += (u_int16_t)ntohs((u_int16_t)src_ip.__u6_addr.__u6_addr16[i]);
   }
   for(i = 0; i < 8; i++) {
     checksum += (u_int16_t)ntohs((u_int16_t)dst_ip.__u6_addr.__u6_addr16[i]);
   }
   checksum += sizeof(struct ra_packet); /* pesudo-next-type */
   checksum += 58; /* pesudo-next-type */

   /* Calc ICMPv6 Checksum */
   ra_packet.checksum = 0;
   payload = (char *)&ra_packet;
   for(i = 0; i < 23; i++)
     {
  checksum += (u_int32_t)(((u_int32_t)payload[2*i] << 8) + ((u_int32_t)payload[2*i+ 1]));
     }
   checksum = 0xffff - ( (checksum >>16) + (checksum << 16 >> 16) );
   ra_packet.checksum = htons(checksum);

IPv4のチェックサム再計算方法(mixi日記より) 2007年10月09日22:31

単一16bitレコードの書き換えは RFC1624 <http://www.ietf.org/rfc/rfc1624.txt> に乗っているけど,

data1_old -> data1_new
data2_old -> data2_new

みたいに,16bitの情報を2つ書き換えた時は?

UINT16 checksum_old;
UINT16 checksum_new;
UINT16 checksum_new_buffer;
UINT16 data1_old;
UINT16 data2_old;
UINT16 data1_new;
UINT16 data2_new;

という場合に対して,(全部ntohsしていると仮定して)

checksum_new_buffer = ~( ~checksum_old + ~data1_old + ~data2_old + data1_new + data2_new);
checksum_new = htons ( (UINT16)( (checksum_new_buffer >> 16) + (checksum_new_buffer & 0xffff) ));

でいい。つまり, 「古いのは補数,新しいのはそのままたしこむ」 そして,補数をとって,繰り上がりを足して終わり.