Skip to content
This repository has been archived by the owner on Oct 26, 2023. It is now read-only.

Commit

Permalink
Merge pull request #78 from psychomario/development
Browse files Browse the repository at this point in the history
Various Patches which Complete v1.5
  • Loading branch information
mmattioli committed May 11, 2015
2 parents cebef93 + 362beca commit 5e5aeb4
Show file tree
Hide file tree
Showing 13 changed files with 774 additions and 560 deletions.
174 changes: 62 additions & 112 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#Background
>The Preboot eXecution Environment (PXE, also known as Pre-Execution Environment; sometimes pronounced "pixie") is an environment to boot computers using a network interface independently of data storage devices (like hard disks) or installed operating systems. -[Wikipedia](https://en.wikipedia.org/wiki/Preboot_Execution_Environment)
# Background
>The Preboot eXecution Environment (PXE, also known as Pre-Execution Environment; sometimes pronounced "pixie") is an environment to boot computers using a network interface independently of data storage devices (like hard disks) or installed operating systems. -[Wikipedia](https://en.wikipedia.org/wiki/Preboot_Execution_Environment)
PXE allows computers to boot from a binary image stored on a server, rather than the local hardware. Broadly speaking, a DHCP server informs a client of the TFTP server and filename from which to boot.
PXE allows computers to boot from a binary image stored on a server, rather than the local hardware. Broadly speaking, a DHCP server informs a client of the TFTP server and filename from which to boot.

##DHCP
## DHCP
In the standard DHCP mode, the server has been implemented from [RFC2131](http://www.ietf.org/rfc/rfc2131.txt), [RFC2132](http://www.ietf.org/rfc/rfc2132.txt), and the [DHCP Wikipedia Entry](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol).

The DHCP server is in charge of assigning new clients with IP addresses, and informing them of the location of the TFTP server and filename they should look for. The top half of the DHCP request, as seen on the Wikipedia entry, consists of some network information, followed by 192 legacy null bytes, and then the magic cookie.
Expand All @@ -18,7 +18,9 @@ Also included in these options are our PXE options. The minimum required option

Once the four way handshake is complete, the client will send a TFTP read request to the given fileserver IP address requesting the given filename.

###ProxyDHCP
By default only requests declaring the 'PXEClient' value dhcp option 60 are served, this is defined by [PXE specifications](http://www.pix.net/software/pxeboot/archive/pxespec.pdf) If you're using PyPXE as a library you can change this behavior extending the *DHCP* class and overwriting the *validateReq* method.

### ProxyDHCP
ProxyDHCP mode is useful for when you either cannot (or do not want to) change the main DHCP server on a network. The bulk of ProxyDHCP information can be found in the [Intel PXE spec](http://www.pix.net/software/pxeboot/archive/pxespec.pdf). The main idea behind ProxyDHCP is that the main network DHCP server can hand out the IP leases while the ProxyDHCP server hands out the PXE information to each client. Therefore, slightly different information is sent in the ProxyDHCP packets.

There are multiple ways to implement ProxyDHCP: broadcast, multicast, unicast or lookback. Lookback is the simplest implementation and this is what we have chosen to use. When we receive a DHCP DISCOVER from a client, we respond with a DHCP OFFER but the OFFER packet is sent without a few fields we would normally send in standard DHCP mode (this includes an offered IP address, along with any other network information such as router, DNS server(s), etc.). What we include in this OFFER packet (which isn't in a normal DHCP packet), is a vendor-class identifier of 'PXEClient' - this string identifies the packet as being relevant to PXE booting.
Expand All @@ -29,18 +31,18 @@ There are a few vendor-specific options under the DHCP option 43:

The client should receive two DHCP OFFER packets in ProxyDHCP mode: the first from the main DHCP server and the second from the ProxyDHCP server. Once both are received, the client will continue on with the DHCP handshake and, after it is complete, the client will boot using the settings in the DHCP OFFER from the ProxyDHCP server.

##TFTP
We have only implemented the read OPCODE for the TFTP server, as PXE does not use write. The main TFTP protocol is defined in [RFC1350](http://www.ietf.org/rfc/rfc1350.txt)
## TFTP
We have only implemented the read OPCODE for the TFTP server, as PXE does not use write. Only *octet* transfer mode is supported. The main TFTP protocol is defined in [RFC1350](http://www.ietf.org/rfc/rfc1350.txt)

###blksize
### blksize
The blksize option, as defined in [RFC2348](http://www.ietf.org/rfc/rfc2348.txt) allows the client to specify the block size for each transfer packet. The blksize option is passed along with the read opcode, following the filename and mode. The format is blksize, followed by a null byte, followed by the ASCII base-10 representation of the blksize (i.e 512 rather than 0x200), followed by another null byte.

##HTTP
## HTTP
We have implemented GET and HEAD, as there is no requirement for any other methods. The referenced RFCs are [RFC2616](http://www.ietf.org/rfc/rfc2616.txt) and [RFC7230](http://www.ietf.org/rfc/rfc7230.txt).

The HEAD method is used by some PXE ROMs to find the Content-Length before the GET is sent.

#PyPXE Services
# PyPXE Services
The PyPXE library provies the following services for the purpose of creating a Python-based PXE environment: TFTP, HTTP, and DHCP. Each service must be imorted independently as such:

* `from pypxe import tftp` or `import pypxe.tftp` imports the TFTP service
Expand All @@ -49,9 +51,9 @@ The PyPXE library provies the following services for the purpose of creating a P

**See [`pypxe-server.py`](pypxe-server.py) in the root of the repo for example usage on how to call, define, and setup the services.** When running any Python script that uses these classes, it should be run as a user with root privileges as they bind to interfaces and without root privileges the services will most likely fail to bind properly.

##TFTP Server `pypxe.tftp`
## TFTP Server `pypxe.tftp`

###Importing
### Importing
The TFTP service can be imported _one_ of the following two ways:
```python
from pypxe import tftp
Expand All @@ -60,28 +62,22 @@ from pypxe import tftp
import pypxe.tftp
```

###Usage
### Usage
The TFTP server class, __`TFTPD()`__, is constructed with the following __keyword arguments__:
* __`ip`__
* Description: This is the IP address that the TFTP server will bind to.
* Default: `'0.0.0.0'` (so that it binds to all available interfaces)
* Type: _string_
* __`port`__
* Description: This it the port that the TFTP server will run on.
* Default: `69` (default port for TFTP)
* Type: _int_
* __`netbootDirectory`__
* Description: This is the directory that the TFTP server will serve files from similarly to that of `tftpboot`.
* Default: `'.'` (current directory)
* Type: _string_
* __`mode_debug`__
* Description: This indicates whether or not the TFTP server should be started in debug mode or not.
* Default: `False`
* Type: bool

##DHCP Server `pypxe.dhcp`

###Importing

|Keyword Argument|Description|Default|Type|
|---|---|---|---|
|__`ip`__|This is the IP address that the TFTP server will bind to.|`'0.0.0.0'` (so that it binds to all available interfaces)| _string_|
|__`port`__|This it the port that the TFTP server will run on.|`69` (default port for TFTP)|_int_|
|__`netboot_directory`__|This is the directory that the TFTP server will serve files from similarly to that of `tftpboot`.|`'.'` (current directory)|_string_|
|__`mode_debug`__|This indicates whether or not the TFTP server should be started in debug mode or not.|`False`|`bool`|
|__`logger`__|A [Logger](https://docs.python.org/2/library/logging.html#logger-objects) object used for logging messages, if `None` a local [StreamHandler](https://docs.python.org/2/library/logging.handlers.html#streamhandler) instance will be created.|`None`|[_Logger_](https://docs.python.org/2/library/logging.html#logger-objects)|
|__`default_retries`__|The number of data retransmissions before dropping a connection.|`3`|_int_|
|__`timeout`__|The time in seconds before re-sending an un-acknowledged data block.|`5`|_int_|

## DHCP Server `pypxe.dhcp`

### Importing
The DHCP service can be imported _one_ of the following two ways:
```python
from pypxe import dhcp
Expand All @@ -92,66 +88,28 @@ import pypxe.dhcp

###Usage
The DHCP server class, __`DHCPD()`__, is constructed with the following __keyword arguments__:
* __`ip`__
* Description: This is the IP address that the DHCP server itself binds to.
* Default: `'192.168.2.2'`
* Type: _string_
* __`port`__
* Description: This it the port that the TFTP server will run on.
* Default: `67` (default port to listen for DHCP requests)
* Type: _int_
* __`offerfrom`__
* Description: This specifies the beginning of the range of IP addreses that the DHCP server will hand out to clients.
* Default: `'192.168.2.100'`
* Type: _string_
* __`offerto`__
* Description: This specifies the end of the range of IP addresses that the DHCP server will hand out to clients.
* Default: `'192.168.2.150'`
* Type: _string_
* __`subnetmask`__
* Description: This specifies the subnet mask that the DHCP server will specify to clients.
* Default: `'255.255.255.0'`
* Type: _string_
* __`router`__
* Description: This specifies the IP address of the router that the DHCP server will specify to clients.
* Default: `'192.168.2.1'`
* Type: _string_
* __`dnsserver`__
* Description: This specifies the DNS server that the DHCP server will specify to clients. Only one DNS server can be passed.
* Default: `'8.8.8.8'` ([Google Public DNS](https://developers.google.com/speed/public-dns/))
* Type: _string_
* __`broadcast`__
* Description: This specifies the broadcast address the DHCP will broadcast packets to.
* Default: `'<broadcast>'`
* Type: _string_
* __`fileserver`__
* Description: This is the IP address of the file server containing network boot files that the DHCP server will specify to clients.
* Default: `'192.168.2.2'`
* Type: _string_
* __`filename`__
* Description: This specifies the file name that the client should look for on the remote server.
* Default: `'pxelinux.0'`
* Type: _string_
* __`useipxe`__
* Description: This indicates whether or not iPXE is being used and adjusts itself accordingly.
* Default: `False`
* Type: _bool_
* __`usehttp`__
* Description: This indicates whether or not the built-in HTTP server is being used and adjusts itself accordingly.
* Default: `False`
* Type: _bool_
* __`mode_proxy`__
* Description: This indicates whether or not the DHCP server should be started in ProxyDHCP mode or not.
* Default: `False`
* Type: _bool_
* __`mode_debug`__
* Description: This indicates whether or not the DHCP server should be started in debug mode or not.
* Default: `False`
* Type: _bool_

##HTTP Server `pypxe.http`

###Importing

|Keyword Argument|Description|Default|Type|
|---|---|---|---|
|__`ip`__|This is the IP address that the DHCP server itself binds to.|`'192.168.2.2'`|_string_|
|__`port`__|This it the port that the TFTP server will run on.|`67` (default port to listen for DHCP requests)|_int_|
|__`offer_from`__|This specifies the beginning of the range of IP addresses that the DHCP server will hand out to clients.|`'192.168.2.100'`|_string_|
|__`offer_to`__|This specifies the end of the range of IP addresses that the DHCP server will hand out to clients.|`'192.168.2.150'`|_string_|
|__`subnet_mask`__|This specifies the subnet mask that the DHCP server will specify to clients.|`'255.255.255.0'`|_string_|
|__`router`__|This specifies the IP address of the router that the DHCP server will specify to clients.|`'192.168.2.1'`|_string_|
|__`dns_server`__|This specifies the DNS server that the DHCP server will specify to clients. Only one DNS server can be passed.|`'8.8.8.8'` ([Google Public DNS](https://developers.google.com/speed/public-dns/))|_string_|
|__`broadcast`__|This specifies the broadcast address the DHCP will broadcast packets to.|`'<broadcast>'`|_string_|
|__`file_server`__|This is the IP address of the file server containing network boot files that the DHCP server will specify to clients.|`'192.168.2.2'`|_string_|
|__`file_name`__|This specifies the file name that the client should look for on the remote server.|`'pxelinux.0'`|_string_|
|__`use_ipxe`__|This indicates whether or not iPXE is being used and adjusts itself accordingly.|`False`|_bool_|
|__`use_http`__|This indicates whether or not the built-in HTTP server is being used and adjusts itself accordingly.|`False`|_bool_|
|__`mode_proxy`__|This indicates whether or not the DHCP server should be started in ProxyDHCP mode or not.|`False`|_bool_|
|__`mode_debug`__|This indicates whether or not the DHCP server should be started in debug mode or not.|`False`|_bool_|
|__`logger`__|A [Logger](https://docs.python.org/2/library/logging.html#logger-objects) object used for logging messages, if `None` a local [StreamHandler](https://docs.python.org/2/library/logging.handlers.html#streamhandler) instance will be created.|`None`|[_Logger_](https://docs.python.org/2/library/logging.html#logger-objects)|

## HTTP Server `pypxe.http`

### Importing
The HTTP service can be imported _one_ of the following two ways:
```python
from pypxe import http
Expand All @@ -160,26 +118,18 @@ from pypxe import http
import pypxe.http
```

###Usage
### Usage
The HTTP server class, __`HTTPD()`__, is constructed with the following __keyword arguments__:
* __`ip`__
* Description: This is the IP address that the HTTP server will bind to.
* Default: `'0.0.0.0'` (so that it binds to all available interfaces)
* Type: _string_
* __`port`__
* Description: This it the port that the HTTP server will run on.
* Default: `80` (default port for HTTP)
* Type: _int_
* __`netbootDirectory`__
* Description: This is the directory that the HTTP server will serve files from similarly to that of `tftpboot`.
* Default: `'.'` (current directory)
* Type: _string_
* __`mode_debug`__
* Description: This indicates whether or not the HTTP server should be started in debug mode or not.
* Default: `False`
* Type: bool

##Additional Information

|Keyword Argument|Description|Default|Type|
|---|---|---|---|
|__`ip`__|This is the IP address that the HTTP server will bind to.|`'0.0.0.0'` (so that it binds to all available interfaces)|_string_|
|__`port`__|This it the port that the HTTP server will run on.|`80` (default port for HTTP)|_int_|
|__`netboot_directory`__|This is the directory that the HTTP server will serve files from similarly to that of `tftpboot`.|`'.'` (current directory)|_string_|
|__`mode_debug`__|This indicates whether or not the HTTP server should be started in debug mode or not.|`False`|bool|
|__`logger`__|A [Logger](https://docs.python.org/2/library/logging.html#logger-objects) object used for logging messages, if `None` a local [StreamHandler](https://docs.python.org/2/library/logging.handlers.html#streamhandler) instance will be created.|`None`|[_Logger_](https://docs.python.org/2/library/logging.html#logger-objects)|

## Additional Information
* The function `chr(0)` is used in multiple places throughout the servers. This denotes a `NULL` byte, or `\x00`
* Python 2.6 does not include the `argparse` module, it is included in the standard library as of 2.7 and newer. The `argparse` module is required to take in command line arguments and `pypxe-server.py` will not run without it.
* The TFTP server currently does not support transfer of large files, this is a known issue (see #35). Instead of using TFTP to transfer large files (roughly 33MB or greater) it is recommended that you use the HTTP server to do so. iPXE supports direct boot from HTTP and certain kernels (once you've booted into `pxelinux.0` via TFTP) support fetching files via HTTP as well.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014 PsychoMario
Copyright (c) 2015 PsychoMario

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading

0 comments on commit 5e5aeb4

Please sign in to comment.