⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcpcboot.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
                            newEvent.length);        if (status != newEvent.length)  /* Error reading message - ignore. */            continue;        msgAlign (&dhcpcMsgIn, &rbuf.buf [DHCPC_OFF]);        option = (char *) pickup_opt (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp),                                      _DHCP_MSGTYPE_TAG);        if (option != NULL)             {	    if (*OPTBODY (option) == DHCPNAK)                 {#ifdef DHCPC_DEBUG	        logMsg ("Got DHCPNAK from server\n", 0, 0, 0, 0, 0, 0);#endif                option = (char *)pickup_opt (dhcpcMsgIn.dhcp,                                              DHCPLEN(dhcpcMsgIn.udp),                                              _DHCP_ERRMSG_TAG);#ifdef DHCPC_DEBUG                if (option != NULL &&                    nvttostr (OPTBODY (option), errmsg,                               (int)DHCPOPTLEN (option)) == 0)	            logMsg ("DHCPNAK contains the error message \"%s\"\n",                              (int)errmsg, 0, 0, 0, 0, 0);#endif                clean_param (dhcpcBootParam);                free (dhcpcBootParam);                dhcpcBootParam = NULL;                return (INIT);               /* Next state is INIT */	        }	    else                {                /* Fill in host requirements defaults. */                dhcpcBootDefaultsSet (&tmpparam);                   if (*OPTBODY (option) == DHCPACK &&                    dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp),                                     &tmpparam) == OK)                     {	            if ( (arpans = arp_check (&tmpparam.yiaddr)) == OK)                        {                         merge_param (dhcpcBootParam, &tmpparam);                        *dhcpcBootParam = tmpparam;                        dhcpcBootParam->lease_origin = dhcpcInitEpoch;#ifdef DHCPC_DEBUG                        inet_ntoa_b (dhcpcBootParam->yiaddr, newAddr);                        logMsg ("Got DHCPACK (IP = %s, duration = %d secs)\n",                                (int)newAddr, dhcpcBootParam->lease_duration,                                 0, 0, 0, 0);#endif                        dhcpcBindType = DHCP_NATIVE;                        return (BOUND);                        }                    else                         {                         /* make dhcp_declinfo and send DHCPDECLINE */                          set_declinfo (&tmp_reqspec, errmsg, arpans);                        dhcp_decline (&tmp_reqspec);                        clean_param (dhcpcBootParam);                        free (dhcpcBootParam);                        dhcpcBootParam = NULL;#ifdef DHCPC_DEBUG	                logMsg (                        "Received unacceptable DHCPACK. Entering INIT state.\n",                               0, 0, 0, 0, 0, 0);#endif	                return(INIT);                        }	            }	        }            }        }#ifdef DHCPC_DEBUG    if (status == DHCP_TIMEOUT)        logMsg ("Retransmission from requesting state.\n", 0, 0, 0, 0, 0, 0);#endif    retry++;    return(REQUESTING);    }/********************************************************************************* pickup_opt - extract an option from a DHCP message** This routine searches the fields in a DHCP message for the provided options* tag. If the file and sname message fields are overloaded with options,* they are searched as well. The search order is:**    options field -> 'file' field -> 'sname' field** RETURNS: Pointer to first occurrence of option, or NULL if not found.** ERRNO:   N/A** SEE ALSO: RFC 1533** NOMANUAL*/LOCAL char * 	pickup_opt    (    struct dhcp * 	msg,      /* Incoming message copied to structure */    int 		msglen,   /* Length of message */    char 		tag       /* RFC 1533 tag for desired option */    )    {    BOOL        sname_is_opt = FALSE;    BOOL        file_is_opt = FALSE;    int         i = 0;    char *      opt = NULL;    char *      found = NULL;    /*  search option field. */    opt = &msg->options[MAGIC_LEN];    for (i = 0; i < msglen - DFLTDHCPLEN + DFLTOPTLEN - MAGIC_LEN; i++)        {        if (*(opt + i) == tag)            {            found = (opt + i);            break;            }        else if (*(opt + i) == _DHCP_END_TAG)            break;        else if (*(opt + i) == _DHCP_OPT_OVERLOAD_TAG)            {            i += 2 ;            if (*(opt + i) == 1)                file_is_opt = TRUE;            else if (*(opt + i) == 2)                sname_is_opt = TRUE;            else if (*(opt + i) == 3)                file_is_opt = sname_is_opt = TRUE;            continue;            }        else if (*(opt + i) == _DHCP_PAD_TAG)            continue;        else            i += *(u_char *)(opt + i + 1) + 1;        }    if (found != NULL)        return (found);    /* If necessary, search file field. */    if (file_is_opt)        {        opt = msg->file;        for (i = 0; i < sizeof (msg->file); i++)             {             if (*(opt + i) == _DHCP_PAD_TAG)                 continue;             else if (*(opt + i) == _DHCP_END_TAG)                 break;             else if (*(opt + i) == tag)                 {                 found = (opt + i);                 break;                 }             else                 i += *(u_char *)(opt + i + 1) + 1;             }        if (found != NULL)            return (found);        }    /* If necessary, search sname field. */    if (sname_is_opt)        {        opt = msg->sname;        for (i = 0; i < sizeof (msg->sname); i++)            {            if (*(opt + i) == _DHCP_PAD_TAG)                continue;            else if (*(opt + i) == _DHCP_END_TAG)                break;            else if (*(opt + i) == tag)                {                found = (opt + i);                break;                }            else                i += *(u_char *)(opt + i + 1) + 1;            }        if (found != NULL)            return(found);        }    return(NULL);    }/********************************************************************************* generate_xid - generate a transaction identifier ** This routine forms a transaction identifier for outgoing messages from the* DHCP client. It is called from multiple locations after the initialization * routines have retrieved the network interface hardware address.** RETURNS: 32-bit transaction identifier in host byte order. ** ERRNO: N/A** NOMANUAL*/LOCAL long generate_xid    (    void    )    {    time_t current = 0;    u_short result1 = 0;    u_short result2 = 0;    u_short tmp[6];     bcopy (dhcpcIntface.haddr.haddr, (char *)tmp, 6);    time (&current);    result1 = checksum (tmp, 6);    result2 = checksum ( (u_short *)&current, 2);    return ( (result1 << 16) + result2);    }/********************************************************************************* msgAlign - set the buffer pointers to access message components** This routine sets the pointers in the given message descriptor* structure to access the various components of a received DHCP* message. It is used internally by the Ethernet input hooks and* the state machine routines.** RETURNS: N/A** ERRNO:   N/A** NOMANUAL*/void msgAlign    (    struct msg *rmsg, 	/* Components of received message */    char *rbuf 		/* Received Ethernet packet */    )    {    rmsg->ether = (struct ether_header *) rbuf;    rmsg->ip = (struct ip *) &rbuf[ETHERHL];    if ( (ntohs (rmsg->ip->ip_off) & 0x1fff) == 0 &&        ntohs (rmsg->ip->ip_len) >= DFLTBOOTPLEN + UDPHL + IPHL)        {#if BSD<44        rmsg->udp = (struct udphdr *)&rbuf [ETHERHL +                                         (rmsg->ip->ip_v_hl & 0xf) * WORD];        rmsg->dhcp = (struct dhcp *)&rbuf [ETHERHL +                                        (rmsg->ip->ip_v_hl & 0xf) * WORD +                                         UDPHL];#else        rmsg->udp = (struct udphdr *) &rbuf [ETHERHL +                                           rmsg->ip->ip_hl * WORD];        rmsg->dhcp = (struct dhcp *) &rbuf [ETHERHL +                                           rmsg->ip->ip_hl * WORD +                                          UDPHL];#endif        }    else        {        rmsg->udp = NULL;        rmsg->dhcp = NULL;        }    return;    }/********************************************************************************* 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*/LOCAL 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;    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] = *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);    }/********************************************************************************* arp_check - use ARP to check if given address is in use** This routine broadcasts an ARP request and waits for a reply to determine if* an IP address offered by a DHCP server is already in use.** RETURNS: ERROR if ARP indicates client in use, or OK otherwise.** ERRNO: N/A** NOMANUAL*/LOCAL int arp_check    (    struct in_addr *target    )    {    int i = 0;    long tmp;    char inbuf [ETHERHL + sizeof (struct ether_arp)];    struct ether_header *sether = NULL;    struct ether_arp *sarp = NULL;    STATUS result;    bzero (inbuf, ETHERHL + sizeof (struct ether_arp));    sether = (struct ether_header *) inbuf;    sarp = (struct ether_arp *) &inbuf [ETHERHL];    sarp->arp_hrd = htons (ARPHRD_ETHER);    sarp->arp_pro = htons (ETHERTYPE_IP);    sarp->arp_hln = 6;    sarp->arp_pln = 4;    sarp->arp_op = htons (ARPOP_REQUEST);    /* Set sender H/W address to your address for ARP requests. (RFC 1541). */    for (i = 0; i < 6; i++)         {        sarp->arp_sha[i] = sether->ether_shost[i] =                            dhcpcIntface.haddr.haddr[i];        sarp->arp_tha[i] = 0;        sether->ether_dhost[i] = 0xff;        }    /* Set sender IP address to 0 for ARP requests as per RFC 1541. */    tmp = 0;    bcopy ( (char *)&tmp, (char *)sarp->arp_spa, sarp->arp_pln);    bcopy ( (char *)&target->s_addr, (char *)sarp->arp_tpa, sarp->arp_pln);    sether->ether_type = ETHERTYPE_ARP;    if (etherOutput (dhcpcIntface.iface, sether, (char *)sarp,                      sizeof (struct ether_arp)) == ERROR)         {        return (OK);                      /* it is harmless to return 0 */        }     /* Set sender address to our address for checking by etherHook. */    bcopy ( (char *)&target->s_addr, (char *)dhcpcBootArpSpa, sarp->arp_pln);                   /* Create signalling semaphore. */    dhcpcBootArpEventSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);    if (dhcpcBootArpEventSem == NULL)        {#ifdef DHCPC_DEBUG        logMsg ("Error creating ARP semaphore.\n", 0, 0, 0, 0, 0, 0);#endif        return (OK);        }    /* Wait up to one-half a second for a reply. If none received, return 0. */    if (muxDevExists (dhcpcDevice.name, dhcpcDevice.unit))        etherInputHookAdd (dhcpcBootArpInputHook,                            dhcpcDevice.name, dhcpcDevice.unit);     else        etherInputHookAdd (dhcpcBootArpInputHook, NULL, dhcpcDevice.unit);    result = semTake (dhcpcBootArpEventSem, sysClkRateGet() / 2);     result = ERROR;    semDelete (dhcpcBootArpEventSem);     if (muxDevExists (dhcpcDevice.name, dhcpcDevice.unit))        etherInputHookDelete (dhcpcBootArpInputHook,                               dhcpcDevice.name, dhcpcDevice.unit);     else        etherInputHookDelete (dhcpcBootArpInputHook, NULL, dhcpcDevice.unit);    /* Restore previous input hook. */    if (result == ERROR)    /* Error indicates timeout occurred. */        return (OK);    else                    /* ARP reply received - duplicate IP address. */        return (ERROR);    }#ifdef DHCPC_DEBUG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -