📄 opendhcpd.cpp
字号:
if (req->server || req->dhcpp.header.bp_sname[0]) { if (req->server == cfig.dhcpConn[req->sockInd].server || !strcasecmp(req->dhcpp.header.bp_sname, cfig.servername) || !strcasecmp(req->dhcpp.header.bp_sname, cfig.servername_fqn)) { if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t) { req->resp_type = DHCP_MESS_ACK; req->dhcpp.header.bp_yiaddr = req->reqIP; } else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t) { req->resp_type = DHCP_MESS_ACK; req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr; } else { if (cfig.logLevel >= 1) { sprintf(logBuff, "DHCP Request from Client %s, without Discover, ignored", req->hostname); logMess(logBuff, 1); } return 0; } } else { if (!req->hostname[0]) sprintf(req->hostname, "%s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, '-')); if (cfig.logLevel == 2) { if (req->dhcpp.header.bp_sname[0]) sprintf(logBuff, "DHCP Request from Client %s, for Server %s, ignored", req->hostname, req->dhcpp.header.bp_sname); else sprintf(logBuff, "DHCP Request from Client %s, for Server %s, ignored", req->hostname, IP2String(tempbuff, req->server)); logMess(logBuff, 2); } return 0; } } else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t) { req->resp_type = DHCP_MESS_ACK; req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr; } else if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t) { req->resp_type = DHCP_MESS_ACK; req->dhcpp.header.bp_yiaddr = req->reqIP; } else { if (cfig.logLevel == 2) { sprintf(logBuff, "DHCP Request from Client %s without Discover, ignored", req->hostname); logMess(logBuff, 1); } return 0; } } else return 0; addOptions(req); int packSize = (DWORD)(req->vp) - (DWORD)&req->dhcpp; packSize++; if (req->req_type == DHCP_MESS_NONE) packSize = req->bytes; if (req->dhcpp.header.bp_giaddr) { req->addr.sin_port = htons(IPPORT_DHCPS); req->addr.sin_addr.s_addr = req->dhcpp.header.bp_giaddr; } else if (req->dhcpp.header.bp_broadcast || !req->addr.sin_addr.s_addr) { req->addr.sin_port = htons(IPPORT_DHCPC); req->addr.sin_addr.s_addr = INADDR_BROADCAST; } else { req->addr.sin_port = htons(IPPORT_DHCPC); } req->dhcpp.header.bp_op = BOOTP_REPLY; errno = 0; req->bytes = sendto(cfig.dhcpConn[req->sockInd].sock, req->raw, packSize, 0, //MSG_DONTROUTE, (sockaddr*)&req->addr, sizeof(req->addr)); if (errno || req->bytes <= 0) return 0; //printf("goes=%s %i\n",IP2String(tempbuff, req->dhcpp.header.bp_yiaddr),req->sockInd); return req->dhcpp.header.bp_yiaddr;}DWORD alad(data1 *req){ time_t t = time(NULL); //printf("in\n"); if (req->dhcpEntry && (req->req_type == DHCP_MESS_NONE || req->resp_type == DHCP_MESS_ACK)) { DWORD retVal = updateDHCP(req); if (retVal) { if (cfig.logLevel == 2) { if (req->lease && req->reqIP) { sprintf(logBuff, "Client %s alotted %s for %u seconds", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease); } else if (req->lease) { sprintf(logBuff, "Client %s renewed %s for %u seconds", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease); } else if (req->hostname[0]) { sprintf(logBuff, "BOOTP Client %s alotted %s", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr)); } else { sprintf(logBuff, "BOOTP Client %s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':')); sprintf(logBuff + strlen(logBuff), " alotted %s", IP2String(tempbuff, req->dhcpp.header.bp_yiaddr)); } logMess(logBuff, 2); } sendRepl(req); return retVal; } } else if (cfig.logLevel == 2 && req->resp_type == DHCP_MESS_OFFER) { sprintf(logBuff, "Client %s offered %s", req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr)); logMess(logBuff, 2); } //printf("%u=out\n", req->resp_type); return 0;}void addOptions(data1 *req){ if (!req->messsize && req->req_type == DHCP_MESS_NONE) req->messsize = req->bytes; else if (!req->messsize) req->messsize = sizeof(dhcp_packet); data3 op; int i; if (req->resp_type) { op.opt_code = DHCP_OPTION_MESSAGETYPE; op.size = 1; op.value[0] = req->resp_type; pvdata(req, &op); } if (req->dhcpEntry && req->resp_type != DHCP_MESS_DECLINE && req->resp_type != DHCP_MESS_NAK) { if (req->dhcpEntry->fixed) { //printf("%u,%u\n", req->dhcpEntry->options, *req->dhcpEntry->options); BYTE *opPointer = req->dhcpEntry->options; if (opPointer) { BYTE requestedOnly = *opPointer; opPointer++; while (*opPointer && *opPointer < UCHAR_MAX) { op.size = *(opPointer + 1); if (!requestedOnly || req->paramreqlist[*opPointer]) { op.opt_code = *opPointer; memcpy(op.value, opPointer + 2, op.size); pvdata(req, &op); } opPointer += (op.size + 2); } } } if (req->resp_type) { if (req->dhcpEntry->rangeInd >= 0) { BYTE *opPointer = cfig.dhcpRanges[req->dhcpEntry->rangeInd].options; //printf("Range=%i Pointer=%u\n", req->dhcpEntry->rangeInd,opPointer); if (opPointer) { BYTE requestedOnly = *opPointer; opPointer++; while (*opPointer && *opPointer < UCHAR_MAX) { op.size = *(opPointer + 1); if (!requestedOnly || req->paramreqlist[*opPointer]) { op.opt_code = *opPointer; memcpy(op.value, opPointer + 2, op.size); pvdata(req, &op); } opPointer += (op.size + 2); } } } BYTE *opPointer = cfig.options; if (opPointer) { BYTE requestedOnly = *opPointer; opPointer++; while (*opPointer && *opPointer < UCHAR_MAX) { op.size = *(opPointer + 1); if (!requestedOnly || req->paramreqlist[*opPointer]) { op.opt_code = *opPointer; memcpy(op.value, opPointer + 2, op.size); pvdata(req, &op); } opPointer += (op.size + 2); } } if (!req->opAdded[DHCP_OPTION_SERVERID]) { op.opt_code = DHCP_OPTION_SERVERID; op.size = 4; pIP(op.value, cfig.dhcpConn[req->sockInd].server); pvdata(req, &op); strcpy(req->dhcpp.header.bp_sname, cfig.servername_fqn); }/* if (!req->opAdded[DHCP_OPTION_DOMAINNAME]) { op.opt_code = DHCP_OPTION_DOMAINNAME; op.size = strlen(cfig.zone); memcpy(op.value, cfig.zone, op.size); pvdata(req, &op); }*/ if (req->dhcpEntry->hostname && req->hostname[0] && strcasecmp(req->dhcpEntry->hostname, req->hostname)) { free(req->dhcpEntry->hostname); req->dhcpEntry->hostname = 0; } if (!req->dhcpEntry->hostname && req->hostname[0]) req->dhcpEntry->hostname = cloneString(req->hostname); if (!req->opAdded[DHCP_OPTION_HOSTNAME] && req->dhcpEntry->hostname) { op.opt_code = DHCP_OPTION_HOSTNAME; op.size = strlen(req->dhcpEntry->hostname); memcpy(op.value, req->dhcpEntry->hostname, op.size); pvdata(req, &op); } if (!req->opAdded[DHCP_OPTION_IPADDRLEASE]) { op.opt_code = DHCP_OPTION_IPADDRLEASE; op.size = 4; pULong(op.value, cfig.lease); pvdata(req, &op); } if (!req->opAdded[DHCP_OPTION_NETMASK]) { op.opt_code = DHCP_OPTION_NETMASK; op.size = 4; if (req->dhcpEntry->rangeInd >= 0) pIP(op.value, cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask); else pIP(op.value, cfig.dhcpConn[req->sockInd].mask); pvdata(req, &op); } if (req->clientId.opt_code == DHCP_OPTION_CLIENTID) pvdata(req, &req->clientId); if (req->agentOption.opt_code == DHCP_OPTION_RELAYAGENTINFO) pvdata(req, &req->agentOption); } } *(req->vp) = DHCP_OPTION_END;}void pvdata(data1 *req, data3 *op){ if (!req->opAdded[op->opt_code] && (((DWORD)req->vp - (DWORD)&req->dhcpp) + op->size < req->messsize)) { if (op->opt_code == DHCP_OPTION_BOOTFILE) memcpy(req->dhcpp.header.bp_file, op->value, op->size); else if (op->opt_code == DHCP_OPTION_NEXTSERVER) req->dhcpp.header.bp_siaddr = fIP(op->value); else if(op->size) { if (op->opt_code == DHCP_OPTION_IPADDRLEASE) { if (!req->lease || req->lease > fULong(op->value)) req->lease = fULong(op->value); if (req->dhcpEntry->no_route || req->lease >= LONG_MAX) req->lease = ULONG_MAX; pULong(op->value, req->lease); } else if (op->opt_code == DHCP_OPTION_HOSTNAME) { memset(req->hostname, 0, sizeof(req->hostname)); memcpy(req->hostname, op->value, op->size); } memcpy(req->vp, op, (op->size + 2)); (req->vp) += 2; (req->vp) += op->size; } req->opAdded[op->opt_code] = true; }}DWORD updateDHCP(data1 *req){ time_t t = time(NULL); data8 *dhcpData = (data8*)calloc(1, sizeof(data8)); strcpy(dhcpData->hostname, req->hostname); memcpy(dhcpData->bp_chaddr, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen); dhcpData->bp_hlen = req->dhcpp.header.bp_hlen; dhcpData->ip = req->dhcpEntry->ip; if (!req->dhcpEntry->fixed) dhcpData->source = req->dhcpEntry->source; if (!req->req_type) { dhcpData->expiry = LONG_MAX; setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST); } else if (req->lease > (DWORD)(LONG_MAX - t)) { dhcpData->expiry = LONG_MAX; setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST); } else if (req->lease) { dhcpData->expiry = t + req->lease; setLeaseExpiry(req->dhcpEntry, req->lease, req->req_type == DHCP_MESS_REQUEST); } else { dhcpData->expiry = 0; req->dhcpEntry->expiry = 0; } if (req->dhcpEntry->dhcpInd) dhcpData->dhcpInd = req->dhcpEntry->dhcpInd; else { cfig.dhcpIndex++; req->dhcpEntry->dhcpInd = cfig.dhcpIndex; } dhcpData->local = req->dhcpEntry->local; pthread_t threadId; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); int errcode = pthread_create(&threadId, &attr, updateStateFile, (void*)dhcpData); pthread_attr_destroy(&attr); if(errcode) { if (cfig.logLevel) { sprintf(logBuff, "Thread Creation Failed"); logMess(logBuff, 1); } free(dhcpData); } return req->dhcpEntry->ip;}void setLeaseExpiry(data7 *dhcpEntry, time_t expiry, bool local){ //printf("%u\n", local); time_t t = time(NULL); if (dhcpEntry && dhcpEntry->ip) { if (LONG_MAX - t < expiry) dhcpEntry->expiry = LONG_MAX; else dhcpEntry->expiry = t + expiry; dhcpEntry->local = local; if (dhcpEntry->rangeInd >= 0 && dhcpEntry->rangeInd < 32) { DWORD iip = htonl(dhcpEntry->ip); if (iip >= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart && iip <= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeEnd) { int ind = iip - cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart; if (cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] != LONG_MAX) cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] = dhcpEntry->expiry; cfig.dhcpRanges[dhcpEntry->rangeInd].dhcpEntry[ind] = dhcpEntry; } } }}void setLeaseExpiry(DWORD ip, time_t expiry){ time_t t = time(NULL); if (ip) { DWORD iip = htonl(ip); for (char rangeInd = 0; rangeInd < 32 && cfig.dhcpRanges[rangeInd].rangeStart; rangeInd++) { if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd) { int ind = iip - cfig.dhcpRanges[rangeInd].rangeStart; if (cfig.dhcpRanges[rangeInd].expiry[ind] != LONG_MAX) { if (LONG_MAX - t < expiry) cfig.dhcpRanges[rangeInd].expiry[ind] = LONG_MAX; else cfig.dhcpRanges[rangeInd].expiry[ind] = t + expiry; } break; } } }}DWORD sendRepl(data1 *req){ data3 op; if (cfig.replication == 1) req->target.sin_addr.s_addr = cfig.zoneServers[1]; else if (cfig.replication == 2) req->target.sin_addr.s_addr = cfig.zoneServers[0]; else return 0; req->target.sin_port = htons(IPPORT_DHCPS); req->target.sin_family = AF_INET; BYTE *opPointer = req->dhcpp.vend_data; while ((*opPointer) < UCHAR_MAX && opPointer < req->vp) { if ((*opPointer) == DHCP_OPTION_MESSAGETYPE) { *(opPointer + 2) = DHCP_MESS_INFORM; break; } opPointer = opPointer + *(opPointer + 1) + 2; } if (opPointer >= req->vp) { op.opt_code = DHCP_OPTION_MESSAGETYPE; op.size = 1; op.value[0] = DHCP_MESS_INFORM; memcpy(req->vp, &op, (op.size + 2)); (req->vp) += 2; (req->vp) += op.size; } op.opt_code = DHCP_OPTION_SERIAL; op.size = 4; pULong(op.value, time(NULL)); memcpy(req->vp, &op, (op.size + 2)); (req->vp) += 2; (req->vp) += op.size; //printf("Here1 %u\n",req->vp); *(req->vp) = 255; req->bytes = (DWORD)req->vp - (DWORD)req->raw; req->bytes++; //printf("Here2\n"); req->dhcpp.header.bp_op = BOOTP_REQUEST; errno = 0; //printf("%i\n", req->bytes); req->bytes = sendto(cfig.dhcpReplConn.sock, req->raw, req->bytes, 0, (sockaddr*)&req->target,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -