• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013-2014 Intel Corporation - All Rights Reserved
3  */
4 
5 #include <syslinux/firmware.h>
6 #include <syslinux/pxe_api.h>
7 #include "efi.h"
8 #include "net.h"
9 #include "fs/pxe/pxe.h"
10 
11 const struct url_scheme url_schemes[] = {
12     { "tftp", tftp_open, 0 },
13     { "http", http_open, O_DIRECTORY },
14     { "ftp",  ftp_open,  O_DIRECTORY },
15     { NULL, NULL, 0 },
16 };
17 
18 /**
19  * Network stack-specific initialization
20  */
net_core_init(void)21 void net_core_init(void)
22 {
23     http_bake_cookies();
24 }
25 
pxe_init_isr(void)26 void pxe_init_isr(void) {}
gpxe_init(void)27 void gpxe_init(void) {}
pxe_idle_init(void)28 void pxe_idle_init(void) {}
29 
reset_pxe(void)30 int reset_pxe(void)
31 {
32     return 0;
33 }
34 
35 #define DNS_MAX_SERVERS 4		/* Max no of DNS servers */
36 uint32_t dns_server[DNS_MAX_SERVERS] = {0, };
37 
dns_resolv(const char * name)38 __export uint32_t dns_resolv(const char *name)
39 {
40     /*
41      * Return failure on an empty input... this can happen during
42      * some types of URL parsing, and this is the easiest place to
43      * check for it.
44      */
45     if (!name || !*name)
46 	return 0;
47 
48     return 0;
49 }
50 
pxe_init(bool quiet)51 int pxe_init(bool quiet)
52 {
53     EFI_HANDLE *handles;
54     EFI_STATUS status;
55     UINTN nr_handles;
56 
57     status = LibLocateHandle(ByProtocol, &PxeBaseCodeProtocol,
58 			     NULL, &nr_handles, &handles);
59     if (status != EFI_SUCCESS) {
60 	if (!quiet)
61 	    Print(L"No PXE Base Code Protocol\n");
62 	return -1;
63     }
64 
65     return 0;
66 }
67 
68 #define EDHCP_BUF_LEN 8192
69 
70 struct embedded_dhcp_options {
71     uint32_t magic[4];
72     uint32_t bdhcp_len;
73     uint32_t adhcp_len;
74     uint32_t buffer_size;
75     uint32_t reserved;
76     uint8_t  dhcp_data[EDHCP_BUF_LEN];
77 } __attribute__((aligned(16)));
78 
79 struct embedded_dhcp_options embedded_dhcp_options =
80 {
81     .magic[0] = 0x2a171ead,
82     .magic[1] = 0x0600e65e,
83     .magic[2] = 0x4025a4e4,
84     .magic[3] = 0x42388fc8,
85     .bdhcp_len = 0,
86     .adhcp_len = 0,
87     .buffer_size = EDHCP_BUF_LEN,
88 };
89 
net_parse_dhcp(void)90 void net_parse_dhcp(void)
91 {
92     EFI_PXE_BASE_CODE_MODE *mode;
93     EFI_PXE_BASE_CODE *bc;
94     unsigned int pkt_len = sizeof(EFI_PXE_BASE_CODE_PACKET);
95     EFI_STATUS status;
96     EFI_HANDLE *handles = NULL;
97     UINTN nr_handles = 0;
98     uint8_t hardlen;
99     uint32_t ip;
100     char dst[256];
101 
102     status = LibLocateHandle(ByProtocol, &PxeBaseCodeProtocol,
103 			 NULL, &nr_handles, &handles);
104     if (status != EFI_SUCCESS)
105 	return;
106 
107     /* Probably want to use IPv4 protocol to decide which handle to use */
108     status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[0],
109 			   &PxeBaseCodeProtocol, (void **)&bc);
110     if (status != EFI_SUCCESS) {
111 	Print(L"Failed to lookup PxeBaseCodeProtocol\n");
112     }
113 
114     mode = bc->Mode;
115 
116     /*
117      * Parse any "before" hardcoded options
118      */
119     parse_dhcp_options(embedded_dhcp_options.dhcp_data,
120 		       embedded_dhcp_options.bdhcp_len, 0);
121 
122     /*
123      * Get the DHCP client identifiers (query info 1)
124      */
125     Print(L"Getting cached packet ");
126     parse_dhcp(&mode->DhcpDiscover.Dhcpv4, pkt_len);
127     /*
128      * We don't use flags from the request packet, so
129      * this is a good time to initialize DHCPMagic...
130      * Initialize it to 1 meaning we will accept options found;
131      * in earlier versions of PXELINUX bit 0 was used to indicate
132      * we have found option 208 with the appropriate magic number;
133      * we no longer require that, but MAY want to re-introduce
134      * it in the future for vendor encapsulated options.
135      */
136     *(char *)&DHCPMagic = 1;
137 
138     /*
139      * Get the BOOTP/DHCP packet that brought us file (and an IP
140      * address). This lives in the DHCPACK packet (query info 2)
141      */
142     parse_dhcp(&mode->DhcpAck.Dhcpv4, pkt_len);
143     /*
144      * Save away MAC address (assume this is in query info 2. If this
145      * turns out to be problematic it might be better getting it from
146      * the query info 1 packet
147      */
148     hardlen = mode->DhcpAck.Dhcpv4.BootpHwAddrLen;
149     MAC_len = hardlen > 16 ? 0 : hardlen;
150     MAC_type = mode->DhcpAck.Dhcpv4.BootpHwType;
151     memcpy(MAC, mode->DhcpAck.Dhcpv4.BootpHwAddr, MAC_len);
152 
153     /*
154      * Get the boot file and other info. This lives in the CACHED_REPLY
155      * packet (query info 3)
156      */
157     parse_dhcp(&mode->PxeReply.Dhcpv4, pkt_len);
158     Print(L"\n");
159 
160     /*
161      * Parse any "after" hardcoded options
162      */
163     parse_dhcp_options(embedded_dhcp_options.dhcp_data +
164 		       embedded_dhcp_options.bdhcp_len,
165 		       embedded_dhcp_options.adhcp_len, 0);
166 
167     ip = IPInfo.myip;
168     sprintf(dst, "%u.%u.%u.%u",
169         ((const uint8_t *)&ip)[0],
170         ((const uint8_t *)&ip)[1],
171         ((const uint8_t *)&ip)[2],
172         ((const uint8_t *)&ip)[3]);
173 
174     Print(L"My IP is %a\n", dst);
175 }
176