Table of Contents

Table of Chapters

3. FUNCTIONS (1)

The following pages contain a list of routines were tailored in the process of porting NicheLite to this particular target and are listed here as they may also be useful to the programmer writing customized applications with the InterNiche stack. It is anticipated that the bulk of the API of interest to the application writer are contained in Chapter 4 - MINI-SOCKETS TCP API

The following pages contain a list of InterNiche internal routines which may be useful to programmers writing customized applications with the InterNiche stack.

3.1 Port Tailored Functions

Name

port_prep

Syntax

extern int (* port_prep)(int already_found);

Parameters

int already_found /* index for nets[ ] structure to use */

Description

This is a pointer to a function. It should be initialized in pre_task_setup() to the actual function (implemented by the porting engineer). This function should prepare the nets[ ] structures for the network interfaces that the target system will want to use. The integer passed is the nets[ ] index of the interface to set up.

The nets[ ] members which need to be filled in are described in Section 2.2.2, entitled "The net Structure, the nets[ ] Array"

Returns

Returns the nets[ ] index of the next interface to be set up. If no interfaces were set up, the returned value is the same as the passed value.

Name

npalloc

npfree

Syntax

void *npalloc(int size);

void *npfree(void *);

Description

All the IP stack's dynamic memory is allocated by calls to npalloc() and released by calls to npfree(). The syntax for these is exactly the same as the standard C library calls malloc() and free(), with the exception that buffers returns from npalloc() are assumed to be pre-initialized to all zeros. In this respect npalloc() is like calloc().

If the target system already supports standard calloc() and free() calls, all that is necessary is to add the following lines to ipport.h_h:

#define npalloc(size)  calloc(1, size)
#define npfree(ptr)    free(ptr)

In the event your target system does not support calloc() and free(), you will need to implement them. An exhaustive description of how these functions work and sample code is available in "The C Programming Language" by Kernighan and Ritchie.

The great majority of the calls to npalloc() are made at initialization time. Only the UDP and TCP layers require these calls during runtime. If your system has severe memory shortages, then these layers can be modified to use pre-allocated blocks of static memory rather than implement a fully functional npalloc() and npfree(), but this is invariably more work and puts limits on the number of simultaneous connections which can be supported.

One issue that must be dealt with on some target processors is memory alignment. Some processors will generate faults if instructions to read or write more than one byte of memory at a time from odd numbered addresses are executed. Even if the target processor supports 2 or 4 byte reads and writes to odd numbered addresses, instructions of this sort usually execute more slowly than accesses to addresses that are an integer multiple of the number of bytes accessed by the instruction. System performance can suffer. If the target system supports the standard calloc() and free() calls then the C library vendors have probably already made sure that the buffers returned by calloc() are properly aligned for the target processor. However if you need to implement npalloc() and npfree() without the standard C library memory allocation functions then you should implement these functions such that the memory blocks are aligned on addresses that are a multiple of the data bus width of the target processor. If you don't know the data bus width of the target processor, 4 is usually a safe guess.

Returns

npalloc() returns a pointer to the block allocated or NULL if memory is unavailable.

Name

dtrap()

Syntax

void dtrap(void);

Description

This primitive is intended to hook a debugger whenever it is called.

Returns

Usually nothing, depends on porting engineer modifications.

Name

dprintf()

initmsg()

Syntax

void dprintf(char *, ...);

void initmsg(char *, ...);

Description

These two routines are functionally the same as the standard C library printf() function and are called by the stack code to inform the porting engineer or end user of system status. initmsg() prints status messages at initialization time. dprintf() prints error warnings during runtime.

InterNiche provides an version of printf() in misclib/ttyio.c. This implementation does not support floating point formats, but is otherwise consistent with standard specifications for the function. The compile-time macro NATIVE_PRINTF (ipport.h) determines whether this code, or a user/library implementation is to be used.

Name

dputchar()

Syntax

void dputchar(int chr);

Description

The InterNiche CUI routines call dputchar() in order to display a character on the target system display or monitor port. If such output is not desired, dputchar() can be implemented as a no-op. Its parameter is an ASCII character that should be displayed on the target system display or monitor device.

dputchar() should perform newline expansion. If the value of chr is an ASCII newline character (0xa) then a newline followed by a carriage return should be output to the display device.

Returns

Nothing.

Name

kbhit()

Syntax

int kbhit(void);

Description

kbhit() should return a non-zero value if a keystroke has been entered by a user at the CUI of the target system. It should not dequeue the character itself from the input device, rather the return value from kbhit() should simply poll the device to determine if a character is present. The entered character is retrieved using the getch() function.

Returns

0 if no character had been entered at the input monitor device, non-zero if at least one character is available.

Name

getch()

Syntax

int getch(void);

Description

kbhit() and getch() are used together to effect CUI input. The stack code calls kbhit() to determine if a character is available and then if a character is available, calls getch() to return the value of the character. getch() should never block for user input.

Returns

If a character is available at the CUI or system monitor device, getch() returns the ASCII value of that character. Its return value is undefined if no character is available.

Name

ENTER_CRIT_SECTION()

EXIT_CRIT_SECTION()

Syntax

#define ENTER_CRIT_SECTION(p);

#define EXIT_CRIT_SECTION(p);

Parameters

None that are currently used.

Description

These two entry points should be designed to be paired around sections of code that must not be interrupted or pre-empted. Usually, ENTER_CRIT_SECTION() should save the processor interrupt state and disable interrupts, whereas EXIT_CRIT_SECTION() should restore the processor interrupt state to as it was before the most recent call to ENTER_CRIT_SECTION(). On UNIX-like systems they can be mapped to the spl() primitive. Only the definitions are given here; for examples see the source code.

The stack source code always pairs these two in the same routines. For example, one common architecture takes advantage of this to push the existing flags register onto the processor stack, saving the interrupt flag state and retrieves the value for the flags register later, restoring the interrupt flag as it was before the ENTER_CRIT_SECTION() call.

The parameter p is currently unused.

Returns

These return no meaningful value.

Name

LOCK_NET_RESOURCE()

UNLOCK_NET_RESOURCE()

Syntax

void LOCK_NET_RESOURCE(int resID);

void UNLOCK_NET_RESOURCE(int resID);

Parameters

The integer defined constants, NET_RESID, RXQ_RESID or FREEQ_RESID.

Description

Returns

Nothing.

Name

cksum()

Syntax

unsigned short cksum (char *buffer, unsigned word_count);

Parameters

char *buffer /* pointer to buffer to checksum */

unsigned word_count /* number of 16 bit words in buffer */

Description

Returns 16 bit Internet checksum of buffer. Algorithms for this are described in RFC1071.

NOTE: A portable C language version of this routine is provided with the demo packages, however TCP implementations can spend a significant portion of their CPU cycles in the checksum routine. This routine is described here to encourage porting engineers to optimize their ports by implementing their checksum routines in assembly language.

Returns

The 16 bit checksum.

Name

panic()

Syntax

void panic(char *msg);

Parameters

char *msg /* short test message describing the fault */

Description

panic() is called if the InterNiche stack software detects a fatal system error. msg is a string describing problem. What this should do varies with the implementation. In a testing or development environment it should print messages, hook debuggers, etc. In an embedded controller, it should try to restart (i.e. warm boot) the system.

Sample for a DOS application is shown below.

Returns

Generally there is no return from this routine, however it is sometimes useful to allow a return under control of a debugger.

Example

void
panic (msg)
   char *msg;
{
   dprintf("panic: %s\n", msg);
   dtrap();      /* try to hook debugger */
   netexit(1);   /* try to clean up */
}

Name

sysuptime()

Syntax

unsigned long sysuptime(void);

Parameters

None

Description

Returns the number of 1/100ths of a second that have elapsed since the target system was last booted.

Returns

See above.

Example

unsigned long sysuptime()
{
   return ((cticks/TPS)*100);   /* 100ths of a sec since boot time */
}

3.2 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.1.

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.

3.3 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.

Returns

Our IP address on one of our networks interfaces.

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.

Note that if you happen to be implementing Mutual Exclusion using the Net Resource Method, 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.

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

Returns

Nothing.

3.4 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.

3.5 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.

3.6 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.