📄 dhcp_client.c
字号:
*timer = (time_t) sysTicks;
return (time_t) (sysTicks);
}
/*******************************************************************************
*
* get_ipsum - retrieve the IP header checksum
*
* This routine fetches the checksum for the given IP header.
*
* RETURNS: Value of checksum in network byte order.
*
* ERRNO: N/A
*
* NOMANUAL
*/
u_short get_ipsum
(
struct ip * pIph /* IP header */
)
{
pIph->ip_sum = 0;
#if BSD<44
return (checksum ( (u_short *)pIph, (pIph->ip_v_hl & 0xf) << 2));
#else
return (checksum ( (u_short *)pIph, pIph->ip_hl << 2));
#endif
}
/*******************************************************************************
*
* check_ipsum - verify the IP header checksum
*
* This routine retrieves the checksum for the given IP header and compares
* it to the received checksum.
*
* RETURNS: TRUE if checksums match, or FALSE otherwise.
*
* ERRNO: N/A
*
* NOMANUAL
*/
BOOL check_ipsum
(
struct ip * pIph /* Received IP header */
)
{
u_short ripcksum; /* received IP checksum */
ripcksum = pIph->ip_sum;
return (ripcksum == get_ipsum (pIph));
}
/*******************************************************************************
*
* udp_cksum - calculate the UDP header checksum
*
* This routine calculates the checksum for the given UDP pseudo-header and
* additional bytes of data contained in the provided buffer, interpreted
* as unsigned shorts in network byte order.
*
* RETURNS: Value of calculated checksum, or 0xffff instead of 0.
*
* ERRNO: N/A
*
* NOMANUAL
*/
u_short udp_cksum
(
struct ps_udph *pUdpPh, /* UDP pseudo-header */
char *buf, /* Additional data (received UDP header) */
int n /* Length of provided buffer */
)
{
u_long sum = 0;
u_short * tmp = NULL;
u_short result;
FAST int i = 0;
unsigned char pad[2];
tmp = (u_short *) pUdpPh;
for (i = 0; i < 6; i++)
{
sum += *tmp++;
}
tmp = (u_short *)buf;
while (n > 1)
{
sum += *tmp++;
n -= sizeof (u_short);
}
if (n == 1) /* n % 2 == 1, so padding is needed */
{
pad [0] = *(u_char *)tmp;
pad [1] = 0;
tmp = (u_short *)pad;
sum += *tmp;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
result = (u_short) ~sum;
if (result == 0)
result = 0xffff;
return (result);
}
/*******************************************************************************
*
* get_udpsum - retrieve the UDP header checksum
*
* This routine fetches the checksum for a UDP header.
*
* RETURNS: Value of checksum in network byte order.
*
* ERRNO: N/A
*
* NOMANUAL
*/
u_short get_udpsum
(
struct ip * pIph, /* IP header */
struct udphdr * pUdph /* UDP header */
)
{
struct ps_udph UdpPh; /* UDP pseudo-header */
bzero ( (char *)&UdpPh, sizeof (UdpPh));
UdpPh.srcip.s_addr = pIph->ip_src.s_addr;
UdpPh.dstip.s_addr = pIph->ip_dst.s_addr;
UdpPh.zero = 0;
UdpPh.prto = IPPROTO_UDP;
UdpPh.ulen = pUdph->uh_ulen;
pUdph->uh_sum = 0;
return (udp_cksum (&UdpPh, (char *)pUdph, ntohs (UdpPh.ulen)));
}
/*******************************************************************************
*
* check_udpsum - verify the IP header checksum
*
* This routine retrieves the checksum for a UDP header and compares it
* to the received checksum.
*
* RETURNS: TRUE if checksums match, or FALSE otherwise.
*
* ERRNO: N/A
*
* NOMANUAL
*/
int check_udpsum
(
struct ip * pIph, /* Received IP header */
struct udphdr * pUdph /* Received UDP header */
)
{
u_short rudpcksum; /* received UDP checksum */
if (pUdph->uh_sum == 0)
return(TRUE);
rudpcksum = pUdph->uh_sum;
return (rudpcksum == get_udpsum (pIph, pUdph));
}
/*******************************************************************************
*
* bindcidcmp - verify client identifiers for active or offered leases
*
* This routine compares a hash table key against the client identifier
* contained in a lease record to verify matching types and values. It also
* checks the recorded subnet against the actual subnet. It is used to verify
* client information when establishing or renewing leases in response to DHCP
* request messages.
*
* RETURNS: TRUE if entries OK, or FALSE otherwise.
*
* ERRNO: N/A
*
* NOMANUAL
*/
int bindcidcmp
(
struct client_id * key, /* pointer to hash table key */
struct dhcp_binding * bp /* pointer to lease record */
)
{
return (bp != NULL &&
key->subnet.s_addr == bp->cid.subnet.s_addr &&
key->idtype == bp->cid.idtype && key->idlen == bp->cid.idlen &&
bcmp (key->id, bp->cid.id, key->idlen) == 0);
}
/*******************************************************************************
*
* bindhaddrcmp - verify hardware address for active or offered leases
*
* This routine compares a hash table key against the client identifier
* contained in a lease record to verify matching types and values. It also
* checks the recorded subnet against the actual subnet. It is used to verify
* client information when establishing or renewing leases in response to DHCP
* request messages.
*
* RETURNS: TRUE if entries OK, or FALSE otherwise.
*
* ERRNO: N/A
*
* NOMANUAL
*/
int bindhaddrcmp
(
struct chaddr * key, /* pointer to hash table key */
struct dhcp_binding * bp /* pointer to lease record */
)
{
return (bp != NULL &&
key->htype == bp->haddr.htype && key->hlen == bp->haddr.hlen &&
bcmp (key->haddr, bp->haddr.haddr, key->hlen) == 0);
}
int dhcp_client_set_server_addr(unsigned char *pIpString)
{
if(!pIpString) {
gDhcpClientGlobalConfig.serverIp = inet_addr(pIpString);
} else {
TRACE3("set dhcp server ip failed,input null\n");
return ERROR;
}
return OK;
}
int dhcp_client_set_client_addr(unsigned char *pIpString)
{
if(!pIpString) {
gDhcpClientGlobalConfig.localIp = inet_addr(pIpString);
} else {
TRACE3("set dhcp sim ip failed,input null\n");
return ERROR;
}
return OK;
}
int dhcp_client_set_discover_broadcast(unsigned int flag)
{
gDhcpClientGlobalConfig.discoverWithBroadcast = flag;
return OK;
}
int dhcp_client_unicast_out(St_DhcpBinding *pBinding)
{
DHCP_ASSERT(DHCP_BINDING_GOOD(pBinding) && DHCP_RES_GOOD(pBinding->pRes));
#ifdef BSSIM_BINDED_2_GW
/* fill ip/udp header */
pIpOut->ip_src.s_addr = htonl(pBinding->pRes->ip_addr.s_addr);
pIpOut->ip_dst.s_addr = htonl(pBinding->pRes->siaddr.s_addr);
pUdpOut->uh_sport = htons(DHCP_CPORT);
pUdpOut->uh_dport = htons(DHCP_SPORT);
pUdpOut->uh_ulen = htons (pBinding->msgLen+ UDPHL);
pUdpOut->uh_sum = get_udpsum (pIpOut, pUdpOut);
pIpOut->ip_v = IPVERSION;
pIpOut->ip_hl = IPHL >> 2;
pIpOut->ip_tos = 0;
pIpOut->ip_len = htons (pBinding->msgLen+ UDPHL + IPHL);
pIpOut->ip_id = pUdpOut->uh_sum;
pIpOut->ip_off = htons (IP_DF); /* XXX */
pIpOut->ip_ttl = 0x20; /* XXX */
pIpOut->ip_p = IPPROTO_UDP;
pIpOut->ip_sum = get_ipsum (pIpOut);
TRACE0("tx dhcp packet len %d msId 0x%02x%02x%02x-%02x%02x%02x internelId %d \n",
gDhcpClientMsgOut.pktLen,
gDhcpClientMsgOut.macAddr[0], gDhcpClientMsgOut.macAddr[1],
gDhcpClientMsgOut.macAddr[2], gDhcpClientMsgOut.macAddr[3],
gDhcpClientMsgOut.macAddr[4], gDhcpClientMsgOut.macAddr[5],
gDhcpClientMsgOut.gwupInternalId);
DUMP0(gDhcpClientMsgOut.pktBuf,gDhcpClientMsgOut.pktLen);
DUMP0((unsigned char *)&gDhcpClientMsgOut,sizeof(gDhcpClientMsgOut));
/* send to server's msgq*/
if(ERROR == msgQSend(AEP_MSG_Q_ID,(char *)&gDhcpClientMsgOut,
sizeof(gDhcpClientMsgOut),WAIT_FOREVER,MSG_PRI_NORMAL)) {
TRACE3("msgQ send failed\n");
return ERROR;
}
#else
gDhcpClientMsgOut.pktLen = pBinding->msgLen;
/* for notify r1macaddr to up sim */
bcopy(pBinding->r1MacAddr,&gDhcpClientMsgOut.pktBuf[gDhcpClientMsgOut.pktLen],6);
gDhcpClientMsgOut.pktLen += 6;
dhcp_client_tx_data_req((char *)gDhcpClientMsgOut.pktBuf,gDhcpClientMsgOut.pktLen,
pBinding->pRes->ip_addr.s_addr,pBinding->pRes->siaddr.s_addr,
DHCP_CPORT,DHCP_SPORT);
#endif
return OK;
}
int dhcp_client_broadcast_out(St_DhcpBinding *pBinding)
{
DHCP_ASSERT(DHCP_BINDING_GOOD(pBinding) && DHCP_RES_GOOD(pBinding->pRes));
#ifdef BSSIM_BINDED_2_GW
/* fill ip/udp header */
pIpOut->ip_src.s_addr = htonl(0);
pIpOut->ip_dst.s_addr = inet_addr("255.255.255.255");
pUdpOut->uh_sport = htons(DHCP_CPORT);
pUdpOut->uh_dport = htons(DHCP_SPORT);
/*pUdpOut->uh_ulen = htons (DFLTDHCPLEN + UDPHL);*/
pUdpOut->uh_ulen = htons (pBinding->msgLen+ UDPHL);
pUdpOut->uh_sum = get_udpsum (pIpOut, pUdpOut);
pIpOut->ip_v = IPVERSION;
pIpOut->ip_hl = IPHL >> 2;
pIpOut->ip_tos = 0;
/*pIpOut->ip_len = htons (DFLTDHCPLEN + UDPHL + IPHL);*/
pIpOut->ip_len = htons (pBinding->msgLen+ UDPHL + IPHL);
pIpOut->ip_id = pUdpOut->uh_sum;
pIpOut->ip_off = htons (IP_DF); /* XXX */
pIpOut->ip_ttl = 0x20; /* XXX */
pIpOut->ip_p = IPPROTO_UDP;
pIpOut->ip_sum = get_ipsum (pIpOut);
gDhcpClientMsgOut.pktLen = pBinding->msgLen+ UDPHL + IPHL;
TRACE0("IP packet, len %d\n",pIpOut->ip_len);
TRACE0("tx dhcp packet len %d msId 0x%02x%02x%02x-%02x%02x%02x internelId %d \n",
gDhcpClientMsgOut.pktLen,
gDhcpClientMsgOut.macAddr[0], gDhcpClientMsgOut.macAddr[1],
gDhcpClientMsgOut.macAddr[2], gDhcpClientMsgOut.macAddr[3],
gDhcpClientMsgOut.macAddr[4], gDhcpClientMsgOut.macAddr[5],
gDhcpClientMsgOut.gwupInternalId);
DUMP0(gDhcpClientMsgOut.pktBuf,gDhcpClientMsgOut.pktLen);
DUMP0((unsigned char *)&gDhcpClientMsgOut,sizeof(gDhcpClientMsgOut));
/* send to server's msgq*/
if(ERROR == msgQSend(AEP_MSG_Q_ID,(char *)&gDhcpClientMsgOut,
sizeof(gDhcpClientMsgOut),WAIT_FOREVER,MSG_PRI_NORMAL)) {
TRACE3("msgQ send failed\n");
return ERROR;
}
#else
gDhcpClientMsgOut.pktLen = pBinding->msgLen;
/* for notify r1macaddr to up sim */
bcopy(pBinding->r1MacAddr,&gDhcpClientMsgOut.pktBuf[gDhcpClientMsgOut.pktLen],6);
gDhcpClientMsgOut.pktLen += 6;
dhcp_client_tx_data_req((char *)gDhcpClientMsgOut.pktBuf,gDhcpClientMsgOut.pktLen,
0,gDhcpBroadcastIp,DHCP_CPORT,DHCP_SPORT);
#endif
return OK;
}
int dhcp_client_send_discover(unsigned char *pMsId)
{
St_DhcpBinding * pBinding = NULL;
if(NULL == (pBinding = dhcp_client_alloc_binding())) {
TRACE3("no binding\n");
return ERROR;
}
if(pMsId) {
bcopy(pMsId,pBinding->r1MacAddr,6);
TRACE2("get r1MacAddr 0x%02x%02x%02x-%02x%02x%02x\n",
pBinding->r1MacAddr[0],pBinding->r1MacAddr[1],pBinding->r1MacAddr[2],
pBinding->r1MacAddr[3],pBinding->r1MacAddr[4],pBinding->r1MacAddr[5]);
} else {
TRACE3("not get r1MacAddr\n");
}
TRACE2("trigger dhcp msId: 0x%02x%02x%02x-%02x%02x%02x\n",
pBinding->r1MacAddr[0],pBinding->r1MacAddr[1],pBinding->r1MacAddr[2],
pBinding->r1MacAddr[3],pBinding->r1MacAddr[4],pBinding->r1MacAddr[5]);
if(ERROR == make_discover(pBinding)) {
TRACE3("make discover failed\n");
dhcp_client_free_binding(pBinding);
return ERROR;
}
if (dhcp_client_broadcast_out(pBinding) == ERROR) {
TRACE3("broadcast out failed\n");
dhcp_client_free_binding(pBinding);
return ERROR;
}
gpDhcpClientTestBinding = pBinding;
return OK;
}
int dhcp_client_send_decline()
{
if (make_decline(gpDhcpClientTestBinding) == ERROR) {
TRACE3("make decline failed\n");
dhcp_client_free_binding(gpDhcpClientTestBinding);
return ERROR;
}
if (dhcp_client_broadcast_out(gpDhcpClientTestBinding) == ERROR) {
TRACE3("broadcast out failed\n");
dhcp_client_free_binding(gpDhcpClientTestBinding);
return ERROR;
}
return OK;
}
int dhcp_client_send_release()
{
if (make_release(gpDhcpClientTestBinding) == ERROR) {
TRACE3("make release failed\n");
dhcp_client_free_binding(gpDhcpClientTestBinding);
return ERROR;
}
if (gpDhcpClientTestBinding->pRes->siaddr.s_addr == 0) {
TRACE3("server ip is 0\n");
dhcp_client_free_binding(gpDhcpClientTestBinding);
return ERROR;
}
if(ERROR == dhcp_client_unicast_out(gpDhcpClientTestBinding)) {
TRACE3("unicast out failed\n");
dhcp_client_free_binding(gpDhcpClientTestBinding);
return ERROR;
}
dhcp_client_free_binding(gpDhcpClientTestBinding);
return OK;
}
int dhcp_client_set_hash(St_DhcpBinding *pBinding)
{
unsigned short hashKey;
St_DhcpBinding_List *pList = NULL;
if(pBinding == NULL ) {
TRACE3("set hash failed for input null\n");
return ERROR;
}
/* 1> set binding's cid and insert cid hash table by cid */
if(pBinding->cid.idlen) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -