Ethernet Functions

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.

channel

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 __packed channel
{
        signed fd;
        signed ifindex;
        char const * ifname;
        uint8_t peer [ETHER_ADDR_LEN];
        uint8_t host [ETHER_ADDR_LEN];
        uint16_t type;

	 ... <operating system dependent data> ...

        signed timeout;
        flag_t flags;
} 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.

closechannel

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.

openchannel

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.

readpacket

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.

sendpacket

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.