aboutsummaryrefslogtreecommitdiffstats
path: root/efi/udp.c
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-09-30 13:22:36 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-09-30 13:33:26 +0100
commit47179ebc03dcb3177312d97cd912605704c40686 (patch)
treee766d15f3153fcabfccbb5e4a6e318d6c7c50478 /efi/udp.c
parent3e86c0e35b96fef58dbfbb96e3ef509ea4047d2e (diff)
parent2fe3a7bdd20d6fada21bd455a902c2b02f46a02d (diff)
downloadsyslinux-47179ebc03dcb3177312d97cd912605704c40686.tar.gz
syslinux-47179ebc03dcb3177312d97cd912605704c40686.tar.xz
syslinux-47179ebc03dcb3177312d97cd912605704c40686.zip
Merge branch 'elflink-pxe-fixes-for-mfleming-2' of git://github.com/geneC/syslinux into firmware
Pull various network stack fixes from Gene Cumm and adapt to the 6.xx core_udp_* API, * 'elflink-pxe-fixes-for-mfleming-2' of git://github.com/geneC/syslinux: PXE ISR: Force polling on select hardware WORKAROUND core/lwip: Fix NULL pointer check PXE: use ddprintf macro com32: Define ddprintf() macro PXELINUX: specify PXE/lwIP undiif: show thread of execution on UNDIIF_ID_DEBUG core: dprintf() the banner. PXELINUX: Use sendto() instead of connect()/send()/disconnect() core: make mbox_post()/__sem_down_slow() check if valid core: mbox/semaphore NULL checks core/lwip/undi: Improve UNDIIF_ID_DEBUG messages Conflicts: core/fs/pxe/pxe.c core/fs/pxe/tftp.c core/init.c
Diffstat (limited to 'efi/udp.c')
-rw-r--r--efi/udp.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/efi/udp.c b/efi/udp.c
index db9bc8f9..59bb4263 100644
--- a/efi/udp.c
+++ b/efi/udp.c
@@ -297,3 +297,88 @@ bail:
free(txdata);
free(token);
}
+
+/**
+ * Send a UDP packet to a destination
+ *
+ * @param:socket, the open socket
+ * @param:data, data buffer to send
+ * @param:len, size of data bufer
+ * @param:ip, the ip address
+ * @param:port, the port number, host-byte order
+ */
+void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data,
+ size_t len, uint32_t ip, uint16_t port)
+{
+ EFI_UDP4_COMPLETION_TOKEN *token;
+ EFI_UDP4_TRANSMIT_DATA *txdata;
+ EFI_UDP4_FRAGMENT_DATA *frag;
+ EFI_UDP4_CONFIG_DATA udata;
+ EFI_STATUS status;
+ struct efi_binding *b;
+ EFI_UDP4 *udp;
+
+ (void)socket;
+
+ b = efi_create_binding(&Udp4ServiceBindingProtocol, &Udp4Protocol);
+ if (!b)
+ return;
+
+ udp = (EFI_UDP4 *)b->this;
+
+ token = zalloc(sizeof(*token));
+ if (!token)
+ goto out;
+
+ txdata = zalloc(sizeof(*txdata));
+ if (!txdata)
+ goto bail;
+
+ memset(&udata, 0, sizeof(udata));
+
+ memcpy(&udata.StationAddress, &IPInfo.myip, sizeof(IPInfo.myip));
+ memcpy(&udata.SubnetMask, &IPInfo.netmask, sizeof(IPInfo.netmask));
+ memcpy(&udata.RemoteAddress, &ip, sizeof(ip));
+ udata.RemotePort = port;
+ udata.AcceptPromiscuous = TRUE;
+ udata.TimeToLive = 64;
+
+ status = uefi_call_wrapper(udp->Configure, 2, udp, &udata);
+ if (status != EFI_SUCCESS)
+ goto bail;
+
+ status = efi_setup_event(&token->Event, (EFI_EVENT_NOTIFY)udp4_cb,
+ token);
+ if (status != EFI_SUCCESS)
+ goto bail;
+
+ txdata->UdpSessionData = NULL;
+ txdata->GatewayAddress = NULL;
+ txdata->DataLength = len;
+ txdata->FragmentCount = 1;
+ frag = &txdata->FragmentTable[0];
+
+ frag->FragmentLength = len;
+ frag->FragmentBuffer = (void *)data;
+
+ token->Packet.TxData = txdata;
+
+ status = uefi_call_wrapper(udp->Transmit, 2, udp, token);
+ if (status != EFI_SUCCESS)
+ goto close;
+
+ while (cb_status == -1)
+ uefi_call_wrapper(udp->Poll, 1, udp);
+
+ /* Reset */
+ cb_status = -1;
+
+close:
+ uefi_call_wrapper(BS->CloseEvent, 1, token->Event);
+
+bail:
+ free(txdata);
+ free(token);
+out:
+ efi_destroy_binding(b, &Udp4ServiceBindingProtocol);
+}