1 2 #include <setjmp.h> 3 #include <stdlib.h> 4 5 #include "dhcpd.h" 6 7 jmp_buf env; 8 9 void expand_domain_search(struct packet *packet); 10 11 void 12 no_option_present() 13 { 14 int ret; 15 struct option_data option; 16 struct packet p; 17 18 option.data = NULL; 19 option.len = 0; 20 p.options[DHO_DOMAIN_SEARCH] = option; 21 22 ret = setjmp(env); 23 if (ret == 0) 24 expand_domain_search(&p); 25 26 if (p.options[DHO_DOMAIN_SEARCH].len != 0 || 27 p.options[DHO_DOMAIN_SEARCH].data != NULL) 28 abort(); 29 } 30 31 void 32 one_domain_valid() 33 { 34 int ret; 35 struct packet p; 36 struct option_data *option; 37 38 char *data = "\007example\003org\0"; 39 char *expected = "example.org."; 40 41 option = &p.options[DHO_DOMAIN_SEARCH]; 42 option->len = 13; 43 option->data = malloc(option->len); 44 memcpy(option->data, data, option->len); 45 46 ret = setjmp(env); 47 if (ret == 0) 48 expand_domain_search(&p); 49 50 if (option->len != strlen(expected) || 51 strcmp(option->data, expected) != 0) 52 abort(); 53 54 free(option->data); 55 } 56 57 void 58 one_domain_truncated1() 59 { 60 int ret; 61 struct option_data *option; 62 struct packet p; 63 64 char *data = "\007example\003org"; 65 66 option = &p.options[DHO_DOMAIN_SEARCH]; 67 option->len = 12; 68 option->data = malloc(option->len); 69 memcpy(option->data, data, option->len); 70 71 ret = setjmp(env); 72 if (ret == 0) 73 expand_domain_search(&p); 74 75 if (ret != 1) 76 abort(); 77 78 free(option->data); 79 } 80 81 void 82 one_domain_truncated2() 83 { 84 int ret; 85 struct option_data *option; 86 struct packet p; 87 88 char *data = "\007ex"; 89 90 option = &p.options[DHO_DOMAIN_SEARCH]; 91 option->len = 3; 92 option->data = malloc(option->len); 93 memcpy(option->data, data, option->len); 94 95 ret = setjmp(env); 96 if (ret == 0) 97 expand_domain_search(&p); 98 99 if (ret != 1) 100 abort(); 101 102 free(option->data); 103 } 104 105 void 106 two_domains_valid() 107 { 108 int ret; 109 struct packet p; 110 struct option_data *option; 111 112 char *data = "\007example\003org\0\007example\003com\0"; 113 char *expected = "example.org. example.com."; 114 115 option = &p.options[DHO_DOMAIN_SEARCH]; 116 option->len = 26; 117 option->data = malloc(option->len); 118 memcpy(option->data, data, option->len); 119 120 ret = setjmp(env); 121 if (ret == 0) 122 expand_domain_search(&p); 123 124 if (option->len != strlen(expected) || 125 strcmp(option->data, expected) != 0) 126 abort(); 127 128 free(option->data); 129 } 130 131 void 132 two_domains_truncated1() 133 { 134 int ret; 135 struct option_data *option; 136 struct packet p; 137 138 char *data = "\007example\003org\0\007example\003com"; 139 140 option = &p.options[DHO_DOMAIN_SEARCH]; 141 option->len = 25; 142 option->data = malloc(option->len); 143 memcpy(option->data, data, option->len); 144 145 ret = setjmp(env); 146 if (ret == 0) 147 expand_domain_search(&p); 148 149 if (ret != 1) 150 abort(); 151 152 free(option->data); 153 } 154 155 void 156 two_domains_truncated2() 157 { 158 int ret; 159 struct option_data *option; 160 struct packet p; 161 162 char *data = "\007example\003org\0\007ex"; 163 164 option = &p.options[DHO_DOMAIN_SEARCH]; 165 option->len = 16; 166 option->data = malloc(option->len); 167 memcpy(option->data, data, option->len); 168 169 ret = setjmp(env); 170 if (ret == 0) 171 expand_domain_search(&p); 172 173 if (ret != 1) 174 abort(); 175 176 free(option->data); 177 } 178 179 void 180 two_domains_compressed() 181 { 182 int ret; 183 struct packet p; 184 struct option_data *option; 185 186 char *data = "\007example\003org\0\006foobar\xc0\x08"; 187 char *expected = "example.org. foobar.org."; 188 189 option = &p.options[DHO_DOMAIN_SEARCH]; 190 option->len = 22; 191 option->data = malloc(option->len); 192 memcpy(option->data, data, option->len); 193 194 ret = setjmp(env); 195 if (ret == 0) 196 expand_domain_search(&p); 197 198 if (option->len != strlen(expected) || 199 strcmp(option->data, expected) != 0) 200 abort(); 201 202 free(option->data); 203 } 204 205 void 206 two_domains_infloop() 207 { 208 int ret; 209 struct packet p; 210 struct option_data *option; 211 212 char *data = "\007example\003org\0\006foobar\xc0\x0d"; 213 214 option = &p.options[DHO_DOMAIN_SEARCH]; 215 option->len = 22; 216 option->data = malloc(option->len); 217 memcpy(option->data, data, option->len); 218 219 ret = setjmp(env); 220 if (ret == 0) 221 expand_domain_search(&p); 222 223 if (ret != 1) 224 abort(); 225 226 free(option->data); 227 } 228 229 void 230 two_domains_forwardptr() 231 { 232 int ret; 233 struct packet p; 234 struct option_data *option; 235 236 char *data = "\007example\003org\xc0\x0d\006foobar\0"; 237 238 option = &p.options[DHO_DOMAIN_SEARCH]; 239 option->len = 22; 240 option->data = malloc(option->len); 241 memcpy(option->data, data, option->len); 242 243 ret = setjmp(env); 244 if (ret == 0) 245 expand_domain_search(&p); 246 247 if (ret != 1) 248 abort(); 249 250 free(option->data); 251 } 252 253 void 254 two_domains_truncatedptr() 255 { 256 int ret; 257 struct packet p; 258 struct option_data *option; 259 260 char *data = "\007example\003org\0\006foobar\xc0"; 261 262 option = &p.options[DHO_DOMAIN_SEARCH]; 263 option->len = 21; 264 option->data = malloc(option->len); 265 memcpy(option->data, data, option->len); 266 267 ret = setjmp(env); 268 if (ret == 0) 269 expand_domain_search(&p); 270 271 if (ret != 1) 272 abort(); 273 274 free(option->data); 275 } 276 277 void 278 multiple_domains_valid() 279 { 280 int ret; 281 struct packet p; 282 struct option_data *option; 283 284 char *data = 285 "\007example\003org\0\002cl\006foobar\003com\0\002fr\xc0\x10"; 286 287 char *expected = "example.org. cl.foobar.com. fr.foobar.com."; 288 289 option = &p.options[DHO_DOMAIN_SEARCH]; 290 option->len = 33; 291 option->data = malloc(option->len); 292 memcpy(option->data, data, option->len); 293 294 ret = setjmp(env); 295 if (ret == 0) 296 expand_domain_search(&p); 297 298 if (option->len != strlen(expected) || 299 strcmp(option->data, expected) != 0) 300 abort(); 301 302 free(option->data); 303 } 304 305 static 306 void 307 parse_date_helper(const char *string, time_t timestamp) 308 { 309 int ret = 0; 310 FILE *file = NULL; 311 time_t ts; 312 313 file = fopen("/tmp/dhclient.test", "w"); 314 if (!file) 315 abort(); 316 317 ret = fwrite(string, strlen(string), 1, file); 318 if (ret <= 0) 319 abort(); 320 321 fclose(file); 322 323 file = fopen("/tmp/dhclient.test", "r"); 324 if (!file) 325 abort(); 326 327 new_parse("test"); 328 ts = parse_date(file); 329 if (ts != timestamp) 330 abort(); 331 332 fclose(file); 333 } 334 335 void 336 parse_date_valid(void) 337 { 338 int ret; 339 340 ret = setjmp(env); 341 if (ret != 0) 342 abort(); 343 344 parse_date_helper(" 2 2024/7/2 20:25:50;\n", 1719951950); 345 #ifndef __i386__ 346 parse_date_helper(" 1 2091/7/2 20:25:50;\n", 3834246350); 347 #endif 348 } 349 350 int 351 main(int argc, char *argv[]) 352 { 353 354 no_option_present(); 355 356 one_domain_valid(); 357 one_domain_truncated1(); 358 one_domain_truncated2(); 359 360 two_domains_valid(); 361 two_domains_truncated1(); 362 two_domains_truncated2(); 363 364 two_domains_compressed(); 365 two_domains_infloop(); 366 two_domains_forwardptr(); 367 two_domains_truncatedptr(); 368 369 multiple_domains_valid(); 370 371 parse_date_valid(); 372 373 return (0); 374 } 375