📄 dhcp.c
字号:
/*-------------------------------------------------------------------*/ dest.sin_family = AF_INET; if ((dhcp.state == DHCP_RENEW) || (type == DHCPRELEASE)) { route.gw = dest.sin_addr.s_addr = dhcp.serverID; } else { dest.sin_addr.s_addr = 0xFFFFFFFF; route.gw = 0; } dest.sin_port = htons(DHCP_SERV); sock->local.sin_addr.s_addr = ip_addr; route.ni = ni; route.flags = RT_GATEWAY; /*-------------------------------------------------------------------*/ /* Send datagram to server. */ /*-------------------------------------------------------------------*/ UdpSend(sock, &dest, buf, opts - &msg->op, &route);}/***********************************************************************//* parse_response: Parse response from DHCP server *//* *//* Returns: -1 if error found, otherwise DHCP message type *//* *//***********************************************************************/static int parse_response(DhcpMsg *msg){ ui8 *opt = &msg->options[0] + 4; ui8 overload = 0; int len, type = -1; uint xid; /*-------------------------------------------------------------------*/ /* Ensure message op code/type is BOOTREPLY. */ /*-------------------------------------------------------------------*/ if (msg->op != BOOTREPLY) return -1; /*-------------------------------------------------------------------*/ /* Ensure transaction ID matches that sent to server. */ /*-------------------------------------------------------------------*/ memcpy(&xid, &msg->xid, sizeof(xid)); if (xid != htonl(TransactionId)) return -1; /*-------------------------------------------------------------------*/ /* Verify presence of magic cookie value. */ /*-------------------------------------------------------------------*/ if ((msg->options[0] != 99) || (msg->options[1] != 130) || (msg->options[2] != 83) || (msg->options[3] != 99)) return -1; /*-------------------------------------------------------------------*/ /* Read "yiaddr" and save it as the address to be requested. */ /*-------------------------------------------------------------------*/ memcpy(&dhcp.reqAddr, &msg->yiaddr, IP_ALEN); /*-------------------------------------------------------------------*/ /* Loop until all options have been read. */ /*-------------------------------------------------------------------*/ for (;;) { /*-----------------------------------------------------------------*/ /* Parse each individual option. */ /*-----------------------------------------------------------------*/ switch (*opt++) { /*---------------------------------------------------------------*/ /* Adjust option pointer with padding option. */ /*---------------------------------------------------------------*/ case PADDING: ++opt; break; /*---------------------------------------------------------------*/ /* Read subnetwork's subnet mask. */ /*---------------------------------------------------------------*/ case SUBNET_MASK: /*-------------------------------------------------------------*/ /* Verify option length equals 4. */ /*-------------------------------------------------------------*/ if (*opt++ != 4) return -1; /*-------------------------------------------------------------*/ /* Read subnet mask, advance option pointer, and break. */ /*-------------------------------------------------------------*/ memcpy(&dhcp.subnetMask, opt, 4); opt += 4; break; case DNS_SERVER: /*-------------------------------------------------------------*/ /* Verify option length is >= 4 and is a multiple of 4. */ /*-------------------------------------------------------------*/ len = *opt++; if ((len < 4) || (len & 3)) return -1; /*-------------------------------------------------------------*/ /* If either DNS address is unconfigured, use this address. */ /*-------------------------------------------------------------*/ if (PriDnsServer == 0) memcpy(&PriDnsServer, opt, 4); else if (SecDnsServer == 0) memcpy(&SecDnsServer, opt, 4); if (PriDnsServer == SecDnsServer) SecDnsServer = 0; /*-------------------------------------------------------------*/ /* Advance option pointer and break. */ /*-------------------------------------------------------------*/ opt += len; break; /*---------------------------------------------------------------*/ /* Read IP address lease time granted by DHCP server. */ /*---------------------------------------------------------------*/ case LEASE_TIME: /*-------------------------------------------------------------*/ /* Verify option length equals 4. */ /*-------------------------------------------------------------*/ if (*opt++ != 4) return -1; /*-------------------------------------------------------------*/ /* Read lease time and advance option pointer. */ /*-------------------------------------------------------------*/ memcpy(&dhcp.leaseTime, opt, 4); opt += 4; /*-------------------------------------------------------------*/ /* Convert to host order, then break. */ /*-------------------------------------------------------------*/ dhcp.leaseTime = ntohl(dhcp.leaseTime); break; /*---------------------------------------------------------------*/ /* Flag locations of overloaded options. */ /*---------------------------------------------------------------*/ case OVERLOAD: /*-------------------------------------------------------------*/ /* Verify option length equals 1. */ /*-------------------------------------------------------------*/ if (*opt++ != 1) return -1; /*-------------------------------------------------------------*/ /* Read overload option value, advance pointer, and break. */ /*-------------------------------------------------------------*/ overload = *opt++; break; /*---------------------------------------------------------------*/ /* Unsupported option. */ /*---------------------------------------------------------------*/ default: opt = opt + 1 + *opt; break; /*---------------------------------------------------------------*/ /* Determine DHCP message type. */ /*---------------------------------------------------------------*/ case MSG_TYPE: /*-------------------------------------------------------------*/ /* Verify option length equals 1. */ /*-------------------------------------------------------------*/ if (*opt++ != 1) return -1; /*-------------------------------------------------------------*/ /* Read message type and verify it's value is legal. */ /*-------------------------------------------------------------*/ type = *opt++; if ((type < 1) || (type > 7)) return -1; break; /*---------------------------------------------------------------*/ /* Read ID of DHCP server. */ /*---------------------------------------------------------------*/ case SERVER_ID: /*-------------------------------------------------------------*/ /* Verify option length equals 4. */ /*-------------------------------------------------------------*/ if (*opt++ != 4) return -1; /*-------------------------------------------------------------*/ /* Read server identifier, advance option pointer, and break. */ /*-------------------------------------------------------------*/ memcpy(&dhcp.serverID, opt, 4); opt += 4; break; /*---------------------------------------------------------------*/ /* Read renewal timer value. */ /*---------------------------------------------------------------*/ case RENEWAL_T1: /*-------------------------------------------------------------*/ /* Verify option length equals 4. */ /*-------------------------------------------------------------*/ if (*opt++ != 4) return -1; /*-------------------------------------------------------------*/ /* Read renewal timer value and advance option pointer. */ /*-------------------------------------------------------------*/ memcpy(&dhcp.renewT1, opt, 4); opt += 4; /*-------------------------------------------------------------*/ /* Convert to host order, then break. */ /*-------------------------------------------------------------*/ dhcp.renewT1 = ntohl(dhcp.renewT1); break; /*---------------------------------------------------------------*/ /* Read rebind timer value. */ /*---------------------------------------------------------------*/ case REBINDING_T2: /*-------------------------------------------------------------*/ /* Verify option length equals 4. */ /*-------------------------------------------------------------*/ if (*opt++ != 4) return -1; /*-------------------------------------------------------------*/ /* Read rebind timer value and advance option pointer. */ /*-------------------------------------------------------------*/ memcpy(&dhcp.rebindT2, opt, 4); opt += 4; /*-------------------------------------------------------------*/ /* Convert to host order, then break. */ /*-------------------------------------------------------------*/ dhcp.rebindT2 = ntohl(dhcp.rebindT2); break; case ROUTER_IP: /*-------------------------------------------------------------*/ /* Verify option length is >= 4 and is a multiple of 4. */ /*-------------------------------------------------------------*/ len = *opt++; if ((len < 4) || (len & 3)) return -1; /*-------------------------------------------------------------*/ /* Read address of first router, advance pointer, and break. */ /*-------------------------------------------------------------*/ memcpy(&dhcp.router, opt, 4); opt += len; break; /*---------------------------------------------------------------*/ /* Finished reading options, sname, or file field. */ /*---------------------------------------------------------------*/ case OPTION_END: /*-------------------------------------------------------------*/ /* Exit if overloading finished or was never requested. */ /*-------------------------------------------------------------*/ if (overload == 0) return type; /*-------------------------------------------------------------*/ /* If file field overloaded, clear selection and set pointer. */ /*-------------------------------------------------------------*/ else if (overload & USE_FILE_FIELD) { overload &= ~USE_FILE_FIELD; opt = &msg->file[0]; } /*-------------------------------------------------------------*/ /* If sname field overloaded, clear selection and set pointer. */ /*-------------------------------------------------------------*/ else if (overload & USE_SNAME_FIELD) { overload &= ~USE_SNAME_FIELD; opt = &msg->sname[0]; } break; } }}/***********************************************************************//* get_response: UDP mode socket callback function *//* *//***********************************************************************/static void get_response(int sock_id, ui32 events){ SOCKET sock = &Socks[sock_id - 1]; NetBuf *buf; int type; /*-------------------------------------------------------------------*/ /* Return if no receive buffers are waiting. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -