int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr) { struct dhcpMessage packet; struct option_set *curr; unsigned char *lease_time; //Foxconn added start Bob Guo 11/15/2006 FILE *fp; unsigned char *client_mac, *client_ip; char logBuffer[96]; //Foxconn added end Bob Guo 11/15/2006 u_int32_t lease_time_align = server_config.lease; struct in_addr addr; init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; else if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; } add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); if (send_packet(&packet, 0) < 0) return -1; add_lease(packet.chaddr, packet.yiaddr, lease_time_align); //Foxconn added start Bob Guo 11/15/2006 client_mac = (unsigned char *)packet.chaddr; client_ip = (unsigned char *)&packet.yiaddr; sprintf(logBuffer, "[DHCP IP: (%d.%d.%d.%d)] to MAC address %02X:%02X:%02X:%02X:%02X:%02X,", *client_ip, *(client_ip+1), *(client_ip+2), *(client_ip+3), *client_mac, *(client_mac+1), *(client_mac+2), *(client_mac+3), *(client_mac+4), *(client_mac+5)); if ((fp = fopen("/dev/aglog", "r+")) != NULL) { fwrite(logBuffer, sizeof(char), strlen(logBuffer)+1, fp); fclose(fp); } //Foxconn added end Bob Guo 11/15/2006 return 0; }
static void init_packet(struct dhcpMessage *packet, struct dhcpMessage *oldpacket, char type) { memset(packet, 0, sizeof(struct dhcpMessage)); packet->op = BOOTREPLY; packet->htype = ETH_10MB; packet->hlen = ETH_10MB_LEN; packet->xid = oldpacket->xid; memcpy(packet->chaddr, oldpacket->chaddr, 16); packet->cookie = htonl(DHCP_MAGIC); packet->options[0] = DHCP_END; packet->flags = oldpacket->flags; packet->giaddr = oldpacket->giaddr; packet->ciaddr = oldpacket->ciaddr; add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type); add_simple_option(packet->options, DHCP_SERVER_ID, ntohl(server_config.server)); /* expects host order */ }
static void init_packet(struct dhcpMessage *packet, struct dhcpMessage *oldpacket, char type) { init_header(packet, type); packet->xid = oldpacket->xid; memcpy(packet->chaddr, oldpacket->chaddr, 16); packet->flags = oldpacket->flags; packet->giaddr = oldpacket->giaddr; packet->ciaddr = oldpacket->ciaddr; add_simple_option(packet->options, DHCP_SERVER_ID, server_config.server); }
int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr) { struct dhcpMessage packet; struct option_set *curr; unsigned char *lease_time; u_int32_t lease_time_align = server_config.lease; struct in_addr addr; init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; else if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; } add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; // LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); if(get_option(oldpacket, DHCP_SERVER_ID)){ // by honor LOG(LOG_INFO, "broadcasting ACK of %s to %02x:%02x:%02x:%02x:%02x:%02x", inet_ntoa(addr), packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]); if (send_packet(&packet, 1) < 0) return -1; } else{ LOG(LOG_INFO, "sending ACK of %s to %02x:%02x:%02x:%02x:%02x:%02x", inet_ntoa(addr), packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]); if (send_packet(&packet, 0) < 0) return -1; } add_lease(packet.chaddr, packet.yiaddr, lease_time_align); return 0; }
int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr) { struct dhcpMessage packet; struct option_set *curr; char *lease_time; u_int32_t lease_time_align = server_config.lease; struct in_addr addr; char *hostname; char hostname_copy[64]; init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; else if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; } add_simple_option(packet.options, DHCP_LEASE_TIME, lease_time_align); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); if (send_packet(&packet, 0) < 0) return -1; hostname = get_option(oldpacket, DHCP_HOST_NAME); memset(hostname_copy, 0, sizeof(hostname_copy)); if (hostname) { strncpy(hostname_copy, hostname, hostname[-1]); } add_lease(packet.chaddr, packet.yiaddr, lease_time_align, hostname_copy); return 0; }
int FAST_FUNC send_ACK(struct dhcpMessage *oldpacket, uint32_t yiaddr) { struct dhcpMessage packet; struct option_set *curr; uint8_t *lease_time; uint32_t lease_time_aligned = server_config.lease; struct in_addr addr; uint8_t *p_host_name; init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; lease_time = get_option(oldpacket, DHCP_LEASE_TIME); if (lease_time) { move_from_unaligned32(lease_time_aligned, lease_time); lease_time_aligned = ntohl(lease_time_aligned); if (lease_time_aligned > server_config.lease) lease_time_aligned = server_config.lease; else if (lease_time_aligned < server_config.min_lease) lease_time_aligned = server_config.min_lease; } add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; bb_info_msg("Sending ACK to %s", inet_ntoa(addr)); if (send_packet(&packet, 0) < 0) return -1; p_host_name = get_option(oldpacket, DHCP_HOST_NAME); add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned, p_host_name); if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) { /* rewrite the file with leases at every new acceptance */ write_leases(); } return 0; }
/* send a DHCP OFFER to a DHCP DISCOVER */ int sendOffer(struct dhcpMessage *oldpacket) { #ifdef DHCPD_HEAP_REPLACE_STACK struct dhcpMessage *packet; #else struct dhcpMessage packet; #endif struct dhcpOfferedAddr *lease = NULL; u_int32_t req_align, lease_time_align = server_config.lease; unsigned char *req, *lease_time; struct option_set *curr; //struct in_addr addr; #ifdef DHCPD_HEAP_REPLACE_STACK packet = calloc(1,sizeof(struct dhcpMessage)); if (!packet) { DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__); return -1; } init_packet(packet, oldpacket, DHCPOFFER); #else init_packet(&packet, oldpacket, DHCPOFFER); #endif /* ADDME: if static, short circuit */ /* the client is in our lease/offered table */ if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { if (!lease_expired(lease)) lease_time_align = lease->expires - time(0); #ifdef DHCPD_HEAP_REPLACE_STACK packet->yiaddr = lease->yiaddr; #else packet.yiaddr = lease->yiaddr; #endif /* Or the client has a requested ip */ } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) && /* Don't look here (ugly hackish thing to do) */ memcpy(&req_align, req, 4) && /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(server_config.start) && ntohl(req_align) <= ntohl(server_config.end) && /* and its not already taken/offered */ /* ADDME: check that its not a static lease */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ /* ADDME: or maybe in here */ lease_expired(lease)))) { #ifdef DHCPD_HEAP_REPLACE_STACK packet->yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ #else packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ #endif /* otherwise, find a free IP */ /*ADDME: is it a static lease? */ } else { #ifdef DHCPD_HEAP_REPLACE_STACK packet->yiaddr = find_address(0); /* try for an expired lease */ if (!packet->yiaddr) packet->yiaddr = find_address(1); #else packet.yiaddr = find_address(0); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address(1); #endif } #ifdef DHCPD_HEAP_REPLACE_STACK if(!(packet->yiaddr)) { if (packet != NULL) free(packet); #else if(!packet.yiaddr) { #endif DHCPD_LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned"); return -1; } #ifdef DHCPD_HEAP_REPLACE_STACK if (!add_lease(packet->chaddr, packet->yiaddr, server_config.offer_time)) { if (packet != NULL) { free(packet); packet = NULL; } #else if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { #endif DHCPD_LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); return -1; } if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; } /* Make sure we aren't just using the lease time from the previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; /* ADDME: end of short circuit */ #ifdef DHCPD_HEAP_REPLACE_STACK struct netif *netif = netif_find(server_config.interface); add_simple_option(packet->options, DHCP_LEASE_TIME, htonl(lease_time_align)); #ifdef __CONFIG_LWIP_V1 add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(&netif->netmask)); add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(&netif->gw)); add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(&netif->ip_addr)); #elif LWIP_IPV4 /* now only for IPv4 */ add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(ip_2_ip4(&netif->netmask))); add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(ip_2_ip4(&netif->gw))); add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(ip_2_ip4(&netif->ip_addr))); #else #error "IPv4 not support!" #endif #else add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); #endif curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) #ifdef DHCPD_HEAP_REPLACE_STACK add_option_string(packet->options, curr->data); #else add_option_string(packet.options, curr->data); #endif curr = curr->next; } #ifdef DHCPD_HEAP_REPLACE_STACK add_bootp_options(packet); //addr.s_addr = packet->yiaddr; DHCPD_LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(packet->yiaddr)); int ret = send_packet(packet, 0); if (packet != NULL) { free(packet); packet = NULL; } return ret; #else add_bootp_options(&packet); addr.s_addr = packet.yiaddr; DHCPD_LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); #endif } int sendNAK(struct dhcpMessage *oldpacket) { #ifdef DHCPD_HEAP_REPLACE_STACK struct dhcpMessage *packet; #else struct dhcpMessage packet; #endif #ifdef DHCPD_HEAP_REPLACE_STACK packet = calloc(1,sizeof(struct dhcpMessage)); if (!packet) DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__); init_packet(packet, oldpacket, DHCPNAK); #else init_packet(&packet, oldpacket, DHCPNAK); #endif DEBUG(LOG_INFO, "sending NAK"); #ifdef DHCPD_HEAP_REPLACE_STACK int ret = send_packet(packet, 1); if (packet != NULL) free(packet); return ret; #else return send_packet(&packet, 1); #endif } int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr) { #ifdef DHCPD_HEAP_REPLACE_STACK struct dhcpMessage *packet; #else struct dhcpMessage packet; #endif struct option_set *curr; unsigned char *lease_time; u_int32_t lease_time_align = server_config.lease; //struct in_addr addr; #ifdef DHCPD_HEAP_REPLACE_STACK packet = calloc(1,sizeof(struct dhcpMessage)); if (!packet) DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__); init_packet(packet, oldpacket, DHCPACK); packet->yiaddr = yiaddr; #else init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; #endif if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; else if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; } #ifdef DHCPD_HEAP_REPLACE_STACK struct netif *netif = netif_find(server_config.interface); add_simple_option(packet->options, DHCP_LEASE_TIME, htonl(lease_time_align)); #ifdef __CONFIG_LWIP_V1 add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(&netif->netmask)); add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(&netif->gw)); add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(&netif->ip_addr)); #elif LWIP_IPV4 /* now only for IPv4 */ add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(ip_2_ip4(&netif->netmask))); add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(ip_2_ip4(&netif->gw))); add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(ip_2_ip4(&netif->ip_addr))); #else #error "IPv4 not support!" #endif #else add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); #endif curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) #ifdef DHCPD_HEAP_REPLACE_STACK add_option_string(packet->options, curr->data); #else add_option_string(packet.options, curr->data); #endif curr = curr->next; } #ifdef DHCPD_HEAP_REPLACE_STACK add_bootp_options(packet); //addr.s_addr = packet->yiaddr; DHCPD_LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(packet->yiaddr)); int ret = 0; if (send_packet(packet, 0) < 0) ret = -1; add_lease(packet->chaddr, packet->yiaddr, lease_time_align); if (packet) free(packet); return ret; #else add_bootp_options(&packet); //addr.s_addr = packet.yiaddr; DHCPD_LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(packet->yiaddr)); if (send_packet(&packet, 0) < 0) return -1; add_lease(packet.chaddr, packet.yiaddr, lease_time_align); return 0; #endif } int send_inform(struct dhcpMessage *oldpacket) { #ifdef DHCPD_HEAP_REPLACE_STACK struct dhcpMessage *packet; #else struct dhcpMessage packet; #endif struct option_set *curr; #ifdef DHCPD_HEAP_REPLACE_STACK packet = calloc(1,sizeof(struct dhcpMessage)); if (!packet) DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__); init_packet(packet, oldpacket, DHCPACK); #else init_packet(&packet, oldpacket, DHCPACK); #endif curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) #ifdef DHCPD_HEAP_REPLACE_STACK add_option_string(packet->options, curr->data); #else add_option_string(packet.options, curr->data); #endif curr = curr->next; } #ifdef DHCPD_HEAP_REPLACE_STACK add_bootp_options(packet); int ret = send_packet(packet, 0); if (packet) free(packet); return ret; #else add_bootp_options(&packet); return send_packet(&packet, 0); #endif }
/* send a DHCP OFFER to a DHCP DISCOVER */ int FAST_FUNC send_offer(struct dhcpMessage *oldpacket) { struct dhcpMessage packet; uint32_t req_align; uint32_t lease_time_aligned = server_config.lease; uint32_t static_lease_ip; uint8_t *req, *lease_time, *p_host_name; struct option_set *curr; struct in_addr addr; init_packet(&packet, oldpacket, DHCPOFFER); static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr); /* ADDME: if static, short circuit */ if (!static_lease_ip) { struct dhcpOfferedAddr *lease; lease = find_lease_by_chaddr(oldpacket->chaddr); /* the client is in our lease/offered table */ if (lease) { signed_leasetime_t tmp = lease->expires - time(NULL); if (tmp >= 0) lease_time_aligned = tmp; packet.yiaddr = lease->yiaddr; /* Or the client has requested an ip */ } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL /* Don't look here (ugly hackish thing to do) */ && (move_from_unaligned32(req_align, req), 1) /* and the ip is in the lease range */ && ntohl(req_align) >= server_config.start_ip && ntohl(req_align) <= server_config.end_ip /* and is not already taken/offered */ && (!(lease = find_lease_by_yiaddr(req_align)) /* or its taken, but expired */ || lease_expired(lease)) ) { packet.yiaddr = req_align; /* otherwise, find a free IP */ } else { packet.yiaddr = find_free_or_expired_address(); } if (!packet.yiaddr) { bb_error_msg("no IP addresses to give - OFFER abandoned"); return -1; } p_host_name = get_option(oldpacket, DHCP_HOST_NAME); if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time, p_host_name)) { bb_error_msg("lease pool is full - OFFER abandoned"); return -1; } lease_time = get_option(oldpacket, DHCP_LEASE_TIME); if (lease_time) { move_from_unaligned32(lease_time_aligned, lease_time); lease_time_aligned = ntohl(lease_time_aligned); if (lease_time_aligned > server_config.lease) lease_time_aligned = server_config.lease; } /* Make sure we aren't just using the lease time from the previous offer */ if (lease_time_aligned < server_config.min_lease) lease_time_aligned = server_config.min_lease; } else { /* It is a static lease... use it */ packet.yiaddr = static_lease_ip; } add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); }
int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr) { struct dhcpMessage packet; struct option_set *curr; struct dhcpOfferedAddr *offerlist; char *lease_time, *vendorid, *userclsid; char length = 0; u_int32_t lease_time_align = cur_iface->lease; struct in_addr addr; //brcm begin char VIinfo[VENDOR_IDENTIFYING_INFO_LEN]; char *req; int saveVIoptionNeeded = 0; //brcm end init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; if ((lease_time = (char *)get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > cur_iface->lease) lease_time_align = cur_iface->lease; else if (lease_time_align < server_config.min_lease) lease_time_align = cur_iface->lease; } //<< jojopo : wifi leasetime 300 seconds , 2015/12/25 if(isHostFromWireless(packet.chaddr)) lease_time_align = 300; //>> jojopo : end add_simple_option(packet.options, DHCP_LEASE_TIME, lease_time_align); curr = cur_iface->options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); //brcm begin /* if DHCPRequest from client has device identity, send back gateway identity, and save the device identify */ if ((req = (char *)get_option(oldpacket, DHCP_VENDOR_IDENTIFYING))) { if (createVIoption(VENDOR_IDENTIFYING_FOR_GATEWAY, VIinfo) != -1) { add_option_string(packet.options, (unsigned char *)VIinfo); } saveVIoptionNeeded = 1; } //brcm end addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); if (send_packet(&packet, 0) < 0) return -1; add_lease(packet.chaddr, packet.yiaddr, lease_time_align); offerlist = find_lease_by_chaddr(packet.chaddr); if (saveVIoptionNeeded) { saveVIoption(req,offerlist); } vendorid = (char *)get_option(oldpacket, DHCP_VENDOR); userclsid = (char *)get_option(oldpacket, DHCP_USER_CLASS_ID); memset(offerlist->classid, 0, sizeof(offerlist->classid)); memset(offerlist->vendorid, 0, sizeof(offerlist->vendorid)); if( vendorid != NULL){ length = *(vendorid - 1); memcpy(offerlist->vendorid, vendorid, (size_t)length); offerlist->vendorid[(int)length] = '\0'; } if( userclsid != NULL){ length = *(userclsid - 1); memcpy(offerlist->classid, userclsid, (size_t)length); offerlist->classid[(int)length] = '\0'; } return 0; }
/* send a DHCP OFFER to a DHCP DISCOVER */ int sendOffer(struct dhcpMessage *oldpacket) { struct dhcpMessage packet; struct dhcpOfferedAddr *lease = NULL; u_int32_t req_align, lease_time_align = cur_iface->lease; char *req, *lease_time; struct option_set *curr; struct in_addr addr; //For static IP lease uint32_t static_lease_ip; //brcm begin char VIinfo[VENDOR_IDENTIFYING_INFO_LEN]; //brcm end init_packet(&packet, oldpacket, DHCPOFFER); //For static IP lease static_lease_ip = getIpByMac(cur_iface->static_leases, oldpacket->chaddr); if(!static_lease_ip) { /* the client is in our lease/offered table */ if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { if (!lease_expired(lease)) lease_time_align = lease->expires - time(0); packet.yiaddr = lease->yiaddr; /* Or the client has a requested ip */ } else if ((req = (char *)get_option(oldpacket, DHCP_REQUESTED_IP)) && /* Don't look here (ugly hackish thing to do) */ memcpy(&req_align, req, 4) && /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(cur_iface->start) && ntohl(req_align) <= ntohl(cur_iface->end) && /* and its not already taken/offered */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ lease_expired(lease)))) { packet.yiaddr = req_align; /* otherwise, find a free IP */ } else { packet.yiaddr = find_address(0); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address(1); } if(!packet.yiaddr) { LOG(LOG_WARNING, "no IP addresses to give -- " "OFFER abandoned"); return -1; } if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { LOG(LOG_WARNING, "lease pool is full -- " "OFFER abandoned"); return -1; } if ((lease_time = (char *)get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > cur_iface->lease) lease_time_align = cur_iface->lease; } /* Make sure we aren't just using the lease time from the * previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = cur_iface->lease; //<< jojopo : wifi leasetime 300 seconds , 2015/12/25 if(isHostFromWireless(packet.chaddr)) lease_time_align = 300; //>> jojopo : end } else { /* It is a static lease... use it */ packet.yiaddr = static_lease_ip; } add_simple_option(packet.options, DHCP_LEASE_TIME, lease_time_align); curr = cur_iface->options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); //brcm begin /* if DHCPDISCOVER from client has device identity, send back gateway identity */ if ((req = (char *)get_option(oldpacket, DHCP_VENDOR_IDENTIFYING))) { if (createVIoption(VENDOR_IDENTIFYING_FOR_GATEWAY, VIinfo) != -1) add_option_string(packet.options, (unsigned char *)VIinfo); } //brcm end addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); }
/* send a DHCP OFFER to a DHCP DISCOVER */ int send_offer(struct dhcpMessage *oldpacket) { struct dhcpMessage packet; struct dhcpOfferedAddr *lease = NULL; uint32_t req_align, lease_time_align = server_config.lease; uint8_t *req, *lease_time; struct option_set *curr; struct in_addr addr; uint32_t static_lease_ip; init_packet(&packet, oldpacket, DHCPOFFER); static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr); /* ADDME: if static, short circuit */ if (!static_lease_ip) { /* the client is in our lease/offered table */ lease = find_lease_by_chaddr(oldpacket->chaddr); if (lease) { if (!lease_expired(lease)) lease_time_align = lease->expires - time(0); packet.yiaddr = lease->yiaddr; /* Or the client has a requested ip */ } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) /* Don't look here (ugly hackish thing to do) */ && memcpy(&req_align, req, 4) /* and the ip is in the lease range */ && ntohl(req_align) >= server_config.start_ip && ntohl(req_align) <= server_config.end_ip && !static_lease_ip /* Check that its not a static lease */ /* and is not already taken/offered */ && (!(lease = find_lease_by_yiaddr(req_align)) /* or its taken, but expired */ /* ADDME: or maybe in here */ || lease_expired(lease)) ) { packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ /* otherwise, find a free IP */ } else { /* Is it a static lease? (No, because find_address skips static lease) */ packet.yiaddr = find_address(0); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address(1); } if (!packet.yiaddr) { bb_error_msg("no IP addresses to give - OFFER abandoned"); return -1; } if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { bb_error_msg("lease pool is full - OFFER abandoned"); return -1; } lease_time = get_option(oldpacket, DHCP_LEASE_TIME); if (lease_time) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; } /* Make sure we aren't just using the lease time from the previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; /* ADDME: end of short circuit */ } else { /* It is a static lease... use it */ packet.yiaddr = static_lease_ip; } add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); }
/* send a DHCP OFFER to a DHCP DISCOVER */ int sendOffer(struct dhcpMessage *oldpacket) { struct dhcpMessage packet; struct dhcpOfferedAddr *lease = NULL; u_int32_t req_align, lease_time_align = server_config.lease; unsigned char *req, *lease_time; struct option_set *curr; struct in_addr addr; unsigned char mac[6]; u_int32_t reserved_ip; memcpy(mac, oldpacket->chaddr, 6); init_packet(&packet, oldpacket, DHCPOFFER); /* ADDME: if static, short circuit */ /* the client is in our lease/offered table */ if ((lease = find_lease_by_chaddr(oldpacket->chaddr)) && /* Make sure the IP is not already used on network */ !check_ip(lease->yiaddr)) { if (!lease_expired(lease)) lease_time_align = lease->expires - time(0); packet.yiaddr = lease->yiaddr; /* Find a reserved ip for this MAC */ } else if ( (reserved_ip = find_reserved_ip(mac)) != 0) { packet.yiaddr = htonl(reserved_ip); /* Or the client has a requested ip */ } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) && /* Don't look here (ugly hackish thing to do) */ memcpy(&req_align, req, 4) && /* check if the requested ip has been reserved */ check_reserved_ip(req_align, mac) && /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(server_config.start) && ntohl(req_align) <= ntohl(server_config.end) && /* Check that this request ip is not on network */ //!check_ip(ntohl(req_align)) && /* the input parameter of check_ip() should be network order */ !check_ip(req_align) && /* modified by Max Ding, 07/07/2011 @TD #42 of WNR3500Lv2 */ /* and its not already taken/offered */ /* ADDME: check that its not a static lease */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ /* ADDME: or maybe in here */ lease_expired(lease)))) { packet.yiaddr = req_align; /* otherwise, find a free IP */ /*ADDME: is it a static lease? */ } else { packet.yiaddr = find_address2(0, mac); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address2(1, mac); } if(!packet.yiaddr) { LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned"); return -1; } if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); return -1; } if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; } /* Make sure we aren't just using the lease time from the previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; /* For guest network clients, set lease time to 30 minutes */ if (is_guest_network(mac)) { lease_time_align = GUEST_LEASE_TIME; DEBUG(LOG_INFO, "send OFFER to guest network client with lease time %d sec", GUEST_LEASE_TIME); } /* ADDME: end of short circuit */ add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); }
/* send a DHCP OFFER to a DHCP DISCOVER */ int sendOffer(struct dhcpMessage *oldpacket) { struct dhcpMessage packet; struct dhcpOfferedAddr *lease = NULL; u_int32_t req_align, lease_time_align = server_config.lease; unsigned char *req, *lease_time; struct option_set *curr; struct in_addr addr; init_packet(&packet, oldpacket, DHCPOFFER); /* ADDME: if static, short circuit */ /* the client is in our lease/offered table */ if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { if (!lease_expired(lease)) lease_time_align = lease->expires - time(0); packet.yiaddr = lease->yiaddr; /* Or the client has a requested ip */ } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) && /* Don't look here (ugly hackish thing to do) */ memcpy(&req_align, req, 4) && /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(server_config.start) && ntohl(req_align) <= ntohl(server_config.end) && /* and its not already taken/offered */ /* ADDME: check that its not a static lease */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ /* ADDME: or maybe in here */ lease_expired(lease)))) { packet.yiaddr = req_align; /* otherwise, find a free IP */ /*ADDME: is it a static lease? */ } else { packet.yiaddr = find_address(0); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address(1); } if(!packet.yiaddr) { LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned"); return -1; } if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); return -1; } if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; } /* Make sure we aren't just using the lease time from the previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; /* ADDME: end of short circuit */ add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); }
/* send a DHCP OFFER to a DHCP DISCOVER */ int sendOffer(struct dhcpMessage *oldpacket, struct dhcpOfferedAddr *lease) { struct dhcpMessage packet; u_int32_t req_align, lease_time_align = server_config.lease; unsigned char *req, *lease_time; struct option_set *curr; struct in_addr addr; unsigned long offer_time = server_config.offer_time; init_packet(&packet, oldpacket, DHCPOFFER); /* ADDME: if static, short circuit */ /* the client is in our lease/offered table */ if (lease) { #ifdef MY_DEBUG LOG(LOG_DEBUG,"(1)the client is in our lease/offered table"); #endif if(lease->expires == EXPIRES_NEVER) { /* static lease */ packet.yiaddr = lease->yiaddr; offer_time = EXPIRES_NEVER; /* offer infinite time */ } else if(!check_ip(lease->yiaddr)){ // Confirm the ip isn't used by someone, by honor if (!lease_expired(lease)) lease_time_align = lease->expires - get_time(0); else goto find_ip; packet.yiaddr = lease->yiaddr; } else goto find_ip; /* Or the client has a requested ip */ } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) && /* Don't look here (ugly hackish thing to do) */ memcpy(&req_align, req, 4) && /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(server_config.start) && ntohl(req_align) <= ntohl(server_config.end) && /* and its not already taken/offered */ /* ADDME: check that its not a static lease */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ /* ADDME: or maybe in here */ lease_expired(lease)))) { #ifdef MY_DEBUG LOG(LOG_DEBUG,"(2)the client has a requested ip"); #endif if(req_align == server_config.server) // The request ip cann't be router ip, by honor goto find_ip; else if(!check_ip(req_align)) // Confirm the ip isn't used by someone, by honor packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ else goto find_ip; /* otherwise, find a free IP */ /*ADDME: is it a static lease? */ } else { find_ip: // by honor #ifdef MY_DEBUG LOG(LOG_DEBUG,"(3)find a free IP"); #endif packet.yiaddr = find_address(0); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address(1); } if(!packet.yiaddr) { LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned"); return -1; } if (!add_lease(packet.chaddr, packet.yiaddr, offer_time)) { LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); return -1; } if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > server_config.lease) lease_time_align = server_config.lease; } /* Make sure we aren't just using the lease time from the previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = server_config.lease; /* ADDME: end of short circuit */ add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); curr = server_config.options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "broadcasting OFFER of %s to %02x:%02x:%02x:%02x:%02x:%02x", inet_ntoa(addr), packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]); return send_packet(&packet, 1); // Send broadcast rather than unicast, by honor }