The following pages contain a list of routines which 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.
Name
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
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 */ }
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.
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.
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.
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.
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.