# The Network Kit: BNetDevice

Derived from: none

Declared in: be/addons/net_server/NetDevice.h

Library: libnetdev.so

## Overview

When the Net Server loads your network device add-on and wants to begin using it, it needs to obtain a reference to an object derived from the BNetDevice class. BNetDevice is a pure virtual class that your add-on will subclass and flesh out.

To obtain a pointer to your BNetDevice, the Net Server calls your add-on's static C function `open_device()`. The protocol for this function is:

       BNetDevice *open_device(const char *device_name);

This function should return a pointer to a BNetDevice object. For example:

       extern "C" BNetDevice *open_device(const char *device_name) {
          MyNetDevice *dev;  * Pointer to BNetDevice-derived object */

          dev = new MyNetDevice();
          if (/* device initialized safely */) {
             return dev;
          }
          delete dev;
          return NULL;
       }

In this example, MyNetDevice is the class we've derived from BNetDevice. We instantiate an object of this type and then try to start the device up. If the initialization fails, we delete the object and return `NULL`. If the device is started up safely, we return a pointer to the MyNetDevice object. Once this pointer has been returned, the Net Server knows how to communicate with our device.

If your network device add-on needs to manage timeout activity, you should consider inheriting from BTimeoutHandler as well as from BNetDevice.

Now that you know how the Network Server obtains a reference to your BNetDevice-derived object, let's investigate what needs to be implemented.

### Starting Up and Shutting Down

These two functions need to be implemented to let the Net Server properly initialize and shut down your add-on:

- `Close()` should shut down your add-on, terminating its link with the network.

- `OpenIP()` should, if your device is an IP device, return a pointer to an object derived from BIpDevice. This object will be used for further networking by the Net Server. See BIpDevice for details on how to create IP devices If your device is not an IP device, or it's an IP device but you want to use the built-in IP device, you can just return `NULL`.

### Device Information

Five functions must be implemented to provide access to information about the device your add-on represents, and to provide some additional configuration options:

- `Address()` should return the address of the device in the buffer provided by the caller. The format and size of the buffer is device-type specific; you can assume that the caller previously called `Type()` to determine the type of device your add-on represents and has established an appropriate buffer for you.

- `MaxPacketSize()` should be implemented to return the maximum packet size as currently configured.

- `SetPromiscuous()` truns on promiscuous mode when `true` is passed, and turns off promiscuity when `false` is passed. When your device is in promiscuous mode, it should accept incoming packets for any address, not just your device's own packets.

- `Statistics()`, used primarily for debugging and network tuning, should output information about the device to the specified file.

- `Type()` should return the type of device your add-on represents.

### Multicasting

Multicasting is the ability for a single network interface to service multiple addresses. Network device add-ons must implement two functions to manage multicasting (even if you don't support it):

- `AddMulticastAddress()` should add a new address to the list of addresses that your device will service.

- `RemoveMulticastAddress()` should add an address from the list of addresses your device services.

If your device doesn't support multicasting, you can just return `B_ERROR` from both of these functions.

### Sending and Receiving Packets

Three functions must be implemented to send and receive packets via your device. Note that these may not be used by the Net Server if your device is an IP device, but must still be implemented. See BIpDevice for more details.

- `AllocPacket()` should allocate and return a pointer to a new packet. The packet returned must be of a class derived from BNetPacket (such as BStandardPacket, for example).

- `ReceivePacket()` should block until a packet arrives on the network, then return a pointer to the packet.

- `SendPacket()` should transmit a packet over the network. Once the packet has been sent, `SendPacket()` should delete the packet.

## Destructor

### ~BNetDevice()

          virtual ~BNetDevice()

Your derived class can implement the BNetDevice destructor, if necessary, to perform cleanup before objects of your derived class are deleted.

## Member Functions

### AddMulticastAddress()

          virtual status_t AddMulticastAddress(const char *address) = 0

Your derived class must implement this function, even if it does nothing. This function is called to add a multicast address to your device. The address can be assumed to be in the correct format for the type of device your add-on supports.

RETURN CODES

- `B_OK`. No errors occurred.
- Other errors, as appropriate.

### Address()

          virtual void Address(char *address) = 0

Your derived class should implement `Address()` to stuff the specified buffer with the address of the interface. The format of this buffer is device type specific, and can be assumed to be the right size for the data you need to place into it.

### AllocPacket()

          virtual BNetPacket *AllocPacket(void) = 0

Your derived class should implement `AllocPacket()` to return a pointer to a newly-instantiated BNetPacket-derived object. As discussed further in the section on BNetPacket, you should never instantiate BNetPacket directly; it's an abstract class that you should subclass.

Unless you have special needs, you can usually return a BStandardPacket:

       BNetPacket *AllocPacket(void) {
          return (new BStandardPacket());
       }

### Close()

          virtual void Close(void) = 0

Your derived class's implementation of `Close()` is called by the Net Server when your device is no longer in use. This function should close the device.

### MaxPacketSize()

          virtual unsigned MaxPacketSize(void) = 0

Implement this function to return the size, in bytes, of the maximum packet size setting currently in effect.

### OpenIP()

          virtual BIpDevice *OpenIP(void) = 0

Implement this function to open the IP device associated with the object's interface. If your device is an ethernet device, and you want to use the built-in IP device, you should return `NULL`. All other devices should return a pointer to an object of a type derived from BIpDevice.

The BIpDevice-derived object you return from this function will be used to send and receive IP packets on your network device; its `Run()` function will be called by the Net Server to cause it to begin monitoring the network for IP packets, and packets will be sent by calling its `SendPacket()` function. See the BIpDevice and BIpHandler sections for more information on implementing IP devices.

### ReceivePacket()

          virtual BNetPacket *ReceivePacket(void) = 0

The Network Server will call this function to receive a packet from the network interface defined by your add-on. This function should block until a packet arrives, then return a pointer to it.

### RemoveMulticastAddress()

          virtual status_t RemoveMulticastAddress(const char *address) = 0

Your derived class must implement this function, even if it does nothing. This function is called to remove a multicast address from your device. The address can be assumed to be in the correct format for the type of device your add-on supports.

RETURN CODES

- `B_OK`. No errors occurred.
- Other errors, as appropriate.

### SendPacket()

          virtual void SendPacket(BNetPacket *packet) = 0

Your derived class's implementation of `SendPacket()` is called to transmit the specified packet. When this function is called, you should send the packet, then delete it.

### SetPromiscuous()

          virtual status_t SetPromiscuous(bool promiscuous) = 0

This function is called to switch between promiscuous and non-promiscuous mode. When this function is called with promiscuous set to `true`, your add-on should switch the device into promiscuous mode. When promiscuous is `false`, you should ensure that promiscuous mode is disabled.

RETURN CODES

- `B_OK`. No errors occurred.
- Other errors, as appropriate.

### Statistics()

          virtual void Statistics(FILE *stat_file) = 0

Your implementation of `Statistics()` should output device status information to the specified file. This will typically be called for debugging purposes, but can also be used to provide valuable status information to users.

### Type()

          virtual net_device_type Type(void) = 0

This function returns the type of device your BNetDevice-derived class represents. The `net_device_type` can be one of the following:

- `B_NULL_NET_DEVICE` Not a real device.
- `B_ETHER_NET_DEVICE` Ethernet device.
- `B_PPP_NET_DEVICE` PPP device.
- `B_LOOP_NET_DEVICE` Loopback device.

This information is used by the Network Server, among other things, to determine the format of the device address and how the server should interact with your device add-on.

## Global C Functions

### deliver_packet()

          void deliver_packet(BNetPacket *packet, BNetDevice *device);

`deliver_packet()` delivers the specified packet to the Net Server. You should place a pointer to your add-on's own BNetDevice-derived object in the device parameter. This would be necessary if you implement a device, such as PPP, that receives packets from one interface (like a serial port) and needs to forward them to the Network Server to be processed. The Net Server, in return, will forward the packet to each packet handler that's registered as being interested in getting packets from your device.

The Be Book, in lovely HTML, for BeOS Release 3.

Copyright © 1998 Be, Inc. All rights reserved.

Last modified March 26, 1998.