📄 net_ipv4_bootp.c
字号:
/***************************************** Copyright (c) 2001-2002 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * net_ipv4_bootp.c * * BOOTP/DHCP client * * RFCs related to BOOTP/DHCP * RFC 951 "Bootstrap Protocol" (Obsoleted by 1395) * RFC 1395 "BOOTP Vendor Information Extensions" (Obsoleted by 1497) * RFC 1497 "BOOTP Vendor Information Extensions" (Obsoleted by 1533) * RFC 1533 "DHCP Options and BOOTP Vendor Extensions" (Obsoleted by 2132) * RFC 1534 "Interoperation Between DHCP and BOOTP" * RFC 2132 "DHCP Options and BOOTP Vendor Extensions" */#include "util.h"#include "vsprintf.h"#include "uart.h"#include "timer.h"#include "net.h"#include "net_ipv4.h"#include "bootconfig.h"/* * DHCP mechanism : * * client server * -------------------------------- * DHCPDISCOVER => : client broadcasts looking for DHCP server * <= DHCPOFFER : server broadcasts to client with offer (IP address) * DHCPREQUEST => : client broadcasts to server requesting IP which server offered * <= DHCPACK : server response with ACK*/// data structure for saving infomation from DHCP option// used by dhcp_parse_option()typedef struct dhcp_info { int message_type; uint32_t server_id; uint32_t lease_time; in_addr_t subnet; in_addr_t router; in_addr_t dns_server; in_addr_t broadcast; char domain[24];} dhcp_info_t;// // function prototypes//int dhcp_send_discover(unsigned int xid);int dhcp_send_request(unsigned int xid, in_addr_t ipaddr, in_addr_t serverid);void dhcp_parse_option(unsigned char *str, dhcp_info_t *info);// parse bootp packetint bootp_parsepacket(struct sk_buff *skb){ skb->bootp = (struct bootphdr *) ((char *) skb->udp + sizeof(struct udphdr)); skb->bootp->bp_secs = ntohs(skb->bootp->bp_secs); skb->bootp->bp_flags = ntohs(skb->bootp->bp_flags); skb->bootp->bp_ciaddr = ntohl(skb->bootp->bp_ciaddr); skb->bootp->bp_yiaddr = ntohl(skb->bootp->bp_yiaddr); skb->bootp->bp_siaddr = ntohl(skb->bootp->bp_siaddr); skb->bootp->bp_giaddr = ntohl(skb->bootp->bp_giaddr); return 0;}// bootp == 0 : DHCP protocol// bootp != 0 : BOOP protocolint ipv4_bootp(int bootp){ static int s_last = 0; int retry; unsigned int xid; struct sk_buff *skb; dhcp_info_t info; // bootp header memcpy(&xid, &g_arptable[ARP_CLIENT].node[2], sizeof(xid)); xid += htonl(s_last); s_last += 7; if (bootp) PrintUart("Looking for BOOTP server...\r\n", -1); else PrintUart("Discovering DHCP server...\r\n", -1); // BOOTP : // DHCP : send DHCPDISCOVER message // wating for reply for (retry = 1; retry <= MAX_BOOTP_RETRIES; ++retry) { // flush RX buffer eth_receive(WAIT_NOTHING, 0); // send discover if (bootp) ; else dhcp_send_discover(xid); if ((skb = udp_receive(0, 0, IPPORT_BOOTP_CLIENT, TIMEOUT)) != NULL) { if (bootp_parsepacket(skb) == 0 && skb->bootp->bp_op == BOOTP_REPLY && skb->bootp->bp_xid == xid) break; skb_free(skb); skb = NULL; } if (retry == MAX_BOOTP_RETRIES) PrintUart("Timeout. Connection failed.\r\n", -1); else PrintUart("Timeout. Retrying...\r\n", -1); } // BOOTP : // DHCP : got DHCPOFFER if (skb) { if (bootp) { return 0; } else { memset(&info, 0, sizeof info); dhcp_parse_option(skb->bootp->bp_vend, &info); if (info.message_type != DHCPOFFER) return 1; skb_free(skb); PrintUart("Sending DHCP request...\r\n", -1); // Send request and wait for reply for (retry = 1; retry <= MAX_BOOTP_RETRIES; ++retry) { dhcp_send_request(xid, skb->bootp->bp_yiaddr, info.server_id); if ((skb = udp_receive(0, 0, IPPORT_BOOTP_CLIENT, TIMEOUT)) != NULL) { if (bootp_parsepacket(skb) == 0 && skb->bootp->bp_op == BOOTP_REPLY && skb->bootp->bp_xid == xid) break; skb_free(skb); skb = NULL; } if (retry == MAX_BOOTP_RETRIES) PrintUart("Timeout. Connection failed.\r\n", -1); else PrintUart("Timeout. Retrying...\r\n", -1); } if (skb) { memset(&info, 0, sizeof info); dhcp_parse_option(skb->bootp->bp_vend, &info); if (info.message_type != DHCPACK) return 1; skb_free(skb); g_bootconfig.ipaddr = skb->bootp->bp_yiaddr; g_bootconfig.netmask = info.subnet; g_bootconfig.gateway = info.router; // g_bootconfig.server = skb->bootp->bp_siaddr; g_bootconfig.dns = info.dns_server; strcpy(g_bootconfig.domain, info.domain); net_arp_setup(); PrintFormat("Got IP Address %s\n", ipaddr_to_str(skb->bootp->bp_yiaddr)); return 0; } } } return 1;}/* * DHCP protocol definitions * * from RFC 2132 */#define DHCP_MAGIC 0x63825363#define DHCP_PADDING 0x00 // #define DHCP_SUBNET 0x01 // [4] subnet mask#define DHCP_TIME_OFFSET 0x02 // [4] client's subnet in section from UTC#define DHCP_ROUTER 0x03 // [x4] router addresses#define DHCP_TIME_SERVER 0x04 // [x4] time server addresses#define DHCP_NAME_SERVER 0x05 // [x4] name server addresses#define DHCP_DNS_SERVER 0x06 // [x4] DNS server addresses#define DHCP_LOG_SERVER 0x07 // [x4] log server addresses#define DHCP_COOKIE_SERVER 0x08 // [x4] cookie server addresses#define DHCP_LPR_SERVER 0x09 // [x4] LPR (line printer server) addresses#define DHCP_IMPRESS_SERVER 0x0a // [x4] impress server addresses#define DHCP_RESOURCE_SERVER 0x0b // [x4] resource location server addresses#define DHCP_HOST_NAME 0x0c // [v] name of the client#define DHCP_BOOT_SIZE 0x0d // [2] boot file size#define DHCP_MERIT_DUMP_FILE 0x0e // [v] name of the file to which the client's core image should be dumped#define DHCP_DOMAIN_NAME 0x0f // [v] domain name#define DHCP_SWAP_SERVER 0x10 // [4] IP address of the swap server#define DHCP_ROOT_PATH 0x11 // [v] root disk's path name#define DHCP_EXTENSION_PATH 0x12 // [v] file name retrievable via TFTP#define DHCP_IP_FORWARDING 0x13 // [1] IP forwarding enable / disable#define DHCP_SOURCE_ROUTING 0x14 // [1] Non-local source routing enable / disable#define DHCP_POLICY_FILTER 0x15 // [x8] policy filter for non-local source routing#define DHCP_MAX_DGRAM_REASM 0x16 // [2] maximum datagram reassembly size#define DHCP_IP_TTL 0x17 // [1] IP Time-to-live#define DHCP_PATH_MTU_TIMEOUT 0x18 // [4] Path MTU aging timeout#define DHCP_PATH_MTU_PLATEAU 0x19 // [x2] Path MTU plateau table #define DHCP_MTU 0x1a // [2] interface MTU #define DHCP_SUBNET_LOCAL 0x1b // [1] All subnets are local option#define DHCP_BROADCAST 0x1c // [4] broadcast address#define DHCP_MASK_DISCOVERY 0x1d // [1] perform mask discovery#define DHCP_MASK_SUPPLIER 0x1e // [1] mask supplier#define DHCP_ROUTER_DISCOVERY 0x1f // [1] perform router discovery#define DHCP_ROUTER_SOLICITATE 0x20 // [4] router solicitation address#define DHCP_STATIC_ROUTE 0x21 // [x8] static route#define DHCP_TRAILER_ENCAP 0x22 // [1] trailer encapsulation#define DHCP_ARP_CACHE_TIMEOUT 0x23 // [4] ARP cache timeout ini seconds#define DHCP_ETHERNET_ENCAP 0x24 // [1] ethernet encapsulation#define DHCP_TCP_TTL 0x25 // [1] TCP default TTL #define DHCP_TCP_KEEPALIVE_INT 0x26 // [4] TCP keepalive interval#define DHCP_TCP_KEEPALIVE_GAR 0x27 // [1] TCP keepalive garbage#define DHCP_NIS_DOMAIN 0x28 // [v] NIS (Network information service) domain name#define DHCP_NIS_SERVER 0x29 // [x4] NIS server addresses#define DHCP_NTP_SERVER 0x2a // [x4] NTP (Network time protocol) server addresses#define DHCP_VENDOR_SPECIFIC 0x2b // [v] vendor specific information#define DHCP_NBNS_SERVER 0x2c // [x4] NetBIOS over TCP/IP name server#define DHCP_NBDD_SERVER 0x2d // [x4] NetBIOS over TCP/IP datagram distribution server#define DHCP_NB_NODETYPE 0x2e // [1] NetBIOS over TCP/IP node type#define DHCP_NB_SCOPE 0x2f // [v] NetBIOS over TCP/IP scove#define DHCP_XFONT_SERVER 0x30 // [x4] X Window font server#define DHCP_XDISPLAY_MANAGER 0x31 // [x4] X Window system display manager#define DHCP_REQUESTED_IP 0x32 // [4] requested IP address#define DHCP_LEASE_TIME 0x33 // [4] IP address lease time#define DHCPOPTION_OVERLOAD 0x34 // [1] option overload#define DHCP_MESSAGE_TYPE 0x35 // [1] DHCP message type#define DHCP_SERVER_ID 0x36 // [4] server identifier (DHCPOFFER, DHCPREQUEST)#define DHCP_PARAM_REQUEST 0x37 // [v] parameter request list#define DHCP_MESSAGE 0x38 // [v] error message#define DHCP_MAX_SIZE 0x39 // [2] maximum DHCP message size#define DHCP_T1 0x3a // [4] renewal (T1) time value#define DHCP_T2 0x3b // [4] rebinding (T2) time value#define DHCP_VENDOR_CLASS_ID 0x3c // [v] vendor class identifier#define DHCP_CLIENT_ID 0x3d // [v] client identifier#define DHCP_NISPLUS_DOMAIN 0x40 // [v] NIS+ domain name#define DHCP_NISPLUS_SERVER 0x41 // [x4] NIS server #define DHCP_TFTP_SERVERNAME 0x42 // [v] TFTP server#define DHCP_BOOTFILE 0x43 // [v] bootfile name#define DHCP_MOBILE_IP_AGENT 0x44 // [x4] Mobile IP home agent#define DHCP_SMTP_SERVER 0x45 // [x4] SMTP (Simple Mail Transfer Protocol) server#define DHCP_POP3_SERVER 0x46 // [x4] POP3 (Post Office Protocol) server#define DHCP_NNTP_SERVER 0x47 // [x4] NNTP (Network News Transport Protocol) server#define DHCP_WWW_SERVER 0x48 // [x4] default WWW (World Wide Web) server#define DHCP_FINGER_SERVER 0x49 // [x4] default finger server#define DHCP_IRC_SERVER 0x4a // [x4] default IRC (internet Relay Chat) server#define DHCP_ST_SERVER 0x4b // [x4] StreetTalk server#define DHCP_ST_DA_SERVER 0x4c // [x4] StreetTalk Directory Assistance server#define DHCP_END 0xff // /* * DHCP options definitions */// option typeenum { DHCPOPT_INT8, // 1 byte integer DHCPOPT_INT16, // 2 bytes integer DHCPOPT_INT32, // 4 bytes integer DHCPOPT_IPADDR, // 4 bytes IP addresses DHCPOPT_IPADDR2, // pair of IP addresses DHCPOPT_STR, // zero-terminated string (variant size) DHCPOPT_VARIABLE, // non zero-terminated array of bytes DHCPOPT_LIST = 0x100, // list DHCPOPT_TYPEMASK = 0xff,};static int s_option_len[] = { 1, 2, 4, 4, 4, -1, -2 };struct { int code; int flags;} s_option_list[] = { { DHCP_SUBNET, DHCPOPT_IPADDR }, { DHCP_TIME_OFFSET, DHCPOPT_INT32 }, { DHCP_ROUTER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_TIME_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_NAME_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_DNS_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_LOG_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_COOKIE_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_LPR_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_IMPRESS_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_RESOURCE_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_HOST_NAME, DHCPOPT_STR }, { DHCP_BOOT_SIZE, DHCPOPT_INT16 }, { DHCP_MERIT_DUMP_FILE, DHCPOPT_STR }, { DHCP_DOMAIN_NAME, DHCPOPT_STR }, { DHCP_SWAP_SERVER, DHCPOPT_IPADDR }, { DHCP_ROOT_PATH, DHCPOPT_STR }, { DHCP_EXTENSION_PATH, DHCPOPT_STR }, { DHCP_IP_FORWARDING, DHCPOPT_INT8 }, { DHCP_SOURCE_ROUTING, DHCPOPT_INT8 }, { DHCP_POLICY_FILTER, DHCPOPT_IPADDR2 | DHCPOPT_LIST }, { DHCP_MAX_DGRAM_REASM, DHCPOPT_INT16 }, { DHCP_IP_TTL, DHCPOPT_INT8 }, { DHCP_PATH_MTU_TIMEOUT, DHCPOPT_INT32 }, { DHCP_PATH_MTU_PLATEAU, DHCPOPT_INT16 | DHCPOPT_LIST }, { DHCP_MTU, DHCPOPT_INT16 }, { DHCP_SUBNET_LOCAL, DHCPOPT_INT8 }, { DHCP_BROADCAST, DHCPOPT_IPADDR }, { DHCP_MASK_DISCOVERY, DHCPOPT_INT8 }, { DHCP_MASK_SUPPLIER, DHCPOPT_INT8 }, { DHCP_ROUTER_DISCOVERY, DHCPOPT_INT8 }, { DHCP_ROUTER_SOLICITATE, DHCPOPT_IPADDR }, { DHCP_STATIC_ROUTE, DHCPOPT_IPADDR2 | DHCPOPT_LIST }, { DHCP_TRAILER_ENCAP, DHCPOPT_INT8 }, { DHCP_ARP_CACHE_TIMEOUT, DHCPOPT_INT32 }, { DHCP_ETHERNET_ENCAP, DHCPOPT_INT8 }, { DHCP_TCP_TTL, DHCPOPT_INT8 }, { DHCP_TCP_KEEPALIVE_INT, DHCPOPT_INT32 }, { DHCP_TCP_KEEPALIVE_GAR, DHCPOPT_INT32 }, { DHCP_NIS_DOMAIN, DHCPOPT_STR }, { DHCP_NIS_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_NTP_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_VENDOR_SPECIFIC, DHCPOPT_STR }, { DHCP_NBNS_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_NBDD_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_NB_NODETYPE, DHCPOPT_INT8 }, { DHCP_XFONT_SERVER, DHCPOPT_IPADDR | DHCPOPT_LIST }, { DHCP_XDISPLAY_MANAGER, DHCPOPT_IPADDR }, { DHCP_REQUESTED_IP, DHCPOPT_IPADDR },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -