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

📄 dhcpc_subr.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
* NOMANUAL*/int initialize    (    int 	serverPort, 	/* port monitored by DHCP servers */    int 	clientPort 	/* port monitored by DHCP client */    )    {    char * 	sbufp;    /* Always use default ports for client and server. */    dhcps_port = htons (serverPort);    dhcpc_port = htons (clientPort);    dhcpif.rbufsize = DFLTDHCPLEN + UDPHL + IPHL + ETHERHL;    /* Include offset to allow 4-byte alignment of IP header for Sun BSP's. */    dhcpif.rbuf = (char *)memalign (4, dhcpif.rbufsize + DHCPC_OFF);    if (dhcpif.rbuf == NULL)         {#ifdef DHCPC_DEBUG        logMsg ("allocation error for rbuf in initialize\n", 0, 0, 0, 0, 0, 0);#endif        return (-1);        }    bzero (dhcpif.rbuf, dhcpif.rbufsize + DHCPC_OFF);    pDhcpcRecvBuf = (char *)memalign (4, dhcpif.rbufsize + DHCPC_OFF);    if (pDhcpcRecvBuf == NULL)        {        return (-1);        }    bzero (pDhcpcRecvBuf, dhcpif.rbufsize + DHCPC_OFF);    sbuf.size = ETHERHL + IPHL + UDPHL + DFLTDHCPLEN;    /* Include offset to allow 4-byte alignment of IP header for Sun BSP's. */    if ( (sbuf.buf = (char *)memalign (4, sbuf.size + DHCPC_OFF)) == NULL)         {#ifdef DHCPC_DEBUG        logMsg ("allocation error for sbuf in initialize\n", 0, 0, 0, 0, 0, 0);#endif        return(-1);        }     bzero (sbuf.buf, sbuf.size + DHCPC_OFF);    sbufp = &sbuf.buf [DHCPC_OFF];    dhcpcMsgOut.ether = (struct ether_header *)sbufp;    dhcpcMsgOut.ip = (struct ip *)&sbufp [ETHERHL];    dhcpcMsgOut.udp = (struct udphdr *)&sbufp [ETHERHL + IPHL];    dhcpcMsgOut.dhcp = (struct dhcp *)&sbufp [ETHERHL + IPHL + UDPHL];    return (0);    }/********************************************************************************* reset_if - halt the network and reset the network interface** This routine sets the IP address of the network interface to a random* value of 10.x.x.x, which is an old ARPA debugging address, resets the* broadcast address and subnet mask, and flushes the routing tables.* It is called before initiating a lease negotiation if no event notification * hook is present. It is also always called for a lease established at boot * time, whether or not an event hook is registered for that lease.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void reset_if    (    struct if_info * 	pIfData 	/* interface used by lease */    )    {    struct in_addr addr;    struct in_addr mask;     struct in_addr brdaddr;    addr.s_addr = htonl ( (generate_xid (pIfData) & 0xfff) | 0x0a000000);    mask.s_addr = htonl (0xff000000);    brdaddr.s_addr = inet_addr ("255.255.255.255");    config_if (pIfData, &addr, &mask, &brdaddr);    flushroutes ();    }/********************************************************************************* down_if - change network interface flags** This routine clears the IFF_UP flag of the network interface. It is called* when a lease is manually terminated with a dhcpcRelease() or dhcpcShutdown()* call if no event hook is present for the lease. It is always called when* removing a lease established at boot time.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void down_if    (    struct if_info *ifp    )    {    int sockfd;    struct ifreq ridreq;    reset_if (ifp);    if ( (sockfd = socket (AF_INET, SOCK_RAW, 0)) < 0)         return;    bzero ( (char *)&ridreq, sizeof (struct ifreq));    sprintf (ridreq.ifr_name, "%s%d", ifp->name, ifp->unit);    ridreq.ifr_addr.sa_len = sizeof (struct sockaddr_in);    /* down interface */    ioctl (sockfd, SIOCGIFFLAGS, (int) (caddr_t) &ridreq);    ridreq.ifr_flags &= (~IFF_UP);    ioctl (sockfd, SIOCSIFFLAGS, (int) (caddr_t) &ridreq);    close (sockfd);    return;    }/********************************************************************************* config_if - configure network interface** This routine sets one or more of the current address, broadcast address, and * subnet mask, depending on whether or not the corresponding parameters are * NULL.  It is called when a lease is obtained or the network is reset. When a * new lease is obtained, a successful return value is used to cause assignment * of new routing tables.** RETURNS: -1 on error, 0 if new settings assigned, 1 otherwise.** ERRNO: N/A** NOMANUAL*/int config_if    (    struct if_info *ifp,    struct in_addr *addr,    struct in_addr *mask,    struct in_addr *brdcst    )    {    int sockfd = 0;    int status;    struct ifreq ifr;    struct in_addr current_addr;    struct in_addr  current_mask;    struct in_addr  current_brdcst;    if ( (sockfd = socket (AF_INET, SOCK_RAW, 0)) < 0)         return (-1);    bzero ( (char *)&current_addr, sizeof (current_addr));    bzero ( (char *)&current_mask, sizeof (current_mask));    bzero ( (char *)&current_brdcst, sizeof (current_brdcst));    bzero ( (char *)&ifr, sizeof (struct ifreq));    sprintf (ifr.ifr_name, "%s%d", ifp->name, ifp->unit);    ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);    status = ioctl (sockfd, SIOCGIFADDR, (int)&ifr);    current_addr.s_addr =                       ( (struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;    status = ioctl (sockfd, SIOCGIFNETMASK, (int)&ifr);    current_mask.s_addr =                       ( (struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;    status = ioctl (sockfd, SIOCGIFBRDADDR, (int)&ifr);    current_brdcst.s_addr =                  ( (struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr;    if (current_addr.s_addr == addr->s_addr &&        (mask == NULL || current_mask.s_addr == mask->s_addr) &&        (brdcst == NULL || current_brdcst.s_addr == brdcst->s_addr))         {        close (sockfd);        return (1);        }    flushroutes ();     /* down interface */    ioctl (sockfd, SIOCGIFFLAGS, (int)&ifr);    ifr.ifr_flags &= (~IFF_UP);    ioctl (sockfd, SIOCSIFFLAGS, (int)&ifr);    /*     * Deleting the interface address is required to correctly scrub the     * routing table based on the current netmask.     */    bzero ( (char *)&ifr, sizeof (struct ifreq));    sprintf (ifr.ifr_name, "%s%d", ifp->name, ifp->unit);    ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);    ( (struct sockaddr_in *) &ifr.ifr_addr)->sin_family = AF_INET;    ( (struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =                                                            current_addr.s_addr;    status = ioctl (sockfd, SIOCDIFADDR, (int)&ifr);    if (status < 0)         {         /* Sometimes no address has been set, so ignore that error. */        if (errno != EADDRNOTAVAIL)            {            close (sockfd);            return (-1);            }        }    if (mask != NULL)         {        bzero ( (char *)&ifr, sizeof (struct ifreq));        sprintf (ifr.ifr_name, "%s%d", ifp->name, ifp->unit);        ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);        ( (struct sockaddr_in *) &ifr.ifr_addr)->sin_family = AF_INET;        ( (struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =                                                                  mask->s_addr;        status = ioctl (sockfd, SIOCSIFNETMASK, (int)&ifr);        if (status < 0)             {            close (sockfd);            return (-1);            }        }    if (brdcst != NULL)         {        bzero ( (char *)&ifr, sizeof (struct ifreq));        sprintf (ifr.ifr_name, "%s%d", ifp->name, ifp->unit);        ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);        ( (struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_family = AF_INET;        ( (struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr =                                                                brdcst->s_addr;        status = ioctl (sockfd, SIOCSIFBRDADDR, (int)&ifr);        if (status < 0)             {            close (sockfd);            return (-1);            }        }    if (addr != NULL)         {        bzero ( (char *)&ifr, sizeof (struct ifreq));        sprintf (ifr.ifr_name, "%s%d", ifp->name, ifp->unit);        ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);        ( (struct sockaddr_in *) &ifr.ifr_addr)->sin_family = AF_INET;        ( (struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =                                                                  addr->s_addr;        status = ioctl (sockfd, SIOCSIFADDR, (int)&ifr);        if (status < 0)             {            close (sockfd);            return (-1);            }        }    /* bring interface back up */    ioctl (sockfd, SIOCGIFFLAGS, (int)&ifr);    ifr.ifr_flags |= IFF_UP;    ioctl (sockfd, SIOCSIFFLAGS, (int)&ifr);    close (sockfd);    return (0);    }/********************************************************************************* set_route - set network routing table** This routine is called when config_if() assigns new address information.* It sets the default route for a new lease if the DHCP server provided the* router IP address.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void set_route    (    struct dhcp_param *param    )    {    int sockfd = 0;#if BSD<44    struct rtentry rt;#else    struct ortentry rt;#endif    struct sockaddr dst, gateway;    if (param == NULL)        return;    sockfd = socket(AF_INET, SOCK_RAW, 0);    if (sockfd < 0)         {#ifdef DHCPC_DEBUG        logMsg("socket() error in set_route()\n", 0, 0, 0, 0, 0, 0);#endif        return;        }    /* set default route, if router IP address is available. */    if (ISSET(param->got_option, _DHCP_ROUTER_TAG) && param->router != NULL &&        param->router->addr != NULL)         {#if BSD<44        bzero ( (char *)&rt, sizeof (struct rtentry));#else        bzero ( (char *)&rt, sizeof (struct ortentry));#endif        bzero ( (char *)&dst, sizeof (struct sockaddr));        bzero ( (char *)&gateway, sizeof (struct sockaddr));        rt.rt_flags = RTF_UP | RTF_GATEWAY;        ( (struct sockaddr_in *)&dst)->sin_family = AF_INET;        ( (struct sockaddr_in *)&dst)->sin_len = sizeof (struct sockaddr_in);        ( (struct sockaddr_in *)&dst)->sin_addr.s_addr = INADDR_ANY;         ( (struct sockaddr_in *)&gateway)->sin_family = AF_INET;        ( (struct sockaddr_in *)&gateway)->sin_len =                                                    sizeof (struct sockaddr_in);        ( (struct sockaddr_in *)&gateway)->sin_addr.s_addr =                                                   param->router->addr->s_addr;        rt.rt_dst = dst;        rt.rt_gateway = gateway;        if (ioctl (sockfd, SIOCADDRT, (int)&rt) < 0)             {#ifdef DHCPC_DEBUG            logMsg ("SIOCADDRT (default route)\n", 0, 0, 0, 0, 0, 0);#endif            close (sockfd);            }        }    close (sockfd);    return;    }/********************************************************************************* make_decline - construct a DHCP decline message** This routine constructs an outgoing UDP/IP message containing the values* required to decline an offered IP address.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void make_decline    (    char *lsbuf,    struct dhcp_reqspec *pDhcpcReqSpec,    struct if_info * 	pIfData 	/* interface used by lease */    )    {    int offopt = 0;    /* offset in options field */    int i = 0;    u_long tmpul = 0;    struct dhcp    *lsdhcp = NULL;    struct udphdr  *lsudp = NULL;    struct ip      *lsip = NULL;    struct ether_header *lsether = NULL;    struct ps_udph pudph;    bzero ( (char *)&pudph, sizeof (pudph));    lsether = (struct ether_header *)lsbuf;    lsip = (struct ip *)&lsbuf [ETHERHL];    lsudp = (struct udphdr *)&lsbuf [ETHERHL + IPHL];    lsdhcp = (struct dhcp *)&lsbuf [ETHERHL + IPHL + UDPHL];    /* construct dhcp part */    lsdhcp->op = BOOTREQUEST;    lsdhcp->htype = pIfData->haddr.htype;    lsdhcp->hlen = pIfData->haddr.hlen;    lsdhcp->xid = generate_xid (pIfData);    lsdhcp->giaddr = dhcpcMsgIn.dhcp->giaddr;    bcopy (pIfData->haddr.haddr, lsdhcp->chaddr, lsdhcp->hlen);    /* insert magic cookie */    bcopy ( (char *)dhcpCookie, lsdhcp->options, MAGIC_LEN);    offopt = MAGIC_LEN;    /* insert message type */    lsdhcp->options [offopt++] = _DHCP_MSGTYPE_TAG;    lsdhcp->options [offopt++] = 1;    lsdhcp->options [offopt++] = DHCPDECLINE;    /* insert requested IP */    if (pDhcpcReqSpec->ipaddr.s_addr == 0)         return;    else if (CHKOFF (4)) 

⌨️ 快捷键说明

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