Table of Contents

Table of Chapters

4. INTERNAL FUNCTIONS

The following pages contain a list of InterNiche internal routines which may be useful to programmers writing customized applications with the InterNiche stack. These functions are a subset of the routines in the libraries that are deemed to be of interest to a TCP/IP application or network interface writer.

4.1 ARP

Name

etainit()

Syntax

int etainit (void);

Parameters

None

File

ip/et_arp.c

Description

This needs to be called once at initialization time to initialize the ARP layer. It registers the ARP types with the hardware drivers and sets up an ARP timer.

Returns

General error codes as described in Error Codes in section 2.2.8.

Name

make_arp_entry()

Syntax

struct arptabent *make_arp_entry(ip_addr dest_ip, NET net);

Parameters

ip_addr dest_ip /* IP address to make entry for */

NET net /* associated network interface */

File

ip/et_arp.c

Description

Finds the first unused (or the oldest) ARP table entry and makes a new entry to prepare it for an ARP reply. If the IP address already has an ARP entry, the entry is returned with only the time stamp modified. The MAC address of the created entry is not resolved but left as zeros. The eventual ARP reply will fill in the MAC address.

Returns

Returns pointer to ARP table entry selected.

Name

arprcv()

Syntax

int arprcv(PACKET pkt);

Parameters

PACKET pkt /* the PACKET containing the incoming ARP packet */

File

ip/et_arp.c

Description

The upcall for received ARP packets. Called by the interface layer.

Returns

Returns 0 if it was for us, else a negative error code.

4.2 IP

Name

ip_write()

Syntax

int ip_write(u_char prot, PACKET p);

Parameters

u_char prot /*indication of which protocol the packet is carrying TCP,UDP,ICMP */

PACKET p /* a packet to send */

File

ip/ip.c

Description

Fills in the Internet header in the packet p and sends the packet through the appropriate net interface. This will involve using routing. Call with p->nb_plen and p->nb_prot fields set to start of upper (UDP) layer and p->fhost set to target IP address.

Returns

Returns 0 if sent OK, ENP_SEND_PENDING if waiting for ARP, else negative error code if error detected.

Name

ip2mac()

Syntax

int ip2mac(PACKET pkt, ip_addr dest_ip);

Parameters

PACKET pkt /* the packet itself, all set but for dest MAC addr */

ip_addr dest_ip /* the IP host or gateway to get MAC address for */

File

ip/ipnet.c

Description

Takes as input an outgoing IP packet with no MAC information and tries to resolve an Ethernet address matching the passed IP address. If the MAC address is not already cached, we broadcast an ARP request for the missing IP address and attach the packet to the "pending" pointer. The packet will be sent when the ARP reply comes in, or freed if we time out.

Returns

Returns SUCCESS (0) if packet went to MAC sender; ENP_SEND_PENDING if awaiting. ARP reply, or SEND_FAILED if error.

Name

ip_mymach()

Syntax

ip_addr ip_mymach(ip_addr host);

Parameters

ip_addr host /* IP address of foreign host to find */

File

ip/ip.c

Description

Returns the address of our machine relative to a given foreign host IP address. On a single homed host this will always return the sole interface's IP address; on a router it will return the address of the interface to which packets for the host would be routed.

Returns

Our IP address on one of our networks interfaces.

Name

iproute()

Syntax

NET iproute(ip_addr host, ip_addr *hop1);

Parameters

ip_addr host /* IP address of final destination host */

ip_addr *hop1 /* IP address to use in resolving MAC address */

File

ip/ip.c

Description

Performs IP routing on an outgoing IP packet. Takes the Internet address to which we want to send a packet and returns the net interface through which to send it. An IP address is returned pointed to by the output parameter hop1 which is the IP address for resolving the MAC destination address of the packets. If the target host is on our local segment, hop1 will be the same as host, else it will be the IP address of the gateway or router through which we might be able to reach host.

Returns

Returns a pointer to a net structure which describes the interface of the MAC media we should send the packet on. Returns NULL when unable to route.

Name

add_route()

Syntax

RTMIB add_route(ip_addr dest, ip_addr mask, ip_addr nexthop, int iface, int prot);

Parameters

ip_addr dest /* ultimate destination */

ip_addr mask /* net mask, 0xFFFFFFFF if dest is host address */

ip_addr nexthop /* where to forward to */

int iface /* interface (net) for nexthop */

int prot /* how we know it: icmp, table, etc */

File

ip/ip.c

Description

Make an entry in the route table directing dest to nexthop.

Returns

Returns a pointer to the table entry; so caller can process it further, i.e. add metrics.

Name

ip_rcv()

Syntax

int ip_rcv(PACKET p);

Parameters

PACKET p /* the received packet, with p->nb_prot and p->nb_plen pointing to the start of the IP header and Mac information fields filled in. */

File

ip/ipdemux.c

Description

This is the IP receive upcall routine. It handles packets received by network ISRs, etc., verifies their IP headers, and does the upcall to the upper layer that should receive the packet.

Returns

Returns 0 if packet was processed successfully, ENP_NOT_MINE if not for me, or a negative error code if packet was badly formed.

Name

parse_ipad()

Syntax

char * parse_ipad(ip_addr * ipout, unsigned * sbits, char * stringin);

Parameters

ip_addr * ipout /* pointer to IP address to set */

unsigned * sbits /* default subnet bit number */

char * stringin /* buffer with ascii to parse */

File

misclib/parseip.c

Description

Looks for an IP address in stringin buffer, makes an IP address (in big-endian) in ipout.

Returns

Returns NULL upon success, else returns a pointer to a string describing the syntax problem in the input string.

Name

print_ipad()

Syntax

char *print_ipad(unsigned long ipaddr);

Parameters

unsigned long ipaddr /* IP address to print, in Big-Endian (net order) */

File

misclib/in_utils.c

Description

Accepts a 32 bit IP address in big-endian format and returns a pointer to a volatile buffer with a printable version of the address. The buffer will be overwritten by each subsequent call to print_ipad, so the caller should copy it or use it immediately.

Note that the current implementation of print_ipad() is not re-entrant, and should not be used on a port to a pre-emptive RTOS.

Returns

Returns a pointer to the buffer with the printable IP address text.

Name

pk_alloc()

Syntax

PACKET pk_alloc(unsigned int len);

Parameters

unsigned int len /* length in bytes of packet data to be stored in buffer */

File

net/pktalloc.c

Description

pk_alloc() allocates a netbuf structure and associated packet buffer that the caller can use to store data to be transmitted or data that has been received. pk_alloc() is used internally by the InterNiche stack to pass data between the various protocol layers. The porting engineer should use pk_alloc() in his network interface software to pass packets received on the interface up to the InterNiche stack. For a description of how this is performed see the description of rcvdq.

Note that if you happen to be implementing Mutual Exclusion using the Net Resource Method as described in Section 2.2.3.2, then the FREEQ_RESID resource would need to be locked and unlocked while making calls to pk_alloc().

Returns

If the allocation was successful, a pointer to the allocated netbuf structure is returned. If allocation was unsuccessful, NULL is returned.

Name

pk_free()

Syntax

void pk_free(PACKET pkt);

Parameters

PACKET pkt /* ptr to netbuf structure previously allocated by pk_alloc() */

File

net/pktalloc.c

Description

pk_free() is used to return a previously allocated netbuf structure to the pool of such structures that is maintained by the InterNiche stack. The porting engineer should include a call to pk_free() in his network interface code in order to return a netbuf structure and its associated packet buffer to the free pool after the packet has been transmitted by the network device. For a description of how this is performed, see the description of pkt_send().

Note that if you happen to be implementing Mutual Exclusion using the Net Resource Method as described in Sec 2.2.3.2, then the FREEQ_RESID resource would need to be locked and unlocked while making calls to pk_free().

Returns

Nothing.

4.3 ICMP

Name

icmprcv()

Syntax

int icmprcv(PACKET p);

Parameters

PACKET p /* the received packet, with p->nb_prot and p->nb_plen pointing to the start of the ICMP header. p->fhost filled in. */

File

ip/icmp.c

Description

ICMP received packet upcall handler.

Returns

Returns 0 if we processed the packet, ENP_NOT_MINE, or a negative error code.

Name

icmp_destun()

Syntax

void icmp_destun(ip_addr host, struct ip *ip, unsigned type, NET net);

Parameters

ip_addr host /* host to complain to */

struct ip * ip /* IP header of offending packet */

unsigned type /* type of DU to send (PROT, PORT, HOST) */

NET net /* interface that this packet came in on */

File

ip/icmp.c

Description

Send an ICMP "destination unreachable" packet, where type indicates the type of the message. It should be one of the following defined constants:

DSTNET

DSTHOST

DSTPROT

DSTPORT

DSTFRAG

DSTSRC

Returns

No meaningful return value.

Name

icmpEcho()

Syntax

int icmpEcho(ip_addr host, char * data, unsigned length, unshort pingseq);

Parameters

ip_addr host /* host to ping - 32 bit, local-endian */

char * data /* ping data, NULL if don't care */

unsigned length /* total desired length of packet on media */

unshort pingseq /* ping sequence number */

File

net/ping.c

Description

Send an ICMP echo request (the guts of "ping"). Callable from Applications. Sends a single "ping" (ICMP echo request) to the specified host. The application must provide an appropriate pingDemux() routine if ping replies are to be checked.

Returns

Returns 0 if ping sent OK, else negative error code.

4.4 UDP

These calls to the UDP layer are provided for systems which do not implement Sockets. They are much more lightweight, but do not offer the portability of Sockets.

Name

udp_send()

Syntax

int udp_send(unshort fport, unshort lport, PACKET p);

Parameters

unshort fport /* target UDP port */

unshort lport /* local UDP port */

PACKET p /* packet to send, nb_prot ... nb_plen set to data, fhost set */

File

ip/udp.c

Description

Send a UDP datagram to the foreign host in p->fhost. local and remote ports in the UDP header are set from the values passed. Note: This will work just fine without doing a previous udp_open() on the associated ports, but any response to the packet will not be up-called since the UDP layer will have no data to de-multiplex it.

Returns

0 is OK, or a negative ENP_ error code.

Name

udp_alloc()

Syntax

PACKET udp_alloc(int datalen, int optlen);

Parameters

int datalen /* length of UDP data (not including udp header) */

int optlen /* length of IP options if any. Usually 0. */

File

ip/udp.c

Description

This returns a PACKET big enough for the UDP data. It works by adding the space needed for UDP, IP, and MAC headers to the datalen passed and calling pk_alloc(). It also ensures that the FREEQ_RESID resource is locked around the call to pk_alloc().

Returns

Returns a PACKET (pointer to struct netbuf) if OK, else NULL if a big enough packet was not available.

Name

udp_free()

Syntax

void udp_free(PACKET p);

Parameters

PACKET p /* ptr to netbuf structure previously allocated by udp_alloc() */

File

ip/udp.c

Description

udp_free() is used to return a previously allocated PACKET to the InterNiche stack's free pool. It works by calling pk_free(), but like udp_alloc() it ensures that the FREEQ_RESID resource is locked around the access to the free packet pool.

Returns

Void.

Name

udpdemux()

Syntax

int udpdemux(PACKET p);

Parameters

PACKET p /* received UDP PACKET, with nb_prot, nb_plen, set to start of UDP header; and fhost set to foreign host IP address */

File

ip/udp.c

Description

This is upcalled by ip_demux() when it has verified a received UDP packet.

Returns

0 if packet accepted, ENP_NOT_MINE if packet was not for us, or a negative ENP_ error code.

Name

udp_open()

Syntax

UDPCONN udp_open(ip_addr fhost, unshort fsock, unshort lsock, int (*handler) (PACKET, void *), void * data);

Parameters

ip_addr fhost /* host to receive from, 0 if any is OK */

unshort fsock /*foreign socket (port) number, 0 if any is OK*/

unshort lsock /* local socket (port) to receive on */

int * handler /* udp received callback function */

void * data /* returned on upcalls to aid de-muxing */

File

ip/udp_open.c

Description

This routine creates a structure in the UDP layer to receive and upcall UDP packets which match the parameter passed. The foreign host and socket can use 0 as a wild card. This allows us to start "listens" for incoming SNMP Stations, TFTP applications, etc. The handler routine passed is similar to the other upcall handler routines in this section except that it is also passed a copy of the "data" pointer which is passed to udp_open(). This can be any random data the programmer desires, such as a pointer to another routine or control structure to aid in de-multiplexing the received UDP packet.

Returns

NULL on failure, non-NULL on success.

Name

udp_close()

Syntax

void udp_close(UDPCONN con);

Parameters

UDPCONN con /* an open UDP connection */

File

net/udp_open.c

Description

udp_close() closes a udp connection, by removing the connection from UDP's list of connections and deallocating its internal structures.

Returns

Nothing.

4.5 MISCLIB

Name

ns_printf()

Syntax

int ns_printf(void * vio, char * format,...);

Parameters

void * vio /* pointer to output device structure */

char * format /* printf() style format string */

File

misclib/in_utils.c

Description

This function is called by various statistics reporting functions. Its usage is similar to that of the standard C library printf() function. The vio parameter addresses a structure that can be used to redirect the output of the function to some device other than the system console. When vio is NULL, output is directed to the system console.

Returns

A negative value if some error occurred, a non-negative number if successful.

4.6 Dynamic Network Interfaces

These calls form an API for creating, configuring, controlling, and deleting dynamic network interfaces once the stack has completed its initialization. They are present only if the stack is built with the DYNAMIC_IFACES option defined.

Name

ni_create()

Syntax

int ni_create(NET * newifp, int (*create_device)(NET newifp, void * bindinfo), char * name, void * bindinfo);

Parameters

NET * newifp /* pointer where a descriptor for the created network interface may be returned */

int * create_device /* the network interface driver's create_device() function */

char * name /* an optional name for the device */

void * bindinfo /* driver-specific binding information for the device */

File

ip/iface.c

Description

This function creates a new network interface, assigns a name to it, and binds it to a device driver and device. The caller provides a device driver's create_device() function, may also provide a short printable name string for the network interface (up to IF_NAMELEN characters long, including a terminating null), and may also provide binding information for the device driver to use to bind the network interface to the device.

Note that the name argument, if non-NULL, is expected to be a pointer to a short printable string that will be used as the name of the created interface. If the caller does not provide a name string (passes NULL as the name argument), the device driver may generate its own name for the network interface.

The bindinfo argument provides binding information that may be used by the create_device() function to bind the created network interface to a specific network device. The format of this argument is determined by the device driver's create_device() function.

On successful return, the newifp argument is used to return a descriptor for the created network interface. This descriptor is for use with the other dynamic network interfaces API calls to specify the network interface to be operated upon.

Returns

A negative value if some error occurred, zero if successful.

Name

ni_get_config()

Syntax

int ni_get_config(NET ifp, struct niconfig_0 * cfg);

Parameters

NET ifp /* descriptor for a network interface */

struct niconfig_0 * cfg /* buffer for return of interface configuration information */

File

ip/iface.c

Description

This function retrieves IP configuration information for a network interface. The caller provides a network interface descriptor and a buffer for the returned configuration information.

Returns

A negative value if an error occurred, zero if successful.

Name

ni_set_config()

Syntax

int ni_set_config(NET ifp, struct niconfig_0 * cfg);

Parameters

NET ifp /* descriptor for a network interface */

struct niconfig_0 * cfg /* buffer containing interface configuration information */

File

ip/iface.c

Description

This function sets IP configuration information for a network interface. The caller provides a network interface descriptor and a buffer containing the configuration information to be set.

Returns

A negative value if an error occurred, zero if successful.

Name

ni_set_state()

Syntax

int ni_set_state(NET ifp, int opcode);

Parameters

NET ifp /* descriptor for a network interface */

int opcode /* NI_UP to mark interface up, or NI_DOWN to mark it down */

File

ip/iface.c

Description

This function sets the current state of a network interface. The caller provides a network interface descriptor and an integer indicating the state to which the interface is to be set. The opcode argument must be NI_UP to set the interface state to "up", or NI_DOWN to set the interface state to "down".

Returns

A negative value if an error occurred, zero if successful.

Name

ni_delete()

Syntax

int ni_delete(NET ifp);

Parameters

NET ifp /* descriptor for a network interface */

File

ip/iface.c

Description

This function deletes a dynamic network interface. The caller provides a network interface descriptor for the network interface that is to be deleted.

Note that the ifp argument must be a descriptor for a network interface created via ni_create().

The n_close() routine associated with this dynamic network interface needs to be called before calling ni_delete(), so that the physical interface shutdown can be completed cleanly.

Returns

A negative value if an error occurred, zero if successful.

4.7 Syslog Client

InterNiche TCPIP stack ships with a syslog client. The syslog client can be used to send log messages (over UDP) to a syslog server. The API is based on the BSD syslog specification (man-pages). Hence part of the following documentation has been derived from BSD man pages. It inter-operates with all commercial syslog servers. InterNiche syslog client also has a special mechanism where-in different applications can send logs to different syslog servers.

4.7.1 Usability notes.

Applications can use syslog as follows.

  1. Use syslog directly. Just call syslog() to send the log.
  2. Use syslog when needed.
    • Call openlog() to open logging for a facility/application.
    • Call syslog() to send logs.
    • Call closelog() when done.
  3. Use syslog with special features (for InterNiche syslog client). We have defined a special mechanism where-in different applications can send logs to different syslog servers. To use this feature, use the following sequence.
    • Call openlog() to open logging for a facility/application.
    • Call openlogaddr() to set the syslog server address.
    • Call syslog() to send logs to the specific syslog server.
    • Call closelogfac() when done. This will close the logging session for the particular application.

Additional information about the syslog client

4.7.2 Interoperability notes

  1. The openlog(), syslog(), closelog(), setlogmask() functions work as per the BSD specs (man-pages).
  2. In addition to the above, specific functions like openlogaddr() and closelogfac() are provided.
  3. Support for other BSD syslog functions (like vsyslog()) is not provided.

4.7.3 Integration notes

The syslog client is already integrated with the NicheStack. Hence it can be used out-of-the-box. It can be easily ported to other environments too. To do that, the following points should be addressed.

  1. At system startup, call syslog_init() to initialize the syslog client. This is mainly needed to install the syslog sub-menu
  2. At system shutdown, call closelog() to cleanup the syslog client

4.7.4 Syslog API

Name

closelog()

openlog()

syslog()

setlogmask()

Syntax

void closelog (void);

void openlog (const char * ident, int logopt, int facility);

void syslog (int priority, const char * msg, ...);

int setlogmask (int maskpri);

Parameters

const char * ident; /* Identity of the application */

int logopt; /* Options for logging */

int facility; /* Application/facility doing the log */

int priority; /* Priority of the log */

int maskpri; /* Used to mask logs of lower priorities */

File

misclib/syslog.c

Description

The syslog() function writes message to the syslog server. The message is then written to the system console, log files, logged-in users, or forwarded to other machines as appropriate. The message is identical to a printf format string. ('%m' is supported by BSD, but not supported in this implementation). A trailing newline is added if none is present. The vsyslog() function of BSD is not supported. The message is tagged with priority. Priorities are encoded as a facility and a level. The facility describes the part of the system generating the message. The level is selected from the following ordered (high to low) list:

LOG_EMERGA panic condition. This is normally broadcast to all users.
LOG_ALERTA condition that should be corrected immediately, such as a corrupted system database.
LOG_CRITCritical conditions, e.g., hard device errors.
LOG_ERRErrors.
LOG_WARNINGWarning messages.
LOG_NOTICEConditions that are not error conditions, but should possibly be handled specially.
LOG_INFOInformational messages.
LOG_DEBUGMessages that contain information normally of use only when debugging a program.

The openlog() function provides for more specialized processing of the messages sent by syslog(). The parameter ident is a string that will be prepended to every message. The logopt argument is a bit field specifying logging options, which is formed by OR'ing one or more of the following values:

LOG_CONSIf syslog() cannot pass the message to syslogd it will attempt to write the message to the console
LOG_NDELAYOpen the connection to syslogd immediately. Normally the open is delayed until the first message is logged. Useful for programs that need to manage the order in which file descriptors are allocated.
LOG_PERRORWrite the message to standard error output as well to the system log.
LOG_PIDLog the process id with each message: useful for identifying instantiations of daemons.

The facility parameter encodes a default facility to be assigned to all messages that do not have an explicit facility encoded:

LOG_AUTHThe authorization system
LOG_AUTHPRIVThe same as LOG_AUTH, but logged to a file readable only by selected individuals.
LOG_CONSOLEMessages written to console by the kernel console output driver.
LOG_CRONThe cron daemon
LOG_DAEMONSystem daemons that are not provided for explicitly by other facilities.
LOG_FTPThe file transfer protocol daemons
LOG_KERNMessages generated by the kernel. These cannot be generated by any user processes.
LOG_LPRThe line printer spooling system
LOG_MAILThe mail system.
LOG_NEWSThe network news system.
LOG_SECURITYSecurity subsystems
LOG_SYSLOGMessages generated internally by syslogd()
LOG_USERMessages generated by random user processes. This is the default facility identifier if none is specified.
LOG_UUCPThe uucp system.
LOG_LOCAL0Reserved for local use. Similarly for LOG_LOCAL1 through LOG_LOCAL7.

The closelog() function can be used to close the log file.

The setlogmask() function sets the log priority mask to maskpri and returns the previous mask. Calls to syslog() with a priority not set in maskpri are rejected. The mask for an individual priority pri is calculated by the macro LOG_MASK(pri); the mask for all priorities up to and including toppri is given by the macro LOG_UPTO(toppri);. The default allows all priorities to be logged.

Returns

The routines closelog(), openlog(), syslog() return no value.

setlogmask() always returns the previous log mask level.

Name

openlogaddr()

closelogfac()

Syntax

void openlogaddr(int facility, struct sockaddr *sa, int sa_len, char *fname);

void closelogfac(int facility);

Parameters

int facility;

struct sockaddr *sa;

int sa_len;

char *fname;

File

misclib/syslog.c

Description

The function openlogadd() is used to start logging to a particular syslog server. InterNiche syslog client allows separate logging for each facility. Hence different applications can use this feature to log to different syslog servers. The fname parameter gives the name of the file where messages are to be logged.

When the application is done logging, it can call closelogfac() to close special logging for the particular facility.

Returns

None.