Copyright ã1995 by NeXT Computer, Inc.  All Rights Reserved.

IONetwork

Inherits From:	Object

Declared In:	driverkit/IONetwork.h

Class Description

The IONetwork class connects direct drivers, such as Ethernet drivers, into the kernel network interface. One IONetwork object is associated with each instance of a network direct driver. In the future, support may be added for indirect network drivers, as well. 

Network direct drivers must implement the IONetworkDeviceMethods protocol, so that the IONetwork can send them messages.

Note:  Network drivers must run in the kernel.

See the IOEthernet specification for information on how to write Ethernet drivers, and the IOTokenRing specification for information on writing Token Ring drivers. See Chapter 8, ªNetwork Modules,º in NEXTSTEP Operating System Software for more information about network drivers.

Instance Variables

None declared in this class.

Method Types

Initializing an IONetwork instance
- initForNetworkDevice:name:unit:type:
maxTransferUnit:flags:
- finishInitialization

Passing packets from the driver up to the protocol stack
- handleInputPacket:extra:

Outputting a packet	- outputPacket:address:

Performing a command	- performCommand:data:

Allocating a network buffer	- allocateNetbuf

Keeping statistics	- collisions
- incrementCollisions
- incrementCollisionsBy:
- incrementInputErrors
- incrementInputErrorsBy:
- incrementInputPackets
- incrementInputPacketsBy:
- incrementOutputErrors
- incrementOutputErrorsBy:
- incrementOutputPackets
- incrementOutputPacketsBy:
- inputErrors
- inputPackets
- outputErrors
- outputPackets

Instance Methods

allocateNetbuf

- (netbuf_t)allocateNetbuf

This method creates and returns a netbuf to be used for an impending output.

This method doesn't always have to return a buffer. For example, you might want to limit the number of buffers your driver instance can allocate (say, 200 kilobytes worth) so that it won't use too much wired-down kernel memory. When this method fails to return a buffer, it should return NULL.

Here's an example of implementing allocateNetbuf.

#define my_HDR_SIZE    14
#define my_MTU        1500
#define my_MAX_PACKET  (my_HDR_SIZE + my_MTU)

- netbuf_t allocateNetbuf
{
    if (_numbufs == _maxNumbufs)
        return(NULL);
    else {
        _numbufs++;
        return(nb_alloc(my_MAX_PACKET));
    }
}

See also:  nb_alloc() (NEXTSTEP Operating System Software)

collisions

- (unsigned int)collisions

Returns the total number of network packet collisions that have been detected since boot time.

finishInitialization

- (int)finishInitialization

This method should perform any initialization that hasn't already been done. For example, it should make sure its hardware is ready to run. You can specify what the integer return value (if any) should be. 

If you implement this method, you need to check that [self isRunning] == YES.

handleInputPacket:extra:

- (int)handleInputPacket:(netbuf_t)packet extra:(void *)extra

Increments the number of input packets and passes packet to the kernel for processing. The kernel dispatches the packet to the appropriate protocol handler, as described <<only in the OS book, for now>>. 

A network device driver should invoke this method after it's processed a newly received packet. The value of extra should be zero, unless the protocol handler requires another value. For instance, token ring drivers need to return a valid pointer to a token ring header. This method returns EAFNOSUPPORT if no protocol handler accepts the packet; otherwise, it returns zero.

incrementCollisions

- (void)incrementCollisions

Increments by one the total number of network packet collisions that have been detected since boot time. 

incrementCollisionsBy:

- (void)incrementCollisionsBy:(unsigned int)increment

Increments by increment the total number of network packet collisions that have been detected since boot time. 

incrementInputErrors

- (void)incrementInputErrors

Increments by one the total number of packet input errors that have been detected since boot time.

incrementInputErrorsBy:

- (void)incrementInputErrorsBy:(unsigned int)increment

Increments by increment the total number of packet input errors that have been detected since boot time.

incrementInputPackets

- (void)incrementInputPackets

Increments by one the total number of packets that have been received by the computer since boot time. You usually don't need to invoke this method because handleInputPacket:extra: does so for you.

incrementInputPacketsBy:

- (void)incrementInputPacketsBy:(unsigned int)increment

Increments by increment the total number of packets that have been received by the computer since boot time. 

incrementOutputErrors

- (void)incrementOutputErrors

Increments by one the total number of packet output errors that have been detected since boot time.

incrementOutputErrorsBy:

- (void)incrementOutputErrorsBy:(unsigned int)increment

Increments by increment the total number of packet output errors that have been detected since boot time.

incrementOutputPackets

- (void)incrementOutputPackets

Increments by one the total number of packets that have been transmitted by the computer since boot time.

incrementOutputPacketsBy:

- (void)incrementOutputPacketsBy:(unsigned int)increment

Increments by increment the total number of packets that have been transmitted by the computer since boot time.

initForNetworkDevice:name:unit:type:maxTransferUnit:flags:

- initForNetworkDevice:device 
name:(const char *)name 
unit:(unsigned int)unit 
type:(const char *)type 
maxTransferUnit:(unsigned int)mtu 
flags:(unsigned int)flags

Initializes and returns the IONetwork instance associated with the specified direct device driver device. This method connects device into the kernel's networking subsystem. It's typically called from a network driver's implementation of initFromDeviceDescription. You shouldn't invoke initForNetworkDevice:... directly. IOEthernet and IOTokenRing invoke this method on behalf of their subclasses and return an IONetwork object in their respective attachToNetworkWithAddress: methods.

The name argument should be set to a constant string that names this type of network device. For example, Ethernet drivers are named ªenº, and Token Ring drivers are named ªtrº. The unit is an integer greater than or equal to zero that's unique for name. For example, the first instance of an Ethernet driver is unit 0, the second is unit 1, and so on.

The type is a constant string that describes this module. For example, Ethernet drivers supply the constant IFTYPE_ETHERNET (which is defined in net/etherdefs.h to be ª10MB Ethernetº). 

The mtu is the maximum amount of data your module can send or receive. For example, Ethernet drivers use the value ETHERMTU, which is defined in the header file net/etherdefs.h as 1500.

Finally, flags defines the initial flags for the interface. Possible values are:

IFF_UP:	If true, this interface is working.
IFF_BROADCAST:	If true, this interface supports broadcast.
IFF_LOOPBACK:	If true, this interface is local only.
IFF_POINTTOPOINT:	If true, this is a point-to-point interface.

inputErrors

- (unsigned int)inputErrors

Returns the total number of packet input errors that have been detected since boot time.

inputPackets

- (unsigned int)inputPackets

Returns the total number of packets that have been received by the computer since boot time.

outputErrors

- (unsigned int)outputErrors

Returns the total number of packet output errors that have been detected since boot time.

outputPacket:address:

- (int)outputPacket:(netbuf_t)packet address:(void *)address

This method should deliver the specified packet to the given address. Its return value should be zero if no error occurred; otherwise, return an error number from the header file sys/errno.h.

If you implement this method, you need to check that [self isRunning] == YES. If so, insert the necessary hardware addresses into the packet and check it for minimum length requirements.

outputPackets

- (unsigned int)outputPackets

Returns the total number of packets that have been transmitted by the computer since boot time.

performCommand:data:

- (int)performCommand:(const char *)command data:(void *)data

This method performs arbitrary control operations; the character string command is used to select between these operations. Although you don't have to implement any operations, there are five standard operations. You can also define your own operations. 

The standard commands are listed in the following table. The constant strings listed below are declared in the header file net/netif.h (under the bsd directory of /NextDeveloper/Headers).

Command	Operation

IFCONTROL_SETFLAGS	Request to have interface flags turned on or off. The data argument for this command is of type union ifr_ifru (which is declared in the header file net/if.h).

IFCONTROL_SETADDR	Set the address of the interface.

IFCONTROL_GETADDR	Get the address of the interface.

IFCONTROL_AUTOADDR	Automatically set the address of the interface.

IFCONTROL_UNIXIOCTL	Perform a UNIX ioctl() command. This is only for compatibility; ioctl() isn't a recommended interface for network drivers. The argument is of type if_ioctl_t *, where the if_ioctl_t structure contains the UNIX ioctl request (for example, SIOCSIFADDR) in the ioctl_command field and the ioctl data in the ioctl_data field.

An example of implementing performCommand:data: follows.

- (int)performCommand:(const char *)command data:(void *)data
{
    int error = 0;

    if (strcmp(command, IFCONTROL_SETFLAGS) == 0)
        /* do nothing */;
    else
    if (strcmp(command, IFCONTROL_GETADDR) == 0)
        bcopy(&my_address, data, sizeof (my_address));
    else
        error = EINVAL;
    
    return (error);
}