The Open Powerline Toolkit supports raw Ethernet I/O on several popular operating systems, including Linux™, Mac OS X™ and Microsoft Windows™. Other operating systems will probably be added over time. These functions are found in the ether
folder.
Each operating system has a different raw Ethernet interface and so some abstraction was needed to support the toolkit for all environments. Our solution was the channel which is implemented like a FILE
pointer but is used like a file descriptor. All toolkit programs, with a few exceptions, perform raw Ethernet I/O by opening a channel, reading and writing to it and then closing it.
The channel structure contains enough information to perform raw Ethernet I/O in several common runtime environments; however, portions of the structure vary depending on the environment. These differences are appled by compile time constants that include required structure members and exclude others. The common structure members are identified and described below. The others elements are not discussed because they may change.
typedef struct __packedchannel
{ signedfd
; signedifindex
; char const *ifname
; uint8_tpeer
[ETHER_ADDR_LEN
]; uint8_thost
[ETHER_ADDR_LEN
]; uint16_ttype
; ... <operating system dependent data> ... signedtimeout
; flag_tflags
; }CHANNEL
;
fd
Socket file descriptor.
ifindex
Ethernet device index. The index only applies when the toolkit is compiled for LibPcap or WinPcap. This value is the same as that returned in the .ifr_ifindex
member of the ifreq
structure available on most operating systems.
ifname
The interface name. On Linux, ethernet names are typically “eth0”, “eth1” and so on. On Mac OS X, interface names are “en0”, “en1” and so on. This string is the same as that returned by the ifr_ifname
member of the ifreq
structure available on most operating systems.
peer
The Ethernet hardware address of some remote device. It is used to encode the ODA field of outgoing Ethernet frames and format some console messages. It is initialized to the Atheros Local Management Address, 00:B0:52:00:00:01
for HomePlug AV applications. Application programs can, and often do, replace this value at runtime.
host
The Ethernet hardware address of the host computer. It is used to encode the OSA field of outgoing Ethernet frames and format some console messages. This address is initialized to the hardware address assigned to the interface by the host operating system. The value should not change.
type
The Ethernet type/length field. It is used to encode the MTYPE field of outgoing Ethernet frames. The values is initialized to 0x88E1
for HomePlug AV application and 0x887B
for HomePlug 1.0 application. The value should not change.
timeout
A time interval. On Linux™ and Mac OS X™, it is the maximum time that the application will wait for a device to respond when a response is expected. With LibPcap™ and WinPcap™ it the mininum time the application will wait. It is initialized to 50
milliseconds which is a reasonable compromise but most toolkit programs allow the user to change this value.
flags
A bitmap where each bit enables a special behavior during channel open or close or packet read or write. Of general interest is the CHANNEL_VERBOSE
bit which prints outgoing and incoming frames on stderr in hexadecimal dump format. The verbose feature is implemented in for all toolkit programs that perform raw Ethernet I/O and is helpful when debugging device behavior.
Since toolkit applications typically communicate with one powerline device at a time, this structure is statically initialized in a stand-alone module that is linked into each application. It is possible to dynamically initialize it, if needed. The structure is declared in channel.h and statically defined in channel.c.
signed closechannel( | channel) ; |
struct channel * channel
;
Close the Ethernet socket associated with a channel and free associated memory and data structures. Return 0
on success. Return -1
on failure. This function is declared in channel.h and defined in closechannel.c.
signed openchannel( | channel, | |
protocol) ; |
struct channel * channel
;uint16_t protocol
;
Open an Ethernet socket that supports the specified protocol and associate it with the interface referenced by the channel
structure .name member. Initialize the interface as needed. The protocol
effectively filters incoming frames for the application.
Interface initialization differs significantly from environment to environment. The socket descriptor is stored in the channel
structure .fd member and the interface hardware address is stored in the channel
structure .host member. Return 0
on success. Terminate the program with an error message on failure. This function is declared in channel.h and defined in openchannel.c.
signed readpacket( | channel, | |
packet, | ||
length) ; |
struct channel * channel
;void * packet
;signed length
;
Read one Ethernet frame from the specified channel. The frame is written into memory starting at address packet
and is truncated to the specified length
, if necessary. Return the actual number of bytes read on success. Return 0
on timeout. Return -1
on network error. This function behaves like the standard library read
function. The target memory region remains unchanged on timeout or error. This function is declared in channel.h and defined in readpacket.c.
On systems using Berkeley Packet Filters, such as MacOS X, the ODA
field is automatically replaced on transmission to prevent Ethernet address spoofing. This may not be true on other systems but the practice is becoming more common.
signed sendpacket( | channel, | |
packet, | ||
length) ; |
struct channel * channel
;void * packet
;signed length
;
Write one Ethernet frame to the specified channel. The frame is read from memory starting at address packet
and ending at the specified length
. Return the actual number of bytes sent on success. Return 0
on timeout. Return -1
on network error. The frame should be properly formatted as an ethernet frame and must be at least 60 bytes long or it will not be sent. This function behaves like the standard library write
function. The source memory region is not modified. This function is declared in channel.h and defined in sendpacket.c.