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

📄 net_ipv4_bootp.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************** Copyright (c) 2002-2004 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" * * by Ho Lee 11/19/2002 */#include "config.h"#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[64];    char tftpserver[64];    char bootfile[128];} 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){    int retry;    unsigned int xid;    struct sk_buff *skb;    dhcp_info_t info;    in_addr_t yiaddr;    unsigned int startticks;    // bootp header    memcpy(&xid, &g_arptable[ARP_CLIENT].node[2], sizeof(xid));    xid += em86xx_random();    if (bootp)        uart_puts("Looking for BOOTP server...\n");    else        uart_puts("Discovering DHCP server...\n");        // 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);        startticks = timer_getticks();        do {            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;            }        } while (!timer_timeout(startticks, TIMEOUT));        if (skb)            break;        if (retry == MAX_BOOTP_RETRIES)            uart_puts("Timeout. Connection failed.\n");        else            uart_puts("Timeout. Retrying...\n");    }    // BOOTP :     // DHCP : got DHCPOFFER    if (skb) {        if (bootp) {            // Not implemented            skb_free(skb);            return 1;        } else {            memset(&info, 0, sizeof info);            dhcp_parse_option(skb->bootp->bp_vend, &info);            if (info.message_type != DHCPOFFER)                return 1;                        yiaddr = skb->bootp->bp_yiaddr;	    skb_free(skb);	                uart_puts("Sending DHCP request...\n");            // Send request and wait for reply            startticks = timer_getticks();            for (retry = 1; retry <= MAX_BOOTP_RETRIES; ++retry) {                do {                    dhcp_send_request(xid, 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) {                            memset(&info, 0, sizeof info);                            dhcp_parse_option(skb->bootp->bp_vend, &info);                            if (info.message_type == DHCPACK)                                break;                            else if (info.message_type == DHCPOFFER) {                                yiaddr = skb->bootp->bp_yiaddr;                                skb_free(skb);                                continue;                            }                         }                            skb_free(skb);                        skb = NULL;                    }                } while (!timer_timeout(startticks, TIMEOUT));                if (skb)                    break;                if (retry == MAX_BOOTP_RETRIES)                    uart_puts("Timeout. Connection failed.\n");                else                    uart_puts("Timeout. Retrying...\n");            }            if (skb) {                g_bootconfig.ipaddr = skb->bootp->bp_yiaddr;                g_bootconfig.netmask = info.subnet;                g_bootconfig.gateway = info.router;                g_bootconfig.dns = info.dns_server;                if (info.domain[0] != 0)                    strcpy(g_bootconfig.domain, info.domain);                net_arp_setup();                uart_printf("Got IP Address %s\n", ipaddr_to_str(skb->bootp->bp_yiaddr));				#ifdef SET_SERVER_IP_FOR_DOWNLOAD	uart_printf("Set server address to DHCP server address %s\n",                        ipaddr_to_str(g_bootconfig.server));#else#ifdef CONFIG_ENABLE_NETWORK_DNS                // parse server address if available                if (info.tftpserver[0] != 0) {                    uart_printf("Resolving tftp server %s...\n", info.tftpserver);                    g_bootconfig.server = ipv4_gethostbyname(info.tftpserver);					                    if (!ipv4_ipaddr_valid(g_bootconfig.server)) {                        char hostname[256];                        sprintf(hostname, "%s.%s", info.tftpserver, g_bootconfig.domain);                        uart_printf("Resolving tftp server %s...\n", hostname);                        g_bootconfig.server = ipv4_gethostbyname(hostname);                    }                    if (ipv4_ipaddr_valid(g_bootconfig.server)) {                        uart_printf("Set server address to tftp server address %s\n",                            ipaddr_to_str(g_bootconfig.server));                    } else                        uart_puts("Resolving failed\n");                }#endif                if (!ipv4_ipaddr_valid(g_bootconfig.server)) {                    g_bootconfig.server = skb->bootp->bp_siaddr;                    uart_printf("Set server address to DHCP server address %s\n",                        ipaddr_to_str(skb->bootp->bp_siaddr));                }#endif                // boot filename                if (info.bootfile[0] != 0) {                    strcpy(g_bootconfig.kernel_filename, info.bootfile);                    uart_printf("Set kernel filename to %s\n", info.bootfile);                }		else if (skb->bootp->bp_file[0] != 0) {			strcpy(g_bootconfig.kernel_filename, skb->bootp->bp_file);			uart_printf("Set kernel filename to %s\n", skb->bootp->bp_file);		}                skb_free(skb);                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 },

⌨️ 快捷键说明

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