/* $FreeBSD$ */ #include #include #include "dhcpd.h" jmp_buf env; void expand_domain_search(struct packet *packet); void no_option_present() { int ret; struct option_data option; struct packet p; option.data = NULL; option.len = 0; p.options[DHO_DOMAIN_SEARCH] = option; ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (p.options[DHO_DOMAIN_SEARCH].len != 0 || p.options[DHO_DOMAIN_SEARCH].data != NULL) abort(); } void one_domain_valid() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\0"; char *expected = "example.org."; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 13; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (option->len != strlen(expected) || strcmp(option->data, expected) != 0) abort(); free(option->data); } void one_domain_truncated1() { int ret; struct option_data *option; struct packet p; char *data = "\007example\003org"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 12; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void one_domain_truncated2() { int ret; struct option_data *option; struct packet p; char *data = "\007ex"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 3; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void two_domains_valid() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\0\007example\003com\0"; char *expected = "example.org. example.com."; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 26; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (option->len != strlen(expected) || strcmp(option->data, expected) != 0) abort(); free(option->data); } void two_domains_truncated1() { int ret; struct option_data *option; struct packet p; char *data = "\007example\003org\0\007example\003com"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 25; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void two_domains_truncated2() { int ret; struct option_data *option; struct packet p; char *data = "\007example\003org\0\007ex"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 16; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void two_domains_compressed() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\0\006foobar\xc0\x08"; char *expected = "example.org. foobar.org."; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 22; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (option->len != strlen(expected) || strcmp(option->data, expected) != 0) abort(); free(option->data); } void two_domains_infloop() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\0\006foobar\xc0\x0d"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 22; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void two_domains_forwardptr() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\xc0\x0d\006foobar\0"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 22; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void two_domains_truncatedptr() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\0\006foobar\xc0"; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 21; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (ret != 1) abort(); free(option->data); } void multiple_domains_valid() { int ret; struct packet p; struct option_data *option; char *data = "\007example\003org\0\002cl\006foobar\003com\0\002fr\xc0\x10"; char *expected = "example.org. cl.foobar.com. fr.foobar.com."; option = &p.options[DHO_DOMAIN_SEARCH]; option->len = 33; option->data = malloc(option->len); memcpy(option->data, data, option->len); ret = setjmp(env); if (ret == 0) expand_domain_search(&p); if (option->len != strlen(expected) || strcmp(option->data, expected) != 0) abort(); free(option->data); } int main(int argc, char *argv[]) { no_option_present(); one_domain_valid(); one_domain_truncated1(); one_domain_truncated2(); two_domains_valid(); two_domains_truncated1(); two_domains_truncated2(); two_domains_compressed(); two_domains_infloop(); two_domains_forwardptr(); two_domains_truncatedptr(); multiple_domains_valid(); return (0); }