📄 dhcpc.c
字号:
/**************************************************************************** * netutils/dhcpc/dhcpc.c * * Copyright (C) 2007 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Based heavily on portions of uIP: * * Author: Adam Dunkels <adam@dunkels.com> * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <sys/types.h>#include <sys/socket.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>#include <errno.h>#include <debug.h>#include <net/uip/uip.h>#include <net/uip/dhcpc.h>#include <net/uip/uip-lib.h>/**************************************************************************** * Definitions ****************************************************************************/#define STATE_INITIAL 0#define STATE_HAVE_OFFER 1#define STATE_HAVE_LEASE 2#define BOOTP_BROADCAST 0x8000#define DHCP_REQUEST 1#define DHCP_REPLY 2#define DHCP_HTYPE_ETHERNET 1#define DHCP_HLEN_ETHERNET 6#define DHCP_MSG_LEN 236#define DHCPC_SERVER_PORT 67#define DHCPC_CLIENT_PORT 68#define DHCPDISCOVER 1#define DHCPOFFER 2#define DHCPREQUEST 3#define DHCPDECLINE 4#define DHCPACK 5#define DHCPNAK 6#define DHCPRELEASE 7#define DHCP_OPTION_SUBNET_MASK 1#define DHCP_OPTION_ROUTER 3#define DHCP_OPTION_DNS_SERVER 6#define DHCP_OPTION_REQ_IPADDR 50#define DHCP_OPTION_LEASE_TIME 51#define DHCP_OPTION_MSG_TYPE 53#define DHCP_OPTION_SERVER_ID 54#define DHCP_OPTION_REQ_LIST 55#define DHCP_OPTION_END 255#define BUFFER_SIZE 256/**************************************************************************** * Private Types ****************************************************************************/struct dhcp_msg{ uint8 op; uint8 htype; uint8 hlen; uint8 hops; uint8 xid[4]; uint16 secs; uint16 flags; uint8 ciaddr[4]; uint8 yiaddr[4]; uint8 siaddr[4]; uint8 giaddr[4]; uint8 chaddr[16];#ifndef CONFIG_NET_DHCP_LIGHT uint8 sname[64]; uint8 file[128];#endif uint8 options[312];};struct dhcpc_state_s{ struct uip_udp_conn *ds_conn; const void *ds_macaddr; int ds_maclen; int sockfd; struct in_addr ipaddr; struct in_addr serverid; struct dhcp_msg packet;};/**************************************************************************** * Private Data ****************************************************************************/static const uint8 xid[4] = {0xad, 0xde, 0x12, 0x23};static const uint8 magic_cookie[4] = {99, 130, 83, 99};/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: dhcpc_add<option> ****************************************************************************/static uint8 *dhcpc_addmsgtype(uint8 *optptr, uint8 type){ *optptr++ = DHCP_OPTION_MSG_TYPE; *optptr++ = 1; *optptr++ = type; return optptr;}static uint8 *dhcpc_addserverid(struct in_addr *serverid, uint8 *optptr){ *optptr++ = DHCP_OPTION_SERVER_ID; *optptr++ = 4; memcpy(optptr, &serverid->s_addr, 4); return optptr + 4;}static uint8 *dhcpc_addreqipaddr(struct in_addr *ipaddr, uint8 *optptr){ *optptr++ = DHCP_OPTION_REQ_IPADDR; *optptr++ = 4; memcpy(optptr, &ipaddr->s_addr, 4); return optptr + 4;}static uint8 *dhcpc_addreqoptions(uint8 *optptr){ *optptr++ = DHCP_OPTION_REQ_LIST; *optptr++ = 3; *optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_ROUTER; *optptr++ = DHCP_OPTION_DNS_SERVER; return optptr;}static uint8 *dhcpc_addend(uint8 *optptr){ *optptr++ = DHCP_OPTION_END; return optptr;}/**************************************************************************** * Name: dhcpc_sendmsg ****************************************************************************/static int dhcpc_sendmsg(struct dhcpc_state_s *pdhcpc, struct dhcpc_state *presult, int msgtype){ struct sockaddr_in addr; uint8 *pend; in_addr_t serverid = INADDR_BROADCAST; int len; /* Create the common message header settings */ memset(&pdhcpc->packet, 0, sizeof(struct dhcp_msg)); pdhcpc->packet.op = DHCP_REQUEST; pdhcpc->packet.htype = DHCP_HTYPE_ETHERNET; pdhcpc->packet.hlen = pdhcpc->ds_maclen; memcpy(pdhcpc->packet.xid, xid, 4); memcpy(pdhcpc->packet.chaddr, pdhcpc->ds_macaddr, pdhcpc->ds_maclen); memset(&pdhcpc->packet.chaddr[pdhcpc->ds_maclen], 0, 16 - pdhcpc->ds_maclen); memcpy(pdhcpc->packet.options, magic_cookie, sizeof(magic_cookie)); /* Add the common header options */ pend = &pdhcpc->packet.options[4]; pend = dhcpc_addmsgtype(pend, msgtype); /* Handle the message specific settings */ switch (msgtype) { /* Broadcast DISCOVER message to all servers */ case DHCPDISCOVER: pdhcpc->packet.flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ pend = dhcpc_addreqoptions(pend); break; /* Send REQUEST message to the server that sent the *first* OFFER */ case DHCPREQUEST: pdhcpc->packet.flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ memcpy(pdhcpc->packet.ciaddr, &pdhcpc->ipaddr.s_addr, 4); pend = dhcpc_addserverid(&pdhcpc->serverid, pend); pend = dhcpc_addreqipaddr(&pdhcpc->ipaddr, pend); break; /* Send DECLINE message to the server that sent the *last* OFFER */ case DHCPDECLINE: memcpy(pdhcpc->packet.ciaddr, &presult->ipaddr.s_addr, 4); pend = dhcpc_addserverid(&presult->serverid, pend); serverid = presult->serverid.s_addr; break; default: return ERROR; } pend = dhcpc_addend(pend); len = pend - (uint8*)&pdhcpc->packet; /* Send the request */ addr.sin_family = AF_INET; addr.sin_port = HTONS(DHCPC_SERVER_PORT); addr.sin_addr.s_addr = serverid; return sendto(pdhcpc->sockfd, &pdhcpc->packet, len, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));}/**************************************************************************** * Name: dhcpc_parseoptions ****************************************************************************/static uint8 dhcpc_parseoptions(struct dhcpc_state *presult, uint8 *optptr, int len){ uint8 *end = optptr + len; uint8 type = 0; while (optptr < end) { switch(*optptr) { case DHCP_OPTION_SUBNET_MASK: memcpy(&presult->netmask.s_addr, optptr + 2, 4); break; case DHCP_OPTION_ROUTER: memcpy(&presult->default_router.s_addr, optptr + 2, 4); break; case DHCP_OPTION_DNS_SERVER: memcpy(&presult->dnsaddr.s_addr, optptr + 2, 4); break; case DHCP_OPTION_MSG_TYPE: type = *(optptr + 2); break; case DHCP_OPTION_SERVER_ID: memcpy(&presult->serverid.s_addr, optptr + 2, 4); break; case DHCP_OPTION_LEASE_TIME: memcpy(presult->lease_time, optptr + 2, 4); break; case DHCP_OPTION_END: return type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -