Wednesday, 3 August 2016

UEFI Application Networking - Simple Client/Server application

This post is to demonstrate how you can do TCP/IP networking in UEFI applications.
I assume that you have BITS installed on a USB drive, if you haven't see this post.

It is important that you have enabled UEFI networking in the BIOS settings, on my laptop I had to enable this after enabling UEFI. The way to do this may wary from machine to machine. I was unable to do this on my desktop, which is a 2012 machine running Intel Visual BIOS. Here are the screenshots.


Enabling UEFI network stack
Once this is done, simply boot the USB drive, open the python console and write the following code.
Notice the automatic DHCP configuration.

Client


#client code
from socket import *
s=socket(AF_INET,SOCK_STREAM)
s.connect(("192.168.0.107",1010))
s.send("Hello world!\n")

Note that I am assuming that I have two hosts, and the IP addresses that they have are "192.168.0.107", and "192.168.0.103". Change these values accordingly.

Test this client by creating a netcat server on "192.168.0.107", listening on port 1010.


#on 192.168.0.107
echo "Hi!"|sudo nc -l 1010

Here are the screenshots.
UEFI client running on 192.168.0.103 - Notice IP automatic configuration
UEFI client running on 192.168.0.103 - Notice IP automatic configuration

netcat server running on an ubuntu host (192.168.0.107)
If however you get the EFI_TIMEOUT error, as shown in the following, check for the following.

  • The Ethernet wire is connected
  • DHCP server is running
If you still are getting this error, as it happened with me, try updating the BIOS. Updating the BIOS worked for me.

If you are getting EFI_NOT_FOUND error, check for the following.
  • UEFI network stack is enabled (as shown above).
  • Your BIOS supports UEFI networking.
Here are the screenshots for the errors.

EFI_TIMEOUT

EFI_NOT_FOUND
SERVER


#Server code
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("192.168.0.103",1010))
s.listen(1)
conn,addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
conn.send("Hello world!\n")
conn.recv(4)

To test this server, connect to it using netcat.


echo "Hi!"|sudo nc 192.168.0.103 1010

Here are the screenshots.

UEFI server running on 192.168.0.103 - Notice IP automatic configuration
UEFI server running on 192.168.0.103 - Notice IP automatic configuration

netcat client running on an ubuntu host (192.168.0.107)
As in case of client, you may face EFI_TIMEOUT, or EFI_NOT_FOUND error, their resolution will be same as discussed there.

If you want to write a similar UEFI application in C, then try to dive into python code in BITS to see how it is making the use of UEFI run time.

This was just a proof of concept, for demonstrating how a UEFI application can use networking, and therefore the examples are fairly simple. Once networking is established, the possibilities are limitless.

Resources -
  1. My Github repo for UEFI