diff --git a/src/bbl.h b/src/bbl.h index 6270b609..471d9fbe 100644 --- a/src/bbl.h +++ b/src/bbl.h @@ -715,7 +715,9 @@ typedef struct bbl_session_ struct timer_ *timer_auth; struct timer_ *timer_ipcp; struct timer_ *timer_ip6cp; - struct timer_ *timer_dhcp; + struct timer_ *timer_dhcp_retry; + struct timer_ *timer_dhcp_t1; + struct timer_ *timer_dhcp_t2; struct timer_ *timer_dhcpv6; struct timer_ *timer_igmp; struct timer_ *timer_zapping; @@ -811,6 +813,7 @@ typedef struct bbl_session_ /* IPv4 */ bool arp_resolved; uint32_t ip_address; + uint32_t ip_netmask; uint32_t peer_ip_address; uint32_t dns1; uint32_t dns2; @@ -827,13 +830,13 @@ typedef struct bbl_session_ /* DHCP */ dhcp_state_t dhcp_state; uint32_t dhcp_xid; - uint32_t dhcp_server; + uint32_t dhcp_address; + uint32_t dhcp_t1; + uint32_t dhcp_t2; uint32_t dhcp_server_identifier; - uint32_t lease_time; - struct timespec lease_timestamp; - struct timespec request_timestamp; + struct timespec dhcp_lease_timestamp; + struct timespec dhcp_request_timestamp; char *dhcp_client_identifier; - char *dhcp_server_name; char *dhcp_host_name; char *dhcp_domain_name; diff --git a/src/bbl_logging.c b/src/bbl_logging.c index 480cc59b..adfe6837 100644 --- a/src/bbl_logging.c +++ b/src/bbl_logging.c @@ -27,6 +27,7 @@ struct keyval_ log_names[] = { { IP, "ip" }, { LOSS, "loss" }, { L2TP, "l2tp" }, + { DHCP, "dhcp" }, { 0, NULL} }; diff --git a/src/bbl_logging.h b/src/bbl_logging.h index bcf85423..0d31fb4a 100644 --- a/src/bbl_logging.h +++ b/src/bbl_logging.h @@ -32,6 +32,7 @@ enum { IP, LOSS, L2TP, + DHCP, LOG_ID_MAX }; diff --git a/src/bbl_protocols.c b/src/bbl_protocols.c index dd528870..99aad3e5 100644 --- a/src/bbl_protocols.c +++ b/src/bbl_protocols.c @@ -268,7 +268,7 @@ encode_dhcp(uint8_t *buf, uint16_t *len, *(uint32_t*)buf = DHCP_MAGIC_COOKIE; BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); - *buf = DHCPV4_OPTION_DHCP_MESSAGE_TYPE; + *buf = DHCP_OPTION_DHCP_MESSAGE_TYPE; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = 1; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); @@ -276,35 +276,35 @@ encode_dhcp(uint8_t *buf, uint16_t *len, BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); if(dhcp->parameter_request_list) { - *buf = DHCPV4_OPTION_PARAM_REQUEST_LIST; + *buf = DHCP_OPTION_PARAM_REQUEST_LIST; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); option_len_ptr = buf; option_len = 0; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); if(dhcp->option_netmask) { option_len++; - *buf = DHCPV4_OPTION_SUBNET_MASK; + *buf = DHCP_OPTION_SUBNET_MASK; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } if(dhcp->option_router) { option_len++; - *buf = DHCPV4_OPTION_ROUTER; + *buf = DHCP_OPTION_ROUTER; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } if(dhcp->option_dns1 || dhcp->option_dns2) { option_len++; - *buf = DHCPV4_OPTION_DNS_SERVER; + *buf = DHCP_OPTION_DNS_SERVER; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } if(dhcp->option_domain_name) { option_len++; - *buf = DHCPV4_OPTION_DOMAIN_NAME; + *buf = DHCP_OPTION_DOMAIN_NAME; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } *option_len_ptr = option_len; } if(dhcp->client_identifier) { - *buf = DHCPV4_OPTION_CLIENT_IDENTIFIER; + *buf = DHCP_OPTION_CLIENT_IDENTIFIER; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = dhcp->client_identifier_len; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); @@ -312,7 +312,7 @@ encode_dhcp(uint8_t *buf, uint16_t *len, BUMP_WRITE_BUFFER(buf, len, dhcp->client_identifier_len); } if(dhcp->option_server_identifier) { - *buf = DHCPV4_OPTION_SERVER_IDENTIFIER; + *buf = DHCP_OPTION_SERVER_IDENTIFIER; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = 4; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); @@ -320,7 +320,7 @@ encode_dhcp(uint8_t *buf, uint16_t *len, BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); } if(dhcp->option_address) { - *buf = DHCPV4_OPTION_REQUESTED_IP_ADDRESS; + *buf = DHCP_OPTION_REQUESTED_IP_ADDRESS; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); *buf = 4; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); @@ -330,7 +330,7 @@ encode_dhcp(uint8_t *buf, uint16_t *len, if(dhcp->access_line) { /* RFC3046 Relay Agent Information Option (82) */ - *buf = DHCPV4_OPTION_RELAY_AGENT_INFORMATION; + *buf = DHCP_OPTION_RELAY_AGENT_INFORMATION; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); option_len_ptr = buf; option_len = 0; @@ -358,12 +358,12 @@ encode_dhcp(uint8_t *buf, uint16_t *len, *option_len_ptr = option_len; } - *buf = DHCPV4_OPTION_END; + *buf = DHCP_OPTION_END; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); /* This is optional ... */ while(*len % 8) { - *buf = DHCPV4_OPTION_PAD; + *buf = DHCP_OPTION_PAD; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } return PROTOCOL_SUCCESS; @@ -1714,7 +1714,7 @@ decode_dhcp(uint8_t *buf, uint16_t len, while(len >= 2) { option = *buf; BUMP_BUFFER(buf, len, sizeof(uint8_t)); - if(option == DHCPV4_OPTION_PAD) { + if(option == DHCP_OPTION_PAD) { continue; } option_len = *buf; @@ -1723,48 +1723,48 @@ decode_dhcp(uint8_t *buf, uint16_t len, return DECODE_ERROR; } switch(option) { - case DHCPV4_OPTION_END: + case DHCP_OPTION_END: option_len = len; break; - case DHCPV4_OPTION_DHCP_MESSAGE_TYPE: + case DHCP_OPTION_DHCP_MESSAGE_TYPE: if(option_len != 1) { return DECODE_ERROR; } dhcp->type = *buf; break; - case DHCPV4_OPTION_IP_ADDRESS_LEASE_TIME: + case DHCP_OPTION_IP_ADDRESS_LEASE_TIME: if(option_len != 4) { return DECODE_ERROR; } dhcp->lease_time = be32toh(*(uint32_t*)buf); dhcp->option_lease_time = true; break; - case DHCPV4_OPTION_CLIENT_IDENTIFIER: + case DHCP_OPTION_CLIENT_IDENTIFIER: dhcp->client_identifier = buf; dhcp->client_identifier_len = option_len; break; - case DHCPV4_OPTION_SERVER_IDENTIFIER: + case DHCP_OPTION_SERVER_IDENTIFIER: if(option_len != 4) { return DECODE_ERROR; } dhcp->server_identifier = *(uint32_t*)buf; dhcp->option_server_identifier = true; break; - case DHCPV4_OPTION_SUBNET_MASK: + case DHCP_OPTION_SUBNET_MASK: if(option_len != 4) { return DECODE_ERROR; } dhcp->netmask = *(uint32_t*)buf; dhcp->option_netmask = true; break; - case DHCPV4_OPTION_ROUTER: + case DHCP_OPTION_ROUTER: if(option_len < 4) { return DECODE_ERROR; } dhcp->router = *(uint32_t*)buf; dhcp->option_router = true; break; - case DHCPV4_OPTION_DNS_SERVER: + case DHCP_OPTION_DNS_SERVER: if(option_len < 4) { return DECODE_ERROR; } @@ -1775,15 +1775,15 @@ decode_dhcp(uint8_t *buf, uint16_t len, dhcp->option_dns2 = true; } break; - case DHCPV4_OPTION_HOST_NAME: + case DHCP_OPTION_HOST_NAME: dhcp->host_name = (char*)buf; dhcp->host_name_len = option_len; break; - case DHCPV4_OPTION_DOMAIN_NAME: + case DHCP_OPTION_DOMAIN_NAME: dhcp->domain_name = (char*)buf; dhcp->domain_name_len = option_len; break; - case DHCPV4_OPTION_INTERFACE_MTU: + case DHCP_OPTION_INTERFACE_MTU: if(option_len != 2) { return DECODE_ERROR; } diff --git a/src/bbl_protocols.h b/src/bbl_protocols.h index 443f5c5b..3b94028b 100644 --- a/src/bbl_protocols.h +++ b/src/bbl_protocols.h @@ -310,97 +310,97 @@ typedef enum dhcpv6_option_code_ { } dhcpv6_option_code; typedef enum dhcp_message_type_ { - DHCPV4_MESSAGE_DISCOVER = 1, - DHCPV4_MESSAGE_OFFER = 2, - DHCPV4_MESSAGE_REQUEST = 3, - DHCPV4_MESSAGE_DECLINE = 4, - DHCPV4_MESSAGE_ACK = 5, - DHCPV4_MESSAGE_NAK = 6, - DHCPV4_MESSAGE_RELEASE = 7, - DHCPV4_MESSAGE_INFORM = 8, - DHCPV4_MESSAGE_MAX + DHCP_MESSAGE_DISCOVER = 1, + DHCP_MESSAGE_OFFER = 2, + DHCP_MESSAGE_REQUEST = 3, + DHCP_MESSAGE_DECLINE = 4, + DHCP_MESSAGE_ACK = 5, + DHCP_MESSAGE_NAK = 6, + DHCP_MESSAGE_RELEASE = 7, + DHCP_MESSAGE_INFORM = 8, + DHCP_MESSAGE_MAX } dhcp_message_type; typedef enum dhcp_option_code_ { - DHCPV4_OPTION_PAD = 0, - DHCPV4_OPTION_SUBNET_MASK = 1, - DHCPV4_OPTION_TIME_OFFSET = 2, - DHCPV4_OPTION_ROUTER = 3, - DHCPV4_OPTION_TIME_SERVER = 4, - DHCPV4_OPTION_NAME_SERVER = 5, - DHCPV4_OPTION_DNS_SERVER = 6, - DHCPV4_OPTION_LOG_SERVER = 7, - DHCPV4_OPTION_COOKIE_SERVER = 8, - DHCPV4_OPTION_LPR_SERVER = 9, - DHCPV4_OPTION_IMPRESS_SERVER = 10, - DHCPV4_OPTION_RESOURCE_LOCATION_SERVER = 11, - DHCPV4_OPTION_HOST_NAME = 12, - DHCPV4_OPTION_BOOT_FILE_SIZE = 13, - DHCPV4_OPTION_MERIT_DUMP_FILE = 14, - DHCPV4_OPTION_DOMAIN_NAME = 15, - DHCPV4_OPTION_SWAP_SERVER = 16, - DHCPV4_OPTION_ROOT_PATH = 17, - DHCPV4_OPTION_EXTENSIONS_PATH = 18, - DHCPV4_OPTION_IP_FORWARDING = 19, - DHCPV4_OPTION_NON_LOCAL_SOURCE_ROUTING = 20, - DHCPV4_OPTION_POLICY_FILTER = 21, - DHCPV4_OPTION_MAX_DATAGRAM_REASSEMBLY_SIZE = 22, - DHCPV4_OPTION_DEFAULT_IP_TTL = 23, - DHCPV4_OPTION_PATH_MTU_AGING_TIMEOUT = 24, - DHCPV4_OPTION_PATH_MTU_PLATEAU_TABLE = 25, - DHCPV4_OPTION_INTERFACE_MTU = 26, - DHCPV4_OPTION_ALL_SUBNETS_ARE_LOCAL = 27, - DHCPV4_OPTION_BROADCAST_ADDRESS = 28, - DHCPV4_OPTION_PERFORM_MASK_DISCOVERY = 29, - DHCPV4_OPTION_MASK_SUPPLIER = 30, - DHCPV4_OPTION_PERFORM_ROUTER_DISCOVERY = 31, - DHCPV4_OPTION_ROUTER_SOLICITATION_ADDRESS = 32, - DHCPV4_OPTION_STATIC_ROUTE = 33, - DHCPV4_OPTION_TRAILER_ENCAPSULATION = 34, - DHCPV4_OPTION_ARP_CACHE_TIMEOUT = 35, - DHCPV4_OPTION_ETHERNET_ENCAPSULATION = 36, - DHCPV4_OPTION_TCP_DEFAULT_TTL = 37, - DHCPV4_OPTION_TCP_KEEPALIVE_INTERVAL = 38, - DHCPV4_OPTION_TCP_KEEPALIVE_GARBAGE = 39, - DHCPV4_OPTION_NIS_DOMAIN = 40, - DHCPV4_OPTION_NIS_SERVER = 41, - DHCPV4_OPTION_NTP_SERVER = 42, - DHCPV4_OPTION_VENDOR_SPECIFIC_INFO = 43, - DHCPV4_OPTION_NETBIOS_NBNS_SERVER = 44, - DHCPV4_OPTION_NETBIOS_NBDD_SERVER = 45, - DHCPV4_OPTION_NETBIOS_NODE_TYPE = 46, - DHCPV4_OPTION_NETBIOS_SCOPE = 47, - DHCPV4_OPTION_X11_FONT_SERVER = 48, - DHCPV4_OPTION_X11_DISPLAY_MANAGER = 49, - DHCPV4_OPTION_REQUESTED_IP_ADDRESS = 50, - DHCPV4_OPTION_IP_ADDRESS_LEASE_TIME = 51, - DHCPV4_OPTION_OPTION_OVERLOAD = 52, - DHCPV4_OPTION_DHCP_MESSAGE_TYPE = 53, - DHCPV4_OPTION_SERVER_IDENTIFIER = 54, - DHCPV4_OPTION_PARAM_REQUEST_LIST = 55, - DHCPV4_OPTION_MESSAGE = 56, - DHCPV4_OPTION_MAX_DHCP_MESSAGE_SIZE = 57, - DHCPV4_OPTION_RENEWAL_TIME_VALUE = 58, - DHCPV4_OPTION_REBINDING_TIME_VALUE = 59, - DHCPV4_OPTION_VENDOR_CLASS_IDENTIFIER = 60, - DHCPV4_OPTION_CLIENT_IDENTIFIER = 61, - DHCPV4_OPTION_NISP_DOMAIN = 64, - DHCPV4_OPTION_NISP_SERVER = 65, - DHCPV4_OPTION_TFTP_SERVER_NAME = 66, - DHCPV4_OPTION_BOOTFILE_NAME = 67, - DHCPV4_OPTION_MOBILE_IP_HOME_AGENT = 68, - DHCPV4_OPTION_SMTP_SERVER = 69, - DHCPV4_OPTION_POP3_SERVER = 70, - DHCPV4_OPTION_NNTP_SERVER = 71, - DHCPV4_OPTION_DEFAULT_WWW_SERVER = 72, - DHCPV4_OPTION_DEFAULT_FINGER_SERVER = 73, - DHCPV4_OPTION_DEFAULT_IRC_SERVER = 74, - DHCPV4_OPTION_STREETTALK_SERVER = 75, - DHCPV4_OPTION_STDA_SERVER = 76, - DHCPV4_OPTION_RAPID_COMMIT = 80, - DHCPV4_OPTION_RELAY_AGENT_INFORMATION = 82, - DHCPV4_OPTION_CAPTIVE_PORTAL = 160, - DHCPV4_OPTION_END = 255 + DHCP_OPTION_PAD = 0, + DHCP_OPTION_SUBNET_MASK = 1, + DHCP_OPTION_TIME_OFFSET = 2, + DHCP_OPTION_ROUTER = 3, + DHCP_OPTION_TIME_SERVER = 4, + DHCP_OPTION_NAME_SERVER = 5, + DHCP_OPTION_DNS_SERVER = 6, + DHCP_OPTION_LOG_SERVER = 7, + DHCP_OPTION_COOKIE_SERVER = 8, + DHCP_OPTION_LPR_SERVER = 9, + DHCP_OPTION_IMPRESS_SERVER = 10, + DHCP_OPTION_RESOURCE_LOCATION_SERVER = 11, + DHCP_OPTION_HOST_NAME = 12, + DHCP_OPTION_BOOT_FILE_SIZE = 13, + DHCP_OPTION_MERIT_DUMP_FILE = 14, + DHCP_OPTION_DOMAIN_NAME = 15, + DHCP_OPTION_SWAP_SERVER = 16, + DHCP_OPTION_ROOT_PATH = 17, + DHCP_OPTION_EXTENSIONS_PATH = 18, + DHCP_OPTION_IP_FORWARDING = 19, + DHCP_OPTION_NON_LOCAL_SOURCE_ROUTING = 20, + DHCP_OPTION_POLICY_FILTER = 21, + DHCP_OPTION_MAX_DATAGRAM_REASSEMBLY_SIZE = 22, + DHCP_OPTION_DEFAULT_IP_TTL = 23, + DHCP_OPTION_PATH_MTU_AGING_TIMEOUT = 24, + DHCP_OPTION_PATH_MTU_PLATEAU_TABLE = 25, + DHCP_OPTION_INTERFACE_MTU = 26, + DHCP_OPTION_ALL_SUBNETS_ARE_LOCAL = 27, + DHCP_OPTION_BROADCAST_ADDRESS = 28, + DHCP_OPTION_PERFORM_MASK_DISCOVERY = 29, + DHCP_OPTION_MASK_SUPPLIER = 30, + DHCP_OPTION_PERFORM_ROUTER_DISCOVERY = 31, + DHCP_OPTION_ROUTER_SOLICITATION_ADDRESS = 32, + DHCP_OPTION_STATIC_ROUTE = 33, + DHCP_OPTION_TRAILER_ENCAPSULATION = 34, + DHCP_OPTION_ARP_CACHE_TIMEOUT = 35, + DHCP_OPTION_ETHERNET_ENCAPSULATION = 36, + DHCP_OPTION_TCP_DEFAULT_TTL = 37, + DHCP_OPTION_TCP_KEEPALIVE_INTERVAL = 38, + DHCP_OPTION_TCP_KEEPALIVE_GARBAGE = 39, + DHCP_OPTION_NIS_DOMAIN = 40, + DHCP_OPTION_NIS_SERVER = 41, + DHCP_OPTION_NTP_SERVER = 42, + DHCP_OPTION_VENDOR_SPECIFIC_INFO = 43, + DHCP_OPTION_NETBIOS_NBNS_SERVER = 44, + DHCP_OPTION_NETBIOS_NBDD_SERVER = 45, + DHCP_OPTION_NETBIOS_NODE_TYPE = 46, + DHCP_OPTION_NETBIOS_SCOPE = 47, + DHCP_OPTION_X11_FONT_SERVER = 48, + DHCP_OPTION_X11_DISPLAY_MANAGER = 49, + DHCP_OPTION_REQUESTED_IP_ADDRESS = 50, + DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51, + DHCP_OPTION_OPTION_OVERLOAD = 52, + DHCP_OPTION_DHCP_MESSAGE_TYPE = 53, + DHCP_OPTION_SERVER_IDENTIFIER = 54, + DHCP_OPTION_PARAM_REQUEST_LIST = 55, + DHCP_OPTION_MESSAGE = 56, + DHCP_OPTION_MAX_DHCP_MESSAGE_SIZE = 57, + DHCP_OPTION_RENEWAL_TIME_VALUE = 58, + DHCP_OPTION_REBINDING_TIME_VALUE = 59, + DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, + DHCP_OPTION_CLIENT_IDENTIFIER = 61, + DHCP_OPTION_NISP_DOMAIN = 64, + DHCP_OPTION_NISP_SERVER = 65, + DHCP_OPTION_TFTP_SERVER_NAME = 66, + DHCP_OPTION_BOOTFILE_NAME = 67, + DHCP_OPTION_MOBILE_IP_HOME_AGENT = 68, + DHCP_OPTION_SMTP_SERVER = 69, + DHCP_OPTION_POP3_SERVER = 70, + DHCP_OPTION_NNTP_SERVER = 71, + DHCP_OPTION_DEFAULT_WWW_SERVER = 72, + DHCP_OPTION_DEFAULT_FINGER_SERVER = 73, + DHCP_OPTION_DEFAULT_IRC_SERVER = 74, + DHCP_OPTION_STREETTALK_SERVER = 75, + DHCP_OPTION_STDA_SERVER = 76, + DHCP_OPTION_RAPID_COMMIT = 80, + DHCP_OPTION_RELAY_AGENT_INFORMATION = 82, + DHCP_OPTION_CAPTIVE_PORTAL = 160, + DHCP_OPTION_END = 255 } dhcp_option_code; typedef enum access_line_codes_ { diff --git a/src/bbl_rx.c b/src/bbl_rx.c index 2c47aa95..14c370ea 100644 --- a/src/bbl_rx.c +++ b/src/bbl_rx.c @@ -974,10 +974,151 @@ bbl_rx_igmp(bbl_ipv4_t *ipv4, bbl_session_s *session) { } void -bbl_rx_dhcp(bbl_dhcp_t *dhcp, bbl_session_s *session) { - - UNUSED(dhcp); - UNUSED(session); +bbl_dhcp_restart(bbl_session_s *session) { + bbl_interface_s *interface = session->interface; + bbl_session_update_state(interface->ctx, session, BBL_IPOE_SETUP); + + /* Reset DHCP */ + timer_del(session->timer_dhcp_retry); + timer_del(session->timer_dhcp_t1); + timer_del(session->timer_dhcp_t2); + + session->dhcp_state = BBL_DHCP_SELECTING; + session->dhcp_xid = rand(); + session->dhcp_address = 0; + session->dhcp_t1 = 0; + session->dhcp_t2 = 0; + session->dhcp_server_identifier = 0; + session->dhcp_lease_timestamp.tv_sec = 0; + session->dhcp_lease_timestamp.tv_nsec = 0; + session->dhcp_request_timestamp.tv_sec = 0; + session->dhcp_request_timestamp.tv_nsec = 0; + if(session->dhcp_host_name) { + free(session->dhcp_host_name); + session->dhcp_host_name = NULL; + } + if(session->dhcp_host_name) { + free(session->dhcp_domain_name); + session->dhcp_domain_name = NULL; + } + session->send_requests |= BBL_SEND_DHCPREQUEST; + bbl_session_tx_qnode_insert(session); + + /* Reset session IP configuration */ + session->ip_address = 0; + session->ip_netmask = 0; + session->peer_ip_address = 0; + session->dns1 = 0; + session->dns2 = 0; + + /* Stop session traffic */ + timer_del(session->timer_session_traffic_ipv4); + + /* Stop multicast ... */ + timer_del(session->timer_igmp); + timer_del(session->timer_zapping); + session->zapping_joined_group = NULL; + session->zapping_leaved_group = NULL; + session->zapping_count = 0; + session->zapping_view_start_time.tv_sec = 0; + session->zapping_view_start_time.tv_nsec = 0; +} + +void +bbl_dhcp_t1(timer_s *timer) { + bbl_session_s *session = timer->data; + if(session->dhcp_state == BBL_DHCP_BOUND) { + session->dhcp_state = BBL_DHCP_RENEWING; + session->send_requests = BBL_SEND_DHCPREQUEST; + bbl_session_tx_qnode_insert(session); + } +} + +void +bbl_dhcp_t2(timer_s *timer) { + bbl_session_s *session = timer->data; + if(session->dhcp_state == BBL_DHCP_RENEWING) { + session->dhcp_state = BBL_DHCP_INIT; + /* TODO: Restart DHCP...!!! */ + } +} + +void +bbl_rx_dhcp(bbl_ethernet_header_t *eth, bbl_dhcp_t *dhcp, bbl_session_s *session) { + + UNUSED(eth); + if(dhcp->header->xid != session->dhcp_xid) { + return; + } + + switch(session->dhcp_state) { + case BBL_DHCP_SELECTING: + if(dhcp->type == DHCP_MESSAGE_OFFER) { + session->dhcp_state = BBL_DHCP_REQUESTING; + session->dhcp_address = dhcp->header->yiaddr; + session->dhcp_server_identifier = dhcp->server_identifier; + session->send_requests |= BBL_SEND_DHCPREQUEST; + bbl_session_tx_qnode_insert(session); + } + break; + case BBL_DHCP_REQUESTING: + if(dhcp->type == DHCP_MESSAGE_ACK) { + session->dhcp_state = BBL_DHCP_BOUND; + session->ip_address = dhcp->header->yiaddr; + if(dhcp->option_netmask) { + session->ip_netmask = dhcp->netmask; + } + if(dhcp->option_router) { + session->peer_ip_address = dhcp->router; + } + if(dhcp->option_dns1) { + session->dns1 = dhcp->dns1; + } + if(dhcp->option_dns2) { + session->dns2 = dhcp->dns2; + } + if(dhcp->option_host_name) { + if(session->dhcp_host_name) { + free(session->dhcp_host_name); + } + session->dhcp_host_name = calloc(1, dhcp->host_name_len +1); + strncpy(session->dhcp_host_name, dhcp->host_name, dhcp->host_name_len); + } + if(dhcp->option_domain_name) { + if(session->dhcp_domain_name) { + free(session->dhcp_domain_name); + } + session->dhcp_domain_name = calloc(1, dhcp->domain_name_len +1); + strncpy(session->dhcp_domain_name, dhcp->domain_name, dhcp->domain_name_len); + } + LOG(IP, "IPv4 (ID: %u) address %s/%s\n", session->session_id, + format_ipv4_address(&session->ip_address), + format_ipv4_address(&session->ip_netmask)); + + if(session->peer_ip_address) { + session->send_requests |= BBL_SEND_ARP_REQUEST; + bbl_session_tx_qnode_insert(session); + } else { + LOG(DHCP, "Missing DHCP router-option\n"); + } + } else if (dhcp->type == DHCP_MESSAGE_NAK) { + bbl_dhcp_restart(session); + } + break; + case BBL_DHCP_RENEWING: + if(dhcp->type == DHCP_MESSAGE_ACK) { + session->dhcp_state = BBL_DHCP_BOUND; + if(session->peer_ip_address) { + session->send_requests |= BBL_SEND_ARP_REQUEST; + bbl_session_tx_qnode_insert(session); + } + } else if (dhcp->type == DHCP_MESSAGE_NAK) { + bbl_dhcp_restart(session); + } + break; + default: + break; + } return; } @@ -1009,7 +1150,7 @@ bbl_rx_ipv4(bbl_ethernet_header_t *eth, bbl_ipv4_t *ipv4, bbl_interface_s *inter if (udp->protocol == UDP_PROTOCOL_DHCP) { session->stats.dhcp_rx++; interface->stats.dhcp_rx++; - return bbl_rx_dhcp((bbl_dhcp_t*)udp->next, session); + return bbl_rx_dhcp(eth, (bbl_dhcp_t*)udp->next, session); } if(udp->protocol == UDP_PROTOCOL_BBL) { bbl = (bbl_bbl_t*)udp->next; @@ -1959,8 +2100,6 @@ bbl_rx_handler_access(bbl_ethernet_header_t *eth, bbl_interface_s *interface) { session_id |= eth->dst[3] << 16; } - LOG(ERROR, "lets check for session %u\n", session_id); - session = bbl_session_get(ctx, session_id); if(session) { if(session->session_state != BBL_TERMINATED && diff --git a/src/bbl_session.c b/src/bbl_session.c index 5545a5aa..31a7ef9c 100644 --- a/src/bbl_session.c +++ b/src/bbl_session.c @@ -25,7 +25,7 @@ bbl_session_rate_job (timer_s *timer) { } /** - * bbl_session_update_state + * bbl_session_get * * This function allows to change the state of a session including * the required action caused by state changes. @@ -89,6 +89,9 @@ bbl_session_update_state(bbl_ctx_s *ctx, bbl_session_s *session, session_state_t timer_del(session->timer_auth); timer_del(session->timer_ipcp); timer_del(session->timer_ip6cp); + timer_del(session->timer_dhcp_retry); + timer_del(session->timer_dhcp_t1); + timer_del(session->timer_dhcp_t2); timer_del(session->timer_dhcpv6); timer_del(session->timer_igmp); timer_del(session->timer_zapping); diff --git a/src/bbl_tx.c b/src/bbl_tx.c index 15059981..04012d97 100644 --- a/src/bbl_tx.c +++ b/src/bbl_tx.c @@ -1194,11 +1194,13 @@ void bbl_dhcp_timeout (timer_s *timer) { bbl_session_s *session = timer->data; - - if(session->dhcp_state == BBL_DHCP_INIT || + + if(session->dhcp_state == BBL_DHCP_INIT || session->dhcp_state == BBL_DHCP_BOUND) { + /* Wrong state */ return; - } + } + session->send_requests = BBL_SEND_DHCPREQUEST; bbl_session_tx_qnode_insert(session); } @@ -1260,11 +1262,11 @@ bbl_encode_packet_dhcp (bbl_session_s *session) { * elapsed time, in seconds, since the client sent its first * BOOTREQUEST message. */ clock_gettime(CLOCK_REALTIME, &now); - if(session->request_timestamp.tv_sec) { - header.secs = now.tv_sec - session->request_timestamp.tv_sec; + if(session->dhcp_request_timestamp.tv_sec) { + header.secs = now.tv_sec - session->dhcp_request_timestamp.tv_sec; } else { header.secs = 0; - session->request_timestamp.tv_sec = now.tv_sec; + session->dhcp_request_timestamp.tv_sec = now.tv_sec; } /* Option 82 ... */ @@ -1276,7 +1278,7 @@ bbl_encode_packet_dhcp (bbl_session_s *session) { switch(session->dhcp_state) { case BBL_DHCP_SELECTING: - dhcp.type = DHCPV4_MESSAGE_DISCOVER; + dhcp.type = DHCP_MESSAGE_DISCOVER; dhcp.parameter_request_list = true; dhcp.option_netmask = true; dhcp.option_dns1 = true; @@ -1290,7 +1292,11 @@ bbl_encode_packet_dhcp (bbl_session_s *session) { } break; case BBL_DHCP_REQUESTING: - dhcp.type = DHCPV4_MESSAGE_REQUEST; + dhcp.type = DHCP_MESSAGE_REQUEST; + dhcp.option_address = true; + dhcp.address = session->dhcp_address; + dhcp.option_server_identifier = true; + dhcp.server_identifier = session->dhcp_server_identifier; dhcp.parameter_request_list = true; dhcp.option_netmask = true; dhcp.option_dns1 = true; @@ -1298,21 +1304,19 @@ bbl_encode_packet_dhcp (bbl_session_s *session) { dhcp.option_router = true; dhcp.option_host_name = true; dhcp.option_domain_name = true; - dhcp.option_address = true; - dhcp.server_identifier = session->dhcp_server_identifier; break; case BBL_DHCP_RENEWING: - dhcp.type = DHCPV4_MESSAGE_REQUEST; + dhcp.type = DHCP_MESSAGE_REQUEST; break; case BBL_DHCP_DHCPRELEASE: - dhcp.type = DHCPV4_MESSAGE_RELEASE; + dhcp.type = DHCP_MESSAGE_RELEASE; header.flags = 0; break; default: return IGNORED; } - timer_add(&ctx->timer_root, &session->timer_dhcp, "DHCP timeout", 5, 0, session, &bbl_dhcp_timeout); + timer_add(&ctx->timer_root, &session->timer_dhcp_retry, "DHCP timeout", 5, 0, session, &bbl_dhcp_timeout); interface->stats.dhcp_tx++; return encode_ethernet(session->write_buf, &session->write_idx, ð);