Free or Net or Open?
TCPIPアクマ本を読むに当たって折角だから生きたコードを見てみたいと考えて、さて、どれいれようか?と迷う。FreeBSDかNetBSDかOpenBSDか。
早速ぐうぐる先生に聞いてみると以下のページに判りやすく纏めてあった(ありがとうございます)。
http://d.hatena.ne.jp/hcr/20041027/p1
なるほど。大雑把には FreeBSD ... 革新派, NetBSD ... 保守派, OpenBSD ... 真ん中くらい?*1
というところかな。今回の目的だと more clean の Net or Open かな、というところ。
たとえばPCBは?
早速勉強したてホヤホヤのPCBのところのコードを見てみる、と。。。
FreeBSD
IPv6からIPSecまで全部いりなんだけど比較的整理されていてきれい。
156 struct inpcb { 157 LIST_ENTRY(inpcb) inp_hash; /* (i/p) hash list */ 158 LIST_ENTRY(inpcb) inp_list; /* (i/p) list for all PCBs for proto */ 159 void *inp_ppcb; /* (i) pointer to per-protocol pcb */ 160 struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */ 161 struct socket *inp_socket; /* (i) back pointer to socket */ 162 struct ucred *inp_cred; /* (c) cache of socket cred */ 163 u_int32_t inp_flow; /* (i) IPv6 flow information */ 164 int inp_flags; /* (i) generic IP/datagram flags */ 165 int inp_flags2; /* (i) generic IP/datagram flags #2*/ 166 u_char inp_vflag; /* (i) IP version flag (v4/v6) */ 167 u_char inp_ip_ttl; /* (i) time to live proto */ 168 u_char inp_ip_p; /* (c) protocol proto */ 169 u_char inp_ip_minttl; /* (i) minimum TTL or drop */ 170 uint32_t inp_flowid; /* (x) flow id / queue id */ 171 u_int inp_refcount; /* (i) refcount */ 172 void *inp_pspare[4]; /* (x) rtentry / general use */ 173 u_int inp_ispare[4]; /* general use */ 174 175 /* Local and foreign ports, local and foreign addr. */ 176 struct in_conninfo inp_inc; /* (i/p) list for PCB's local port */ 177 178 /* MAC and IPSEC policy information. */ 179 struct label *inp_label; /* (i) MAC label */ 180 struct inpcbpolicy *inp_sp; /* (s) for IPSEC */ 181 182 /* Protocol-dependent part; options. */ 183 struct { 184 u_char inp4_ip_tos; /* (i) type of service proto */ 185 struct mbuf *inp4_options; /* (i) IP options */ 186 struct ip_moptions *inp4_moptions; /* (i) IP mcast options */ 187 } inp_depend4; 188 struct { 189 /* (i) IP options */ 190 struct mbuf *inp6_options; 191 /* (i) IP6 options for outgoing packets */ 192 struct ip6_pktopts *inp6_outputopts; 193 /* (i) IP multicast options */ 194 struct ip6_moptions *inp6_moptions; 195 /* (i) ICMPv6 code type filter */ 196 struct icmp6_filter *inp6_icmp6filt; 197 /* (i) IPV6_CHECKSUM setsockopt */ 198 int inp6_cksum; 199 short inp6_hops; 200 } inp_depend6; 201 LIST_ENTRY(inpcb) inp_portlist; /* (i/p) */ 202 struct inpcbport *inp_phd; /* (i/p) head of this list */ 203 #define inp_zero_size offsetof(struct inpcb, inp_gencnt) 204 inp_gen_t inp_gencnt; /* (c) generation count */ 205 struct llentry *inp_lle; /* cached L2 information */ 206 struct rtentry *inp_rt; /* cached L3 information */ 207 struct rwlock inp_lock; 208 };
NetBSD
こちらはNet/3のコードそのまんま。やはり今回の勉強にはこれがよさそう。ちなみにIPv6に関しては netinet6/in6_pcb.hに別物として定義されている。哲学どおり1つ1つは短く、明快になっている。
76 struct inpcb { 77 struct inpcb_hdr inp_head; 78 #define inp_hash inp_head.inph_hash 79 #define inp_queue inp_head.inph_queue 80 #define inp_af inp_head.inph_af 81 #define inp_ppcb inp_head.inph_ppcb 82 #define inp_state inp_head.inph_state 83 #define inp_socket inp_head.inph_socket 84 #define inp_table inp_head.inph_table 85 #define inp_sp inp_head.inph_sp 86 struct route inp_route; /* placeholder for routing entry */ 87 u_int16_t inp_fport; /* foreign port */ 88 u_int16_t inp_lport; /* local port */ 89 int inp_flags; /* generic IP/datagram flags */ 90 struct ip inp_ip; /* header prototype; should have more */ 91 struct mbuf *inp_options; /* IP options */ 92 struct ip_moptions *inp_moptions; /* IP multicast options */ 93 int inp_errormtu; /* MTU of last xmit status = EMSGSIZE */ 94 };
OpenBSD
おうわーーーーー、Packet Filter から IPSecからIPv6まで全部入っている。NetBSDから喧嘩別れしてダークサイドに入った?
というか正直カオス
88 struct inpcb { 89 LIST_ENTRY(inpcb) inp_hash; 90 LIST_ENTRY(inpcb) inp_lhash; /* extra hash for lport */ 91 CIRCLEQ_ENTRY(inpcb) inp_queue; 92 struct inpcbtable *inp_table; 93 union inpaddru inp_faddru; /* Foreign address. */ 94 union inpaddru inp_laddru; /* Local address. */ 95 #define inp_faddr inp_faddru.iau_a4u.inaddr 96 #define inp_faddr6 inp_faddru.iau_addr6 97 #define inp_laddr inp_laddru.iau_a4u.inaddr 98 #define inp_laddr6 inp_laddru.iau_addr6 99 u_int16_t inp_fport; /* foreign port */ 100 u_int16_t inp_lport; /* local port */ 101 struct socket *inp_socket; /* back pointer to socket */ 102 caddr_t inp_ppcb; /* pointer to per-protocol pcb */ 103 union { /* Route (notice increased size). */ 104 struct route ru_route; 105 struct route_in6 ru_route6; 106 } inp_ru; 107 #define inp_route inp_ru.ru_route 108 #define inp_route6 inp_ru.ru_route6 109 int inp_flags; /* generic IP/datagram flags */ 110 union { /* Header prototype. */ 111 struct ip hu_ip; 112 struct ip6_hdr hu_ipv6; 113 } inp_hu; 114 #define inp_ip inp_hu.hu_ip 115 #define inp_ipv6 inp_hu.hu_ipv6 116 struct mbuf *inp_options; /* IP options */ 117 struct ip6_pktopts *inp_outputopts6; /* IP6 options for outgoing packets */ 118 int inp_hops; 119 union { 120 struct ip_moptions *mou_mo; /* IPv4 multicast options */ 121 struct ip6_moptions *mou_mo6; /* IPv6 multicast options */ 122 } inp_mou; 123 #define inp_moptions inp_mou.mou_mo 124 #define inp_moptions6 inp_mou.mou_mo6 125 u_char inp_seclevel[4]; 126 #define SL_AUTH 0 /* Authentication level */ 127 #define SL_ESP_TRANS 1 /* ESP transport level */ 128 #define SL_ESP_NETWORK 2 /* ESP network (encapsulation) level */ 129 #define SL_IPCOMP 3 /* Compression level */ 130 u_int inp_secrequire:4, /* Condensed State from above */ 131 inp_secresult:4; /* Result from Key Management */ 132 #define SR_FAILED 1 /* Negotiation failed permanently */ 133 #define SR_SUCCESS 2 /* SA successfully established */ 134 #define SR_WAIT 3 /* Waiting for SA */ 135 u_char inp_ip_minttl; /* minimum TTL or drop */ 136 TAILQ_ENTRY(inpcb) inp_tdb_in_next, inp_tdb_out_next; 137 struct tdb *inp_tdb_in, *inp_tdb_out; 138 struct ipsec_policy *inp_ipo; 139 struct ipsec_ref *inp_ipsec_remotecred; 140 struct ipsec_ref *inp_ipsec_remoteauth; 141 #define inp_flowinfo inp_hu.hu_ipv6.ip6_flow 142 143 int in6p_cksum; 144 #ifndef _KERNEL 145 #define inp_csumoffset in6p_cksum 146 #endif 147 struct icmp6_filter *inp_icmp6filt; 148 void *inp_pf_sk; 149 };
というわけでやはり...
お勉強用にはNetBSDですね。組込みでも対応アーキテクチャの広さからNetBSDが選択されることが多いとかいう話(未確認)を聞いたことがあるし。まずはNetBSDで深みにはまってからFreeBSDを見てみよう、とか考えてる。
ちなみにLinuxは、というと、、、ちょうどPCB当たりはsock構造体にあたると思うんだけど、こちらは
108 struct inet_sock { 109 /* sk and pinet6 has to be the first two members of inet_sock */ 110 struct sock sk; 111 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 112 struct ipv6_pinfo *pinet6; 113 #endif 114 /* Socket demultiplex comparisons on incoming packets. */ 115 __be32 daddr; 116 __be32 rcv_saddr; 117 __be16 dport; 118 __u16 num; 119 __be32 saddr;