int check_and_ack(struct dhcpMessage* packet, uint32_t ip) { uint32_t static_ip = 0; /* There is an Static IP for this guy, whether it is requested or not */ if ((static_ip = getIpByMac(server_config.static_leases, packet->chaddr)) != 0) { msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x, static ip %x", ip, static_ip); return sendACK(packet, static_ip); } /* requested ip is reserved by a static lease -- if it is himself, situation above match */ if (reservedIp(server_config.static_leases, ip)) { msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x is reserved as a static ip", ip); return sendNAK(packet); } /* if some one reserve it */ if ( ip != packet->ciaddr && check_ip(packet, ip) ) { msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x already reserved by someone", ip); return sendNAK(packet); } if (ntohl(ip) < ntohl(server_config.start) || ntohl(ip) > ntohl(server_config.end)) { msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x is not in the address pool", ip); return sendNAK(packet); } return sendACK(packet, ip); }
/* find an assignable address, it check_expired is true, we check all the expired leases as well. * Maybe this should try expired leases by age... */ uint32_t find_address(int check_expired) { uint32_t addr, ret; struct dhcpOfferedAddr *lease = NULL; addr = ntohl(server_config.start); /* addr is in host order here */ for (;addr <= ntohl(server_config.end); addr++) { /* ie, 192.168.55.0 */ if (!(addr & 0xFF)) continue; /* ie, 192.168.55.255 */ if ((addr & 0xFF) == 0xFF) continue; /* Only do if it isn't an assigned as a static lease */ if (!reservedIp(server_config.static_leases, htonl(addr))) { /* lease is not taken */ ret = htonl(addr); lease = find_lease_by_yiaddr(ret); /* no lease or it expired and we are checking for expired leases */ if ( (!lease || (check_expired && lease_expired(lease))) && /* and it isn't on the network */ !check_ip(ret) ) { return ret; break; } } } return 0; }
/* true if a lease has expired */ int lease_expired(struct dhcpOfferedAddr *lease) { #ifdef STATIC_LEASE if (reservedIp(server_config.static_leases, lease->yiaddr)) return 0; #endif return (lease->expires < (unsigned long) time(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; char *req, *lease_time; struct option_set *curr; char * l_vdfoption[OPTION_LEN]; int l_ilen = 0; struct in_addr addr; #ifdef VDF_OPTION //add for option125 char VIinfo[VENDOR_IDENTIFYING_INFO_LEN]; unsigned char StrOption121[OPTION121_LEN]; #endif /*start A36D02806, s60000658, 20060906*/ struct option_set *opt = NULL; u_int32_t router_ip = 0; if(NULL != (opt = find_option(server_config.options, DHCP_ROUTER))) { router_ip = *(u_int32_t*)(opt->data + 2); } /*end A36D02806, s60000658, 20060906*/ init_packet(&packet, oldpacket, DHCPOFFER); #ifdef SUPPORT_MACMATCHIP if ( !ismacmatch(oldpacket->chaddr) ) { packet.yiaddr = find_matchip(oldpacket->chaddr); } else #endif /* the client is in our lease/offered table */ if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { /*Start of Mod by y67514:time(0)取的系统时间会受SNTP影响,导致定时器混乱*/ if (!lease_expired(lease)) lease_time_align = lease->expires - getSysUpTime(); /*End of Mod by y67514:time(0)取的系统时间会受SNTP影响,导致定时器混乱*/ 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) && #ifdef VDF_RESERVED //and the ip is not the reserved ip reservedIp(req_align)&& #endif #ifdef SUPPORT_MACMATCHIP isipmatch(req_align) && #endif /* and its not already taken/offered */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ lease_expired(lease)))) { #ifdef SUPPORT_DHCP_FRAG int tmpNum = 1, i =0; if(1 == inmaster) { for(i = 0; i < 5; i++) { if(ntohl(req_align) >= ntohl(ipPool[i].start) && ntohl(req_align) <= ntohl(ipPool[i].end)) { tmpNum = 0; break; } } } #endif /*start of DHCP 网关会分配自己的维护IP porting by w44771 20060505*/ /*packet.yiaddr = req_align; */ if((req_align != server_config.server) #ifdef SUPPORT_DHCP_FRAG && (req_align != router_ip) && (1 == tmpNum))/*A36D02806, s60000658, 20060906*/ #else && (req_align != router_ip))/*A36D02806, s60000658, 20060906*/ #endif { packet.yiaddr = req_align; } else { #ifdef SUPPORT_DHCP_FRAG if(1 == inmaster)
/* find an assignable address, it check_expired is true, we check all the expired leases as well. * Maybe this should try expired leases by age... */ u_int32_t find_address(int check_expired) { u_int32_t addr, ret; struct dhcpOfferedAddr *lease = NULL; addr = ntohl(server_config.start); /* addr is in host order here */ for (;addr <= ntohl(server_config.end); addr++) { #if 1 /* Network IP and BroadcastIP ie. netmask 255.255.255.0, server ip 192.168.55.1 can't lease 192.168.55.0 or 192.168.55.255 */ if(addr==(server_config.netmask & server_config.server)) continue; if(addr==((~(server_config.netmask))|(server_config.server))) continue; #else /* ie, 192.168.55.0 */ if (!(addr & 0xFF)) continue; /* ie, 192.168.55.255 */ if ((addr & 0xFF) == 0xFF) continue; #endif /* not lease server ip */ if(addr == server_config.server) continue; #ifdef STATIC_LEASE /* Only do if it isn't an assigned as a static lease */ if(!reservedIp(server_config.static_leases, htonl(addr))) #endif { /* lease is not taken */ ret = htonl(addr); if ((!(lease = find_lease_by_yiaddr(ret)) || /* or it expired and we are checking for expired leases */ ( (check_expired == 1) && lease_expired(lease))) && /* and it isn't on the network */ !check_ip(ret)) { return ret; } else if(check_expired == 2) //some one leases this ip and this ip is not expired. { int arpping_time = 0; int ret_arpping = 0; //printf("\r\n Any one use this ip[%x]?",ret); for(arpping_time = 0; arpping_time<3; arpping_time++) { char ret_hwaddr[6]; if (arpping(ret, server_config.server, server_config.arp, server_config.interface, ret_hwaddr) == 0) { ret_arpping = 1; break; } } // But this ip is not alive in network. we release this ip if ( ret_arpping == 1) { //printf(" YES.__[%s-%u]\r\n",__FILE__,__LINE__); } else { //printf(" NO.__[%s-%u]\r\n",__FILE__,__LINE__); return ret; } } } } return 0; }