mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * Copyright (c) International Business Machines Corp., 2001 |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| 13 | * the GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
Wanlong Gao | 4548c6c | 2012-10-19 18:03:36 +0800 | [diff] [blame] | 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 18 | */ |
| 19 | |
| 20 | /* |
| 21 | * Test Name: asapi_01 |
| 22 | * |
| 23 | * Test Description: |
| 24 | * These tests are for the "Advanced Sockets API" (RFC 3542) |
| 25 | * Verify that in6 and sockaddr fields are present. |
| 26 | * |
| 27 | * Usage: <for command-line> |
| 28 | * asapi_01 |
| 29 | * |
| 30 | * HISTORY |
| 31 | * 01/2005 written by David L Stevens |
| 32 | * |
| 33 | * RESTRICTIONS: |
| 34 | * None. |
| 35 | * |
| 36 | */ |
| 37 | |
| 38 | #include <stdio.h> |
| 39 | #include <unistd.h> |
| 40 | #include <errno.h> |
| 41 | |
| 42 | #include <sys/wait.h> |
| 43 | |
| 44 | #include <netinet/ip6.h> |
| 45 | |
| 46 | #include "test.h" |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 47 | #include "runcc.h" |
| 48 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 49 | char *TCID = "asapi_01"; /* Test program identifier. */ |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 50 | |
| 51 | void setup(void), cleanup(void); |
| 52 | |
| 53 | enum ttype { EXISTS, ALIAS, VALUE }; |
| 54 | |
| 55 | struct ftent { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 56 | char *ft_tname; /* test name */ |
| 57 | int ft_type; /* test type */ |
| 58 | char *ft_incl; /* include file list */ |
| 59 | char *ft_struct; /* structure name */ |
| 60 | char *ft_field; /* field name */ |
| 61 | char *ft_offset; /* field offset */ |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 62 | union { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 63 | char *fu_value; /* field size or value */ |
| 64 | char *fu_dname; /* #define name */ |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 65 | } ftun; |
| 66 | #define ft_value ftun.fu_value |
| 67 | #define ft_dname ftun.fu_dname |
| 68 | } ftab[] = { |
| 69 | /* section 2.1 structure & field definitions */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 70 | { |
| 71 | "ip6_hdr un1_flow", EXISTS, IP6_H, "ip6_hdr", |
| 72 | "ip6_ctlun.ip6_un1.ip6_un1_flow", "0", { |
| 73 | "4"}}, { |
| 74 | "ip6_hdr ip6_flow", ALIAS, IP6_H, "ip6_hdr", |
| 75 | "ip6_ctlun.ip6_un1.ip6_un1_flow", NULL, { |
| 76 | "ip6_flow"}}, { |
| 77 | "ip6_hdr un1_plen", EXISTS, IP6_H, "ip6_hdr", |
| 78 | "ip6_ctlun.ip6_un1.ip6_un1_plen", "4", { |
| 79 | "2"}}, { |
| 80 | "ip6_hdr ip6_plen", ALIAS, IP6_H, "ip6_hdr", |
| 81 | "ip6_ctlun.ip6_un1.ip6_un1_plen", "4", { |
| 82 | "ip6_plen"}}, { |
| 83 | "ip6_hdr un1_nxt", EXISTS, IP6_H, "ip6_hdr", |
| 84 | "ip6_ctlun.ip6_un1.ip6_un1_nxt", "6", { |
| 85 | "1"}}, { |
| 86 | "ip6_hdr ip6_nxt", ALIAS, IP6_H, "ip6_hdr", |
| 87 | "ip6_ctlun.ip6_un1.ip6_un1_nxt", NULL, { |
| 88 | "ip6_nxt"}}, { |
| 89 | "ip6_hdr un1_hlim", EXISTS, IP6_H, "ip6_hdr", |
| 90 | "ip6_ctlun.ip6_un1.ip6_un1_hlim", "7", { |
| 91 | "1"}}, { |
| 92 | "ip6_hdr ip6_hlim", ALIAS, IP6_H, "ip6_hdr", |
| 93 | "ip6_ctlun.ip6_un1.ip6_un1_hlim", NULL, { |
| 94 | "ip6_hlim"}}, { |
| 95 | "ip6_hdr un1_vfc", EXISTS, IP6_H, "ip6_hdr", |
| 96 | "ip6_ctlun.ip6_un2_vfc", "0", { |
| 97 | "1"}}, { |
| 98 | "ip6_hdr ip6_src", EXISTS, IP6_H, "ip6_hdr", "ip6_src", |
| 99 | "sizeof(struct ip6_hdrctl)", { |
| 100 | "sizeof(struct in6_addr)"}}, { |
| 101 | "ip6_hdr ip6_dst", EXISTS, IP6_H, "ip6_hdr", "ip6_dst", |
| 102 | "(sizeof(struct ip6_hdrctl)+sizeof(struct in6_addr))", { |
| 103 | "sizeof(struct in6_addr)"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 104 | /* section 2.2 structure and field definitions */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 105 | { |
| 106 | "IPPROTO_HOPOPTS", VALUE, IN_H, "IPPROTO_HOPOPTS", NULL, NULL, { |
| 107 | "0"}}, { |
| 108 | "IPPROTO_IPV6", VALUE, IN_H, "IPPROTO_IPV6", NULL, NULL, { |
| 109 | "41"}}, { |
| 110 | "IPPROTO_ROUTING", VALUE, IN_H, "IPPROTO_ROUTING", NULL, NULL, { |
| 111 | "43"}}, { |
| 112 | "IPPROTO_FRAGMENT", VALUE, IN_H, "IPPROTO_FRAGMENT", NULL, NULL, { |
| 113 | "44"}}, { |
| 114 | "IPPROTO_ESP", VALUE, IN_H, "IPPROTO_ESP", NULL, NULL, { |
| 115 | "50"}}, { |
| 116 | "IPPROTO_AH", VALUE, IN_H, "IPPROTO_AH", NULL, NULL, { |
| 117 | "51"}}, { |
| 118 | "IPPROTO_ICMPV6", VALUE, IN_H, "IPPROTO_ICMPV6", NULL, NULL, { |
| 119 | "58"}}, { |
| 120 | "IPPROTO_NONE", VALUE, IN_H, "IPPROTO_NONE", NULL, NULL, { |
| 121 | "59"}}, { |
| 122 | "IPPROTO_DSTOPTS", VALUE, IN_H, "IPPROTO_DSTOPTS", NULL, NULL, { |
| 123 | "60"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 124 | /* ip6_hbh */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 125 | { |
| 126 | "ip6_hbh ip6h_nxt", EXISTS, IP6_H, "ip6_hbh", "ip6h_nxt", "0", { |
| 127 | "1"}}, { |
| 128 | "ip6_hbh ip6h_nxt", EXISTS, IP6_H, "ip6_hbh", "ip6h_len", "1", { |
| 129 | "1"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 130 | /* ip6_dest */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 131 | { |
| 132 | "ip6_dest ip6d_nxt", EXISTS, IP6_H, "ip6_dest", "ip6d_nxt", "0", { |
| 133 | "1"}}, { |
| 134 | "ip6_dest ip6d_nxt", EXISTS, IP6_H, "ip6_dest", "ip6d_len", "1", { |
| 135 | "1"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 136 | /* ip6_rthdr0 */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 137 | { |
| 138 | "ip6_rthdr0 ip6r0_nxt", EXISTS, IP6_H, "ip6_rthdr0", |
| 139 | "ip6r0_nxt", "0", { |
| 140 | "1"}}, { |
| 141 | "ip6_rthdr0 ip6r0_len", EXISTS, IP6_H, "ip6_rthdr0", |
| 142 | "ip6r0_len", "1", { |
| 143 | "1"}}, { |
| 144 | "ip6_rthdr0 ip6r0_type", EXISTS, IP6_H, "ip6_rthdr0", |
| 145 | "ip6r0_type", "2", { |
| 146 | "1"}}, { |
| 147 | "ip6_rthdr0 ip6r0_segleft", EXISTS, IP6_H, "ip6_rthdr0", |
| 148 | "ip6r0_segleft", "3", { |
| 149 | "1"}}, { |
| 150 | "ip6_rthdr0 ip6r0_reserved", EXISTS, IP6_H, "ip6_rthdr0", |
| 151 | "ip6r0_reserved", "4", { |
| 152 | "1"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 153 | /* ip6_frag */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 154 | { |
| 155 | "ip6_frag ip6f_nxt", EXISTS, IP6_H, "ip6_frag", "ip6f_nxt", "0", { |
| 156 | "1"}}, { |
| 157 | "ip6_frag ip6f_reserved", EXISTS, IP6_H, "ip6_frag", |
| 158 | "ip6f_reserved", "1", { |
| 159 | "1"}}, { |
| 160 | "ip6_frag ip6f_offlg", EXISTS, IP6_H, "ip6_frag", |
| 161 | "ip6f_offlg", "2", { |
| 162 | "2"}}, { |
| 163 | "ip6_frag ip6f_ident", EXISTS, IP6_H, "ip6_frag", |
| 164 | "ip6f_ident", "4", { |
| 165 | "4"}}, { |
| 166 | "IP6F_OFF_MASK", VALUE, IP6_H, "IP6F_OFF_MASK", NULL, NULL, { |
| 167 | "htons(0xfff8)"}}, { |
| 168 | "IP6F_RESERVED_MASK", VALUE, IP6_H, "IP6F_RESERVED_MASK", |
| 169 | NULL, NULL, { |
| 170 | "htons(0x0006)"}}, { |
| 171 | "IP6F_MORE_FRAG", VALUE, IP6_H, "IP6F_MORE_FRAG", NULL, NULL, { |
| 172 | "htons(0x0001)"}}, { |
| 173 | "IP6OPT_TYPE", VALUE, IP6_H, "IP6OPT_TYPE(0xff)", NULL, NULL, { |
| 174 | "0xc0"}}, { |
| 175 | "IP6OPT_TYPE_SKIP", VALUE, IP6_H, "IP6OPT_TYPE_SKIP", |
| 176 | NULL, NULL, { |
| 177 | "0x00"}}, { |
| 178 | "IP6OPT_TYPE_DISCARD", VALUE, IP6_H, "IP6OPT_TYPE_DISCARD", |
| 179 | NULL, NULL, { |
| 180 | "0x40"}}, { |
| 181 | "IP6OPT_TYPE_FORCEICMP", VALUE, IP6_H, "IP6OPT_TYPE_FORCEICMP", |
| 182 | NULL, NULL, { |
| 183 | "0x80"}}, { |
| 184 | "IP6OPT_TYPE_ICMP", VALUE, IP6_H, "IP6OPT_TYPE_ICMP", |
| 185 | NULL, NULL, { |
| 186 | "0xc0"}}, { |
| 187 | "IP6OPT_TYPE_MUTABLE", VALUE, IP6_H, "IP6OPT_TYPE_MUTABLE", |
| 188 | NULL, NULL, { |
| 189 | "0x20"}}, { |
| 190 | "IP6OPT_PAD1", VALUE, IP6_H, "IP6OPT_PAD1", NULL, NULL, { |
| 191 | "0x00"}}, { |
| 192 | "IP6OPT_PADN", VALUE, IP6_H, "IP6OPT_PADN", NULL, NULL, { |
| 193 | "0x01"}}, { |
| 194 | "IP6OPT_JUMBO", VALUE, IP6_H, "IP6OPT_JUMBO", NULL, NULL, { |
| 195 | "0xc2"}}, { |
| 196 | "IP6OPT_NSAP_ADDR", VALUE, IP6_H, "IP6OPT_NSAP_ADDR", |
| 197 | NULL, NULL, { |
| 198 | "0xc3"}}, { |
| 199 | "IP6OPT_TUNNEL_LIMIT", VALUE, IP6_H, "IP6OPT_TUNNEL_LIMIT", |
| 200 | NULL, NULL, { |
| 201 | "0x04"}}, { |
| 202 | "IP6OPT_ROUTER_ALERT", VALUE, IP6_H, "IP6OPT_ROUTER_ALERT", |
| 203 | NULL, NULL, { |
| 204 | "0x05"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 205 | /* ip6_opt_jumbo */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 206 | { |
| 207 | "ip6_opt_jumbo ip6oj_type", EXISTS, IP6_H, "ip6_opt_jumbo", |
| 208 | "ip6oj_type", "0", { |
| 209 | "1"}}, { |
| 210 | "ip6_opt_jumbo ip6oj_len", EXISTS, IP6_H, "ip6_opt_jumbo", |
| 211 | "ip6oj_len", "1", { |
| 212 | "1"}}, { |
| 213 | "ip6_opt_jumbo ip6oj_jumbo_len element", EXISTS, IP6_H, |
| 214 | "ip6_opt_jumbo", "ip6oj_jumbo_len[0]", "2", { |
| 215 | "1"}}, { |
| 216 | "ip6_opt_jumbo ip6oj_jumbo_len array", EXISTS, IP6_H, |
| 217 | "ip6_opt_jumbo", "ip6oj_jumbo_len", "2", { |
| 218 | "4"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 219 | /* ip6_opt_nsap */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 220 | { |
| 221 | "ip6_opt_nsap ip6on_type", EXISTS, IP6_H, "ip6_opt_nsap", |
| 222 | "ip6on_type", "0", { |
| 223 | "1"}}, { |
| 224 | "ip6_opt_nsap ip6on_len", EXISTS, IP6_H, "ip6_opt_nsap", |
| 225 | "ip6on_len", "1", { |
| 226 | "1"}}, { |
| 227 | "ip6_opt_nsap ip6on_src_nsap_len", EXISTS, IP6_H, |
| 228 | "ip6_opt_nsap", "ip6on_src_nsap_len", "2", { |
| 229 | "1"}}, { |
| 230 | "ip6_opt_nsap ip6on_dst_nsap_len", EXISTS, IP6_H, |
| 231 | "ip6_opt_nsap", "ip6on_dst_nsap_len", "3", { |
| 232 | "1"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 233 | /* ip6_opt_tunnel */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 234 | { |
| 235 | "ip6_opt_tunnel ip6ot_type", EXISTS, IP6_H, "ip6_opt_tunnel", |
| 236 | "ip6ot_type", "0", { |
| 237 | "1"}}, { |
| 238 | "ip6_opt_tunnel ip6ot_len", EXISTS, IP6_H, "ip6_opt_tunnel", |
| 239 | "ip6ot_len", "1", { |
| 240 | "1"}}, { |
| 241 | "ip6_opt_tunnel ip6ot_encap_limit", EXISTS, IP6_H, |
| 242 | "ip6_opt_tunnel", "ip6ot_encap_limit", "2", { |
| 243 | "1"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 244 | /* ip6_opt_router */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 245 | { |
| 246 | "ip6_opt_router ip6or_type", EXISTS, IP6_H, "ip6_opt_router", |
| 247 | "ip6or_type", "0", { |
| 248 | "1"}}, { |
| 249 | "ip6_opt_router ip6or_len", EXISTS, IP6_H, "ip6_opt_router", |
| 250 | "ip6or_len", "1", { |
| 251 | "1"}}, { |
| 252 | "ip6_opt_router ip6or_value element", EXISTS, IP6_H, |
| 253 | "ip6_opt_router", "ip6or_value[0]", "2", { |
| 254 | "1"}}, { |
| 255 | "ip6_opt_router ip6or_value array", EXISTS, IP6_H, |
| 256 | "ip6_opt_router", "ip6or_value", "2", { |
| 257 | "2"}}, |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 258 | /* IP6_ALERT_* definitions */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 259 | { |
| 260 | "IP6_ALERT_MLD", VALUE, IP6_H, "IP6_ALERT_MLD", NULL, NULL, { |
| 261 | "0"}}, { |
| 262 | "IP6_ALERT_RSVP", VALUE, IP6_H, "IP6_ALERT_RSVP", NULL, NULL, { |
| 263 | "htons(1)"}}, { |
| 264 | "IP6_ALERT_AN", VALUE, IP6_H, "IP6_ALERT_AN", NULL, NULL, { |
| 265 | "htons(2)"}},}; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 266 | |
| 267 | #define FTCOUNT (sizeof(ftab)/sizeof(ftab[0])) |
| 268 | |
| 269 | int TST_TOTAL = FTCOUNT; |
| 270 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 271 | int main(int argc, char *argv[]) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 272 | { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 273 | int i, lc; |
Cyril Hrubis | 0b9589f | 2014-05-27 17:40:33 +0200 | [diff] [blame] | 274 | const char *msg; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 275 | |
| 276 | /* Parse standard options given to run the test. */ |
Garrett Cooper | df3eb16 | 2010-11-28 22:44:32 -0800 | [diff] [blame] | 277 | msg = parse_opts(argc, argv, NULL, NULL); |
| 278 | if (msg != NULL) { |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 279 | tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 280 | } |
| 281 | |
| 282 | setup(); |
| 283 | |
| 284 | for (lc = 0; TEST_LOOPING(lc); ++lc) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 285 | for (i = 0; i < FTCOUNT; ++i) { |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 286 | switch (ftab[i].ft_type) { |
| 287 | case EXISTS: |
| 288 | structcheck(ftab[i].ft_tname, ftab[i].ft_incl, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 289 | ftab[i].ft_struct, ftab[i].ft_field, |
| 290 | ftab[i].ft_offset, |
| 291 | ftab[i].ft_value); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 292 | break; |
| 293 | case ALIAS: |
| 294 | aliascheck(ftab[i].ft_tname, ftab[i].ft_incl, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 295 | ftab[i].ft_struct, ftab[i].ft_field, |
| 296 | ftab[i].ft_dname); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 297 | break; |
| 298 | case VALUE: |
| 299 | valuecheck(ftab[i].ft_tname, ftab[i].ft_incl, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 300 | ftab[i].ft_struct, ftab[i].ft_dname); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 301 | break; |
| 302 | default: |
| 303 | tst_resm(TBROK, "invalid type %d", |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 304 | ftab[i].ft_type); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 305 | break; |
| 306 | } |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | cleanup(); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 311 | |
| 312 | tst_exit(); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 313 | } |
| 314 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 315 | void setup(void) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 316 | { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 317 | TEST_PAUSE; /* if -P option specified */ |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 318 | } |
| 319 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 320 | void cleanup(void) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 321 | { |
Chris Dearman | ec6edca | 2012-10-17 19:54:01 -0700 | [diff] [blame] | 322 | } |