5 typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT;
37 UINT8 BootpHwAddr[16];
38 UINT8 BootpSrvName[64];
39 UINT8 BootpBootFile[128];
41 UINT8 DhcpOptions[56];
42 } EFI_PXE_BASE_CODE_DHCPV4_PACKET;
46 BOOLEAN Ipv6Available;
47 BOOLEAN Ipv6Supported;
53 BOOLEAN DhcpDiscoverValid;
54 BOOLEAN DhcpAckReceived;
55 BOOLEAN ProxyOfferReceived;
56 BOOLEAN PxeDiscoverValid;
57 BOOLEAN PxeReplyReceived;
58 BOOLEAN PxeBisReplyReceived;
59 BOOLEAN IcmpErrorReceived;
60 BOOLEAN TftpErrorReceived;
61 BOOLEAN MakeCallbacks;
71 UINT8 DhcpDiscover[1472];
73 UINT8 ProxyOffer[1472];
74 UINT8 PxeDiscover[1472];
76 UINT8 PxeBisReply[1472];
78 } EFI_PXE_BASE_CODE_MODE;
94 EFI_PXE_BASE_CODE_MODE *Mode;
95 } EFI_PXE_BASE_CODE_PROTOCOL;
112 EFI_GUID EFI_PXE_BASE_CODE_PROTOCOL_GUID = {
113 0x03C4E603, 0xAC28, 0x11D3,
114 0x9A, 0x2D, 0x00, 0x90,
115 0x27, 0x3F, 0xC1, 0x4D,
119 EFI_PXE_BASE_CODE_PROTOCOL *pxe;
122 EFI_PXE_BASE_CODE_DHCPV4_PACKET *dhcp;
124 typedef struct Tftp Tftp;
130 EFI_PXE_BASE_CODE_UDP_PORT sport;
131 EFI_PXE_BASE_CODE_UDP_PORT dport;
139 char pkt[2+2+Segsize];
144 puts(void *x, ushort v)
148 p[1] = (v>>8) & 0xFF;
157 return p[1]<<8 | p[0];
161 hnputs(void *x, ushort v)
165 p[0] = (v>>8) & 0xFF;
174 return p[0]<<8 | p[1];
179 ANY_SRC_PORT = 0x0002,
180 ANY_DEST_IP = 0x0004,
181 ANY_DEST_PORT = 0x0008,
183 MAY_FRAGMENT = 0x0020,
187 udpread(EFI_IP_ADDRESS *sip, EFI_IP_ADDRESS *dip,
188 EFI_PXE_BASE_CODE_UDP_PORT *sport,
189 EFI_PXE_BASE_CODE_UDP_PORT dport,
190 int *len, void *data)
195 if(eficall(pxe->UdpRead, pxe, (UINTN)ANY_SRC_PORT, dip, &dport, sip, sport, nil, nil, &size, data))
203 udpwrite(EFI_IP_ADDRESS *dip,
204 EFI_PXE_BASE_CODE_UDP_PORT sport,
205 EFI_PXE_BASE_CODE_UDP_PORT dport,
211 if(eficall(pxe->UdpWrite, pxe, (UINTN)MAY_FRAGMENT, dip, &dport, nil, nil, &sport, nil, nil, &size, data))
218 pxeread(void *f, void *data, int len)
223 while(!t->eof && t->rp >= t->ep){
226 if(udpread(&t->dip, &t->sip, &t->dport, t->sport, &n, t->pkt))
231 switch(nhgets(t->pkt)){
233 seq = nhgets(t->pkt+2);
238 hnputs(t->pkt, Tftp_ACK);
239 while(udpwrite(&t->dip, t->sport, t->dport, 4, t->pkt))
249 t->eof = n < Segsize;
263 memmove(data, t->rp, len);
277 tftpopen(Tftp *t, char *path)
279 static EFI_PXE_BASE_CODE_UDP_PORT xport = 6666;
290 hnputs(p, Tftp_READ); p += 2;
292 memmove(p, path, n); p += n;
293 memmove(p, "octet", 6); p += 6;
296 if(r = udpwrite(&t->dip, t->sport, TftpPort, n, t->pkt))
298 if(r = pxeread(t, 0, 0))
311 memset(t, 0, sizeof(Tftp));
313 memmove(&t->dip, dhcp->BootpSiAddr, 4);
314 memmove(&t->sip, pxe->Mode->StationIp, 4);
316 if(tftpopen(t, name))
324 EFI_PXE_BASE_CODE_MODE *mode;
333 if(eficall(ST->BootServices->LocateHandleBuffer,
334 ByProtocol, &EFI_PXE_BASE_CODE_PROTOCOL_GUID, nil, &Count, &Handles))
337 for(i=0; i<Count; i++){
339 if(eficall(ST->BootServices->HandleProtocol,
340 Handles[i], &EFI_PXE_BASE_CODE_PROTOCOL_GUID, &pxe))
343 if(mode == nil || mode->UsingIpv6 || mode->Started == 0)
345 if(mode->DhcpAckReceived){
346 dhcp = (EFI_PXE_BASE_CODE_DHCPV4_PACKET*)mode->DhcpAck;
349 if(mode->PxeReplyReceived){
350 dhcp = (EFI_PXE_BASE_CODE_DHCPV4_PACKET*)mode->PxeReply;
365 mac = dhcp->BootpHwAddr;
366 memmove(ini, "/cfg/pxe/", 9);
368 ini[9+i*2+0] = hex[mac[i] >> 4];
369 ini[9+i*2+1] = hex[mac[i] & 0xF];
372 if((*pf = pxeopen(ini)) == nil)
373 *pf = pxeopen("/cfg/pxe/default");