The SIP project
ORIGINAL SITE: http://www.ensica.fr/~frances/sip.html
Goals
The SIP project aims to provide small computers (like old 8-bit computers
or embedded microcontrollers with little memory) with standard Internet
access through a TCP/IP/PPP stack on top of a RS232 link.
This development should demonstrate that you don't need a Mega-Turbo-Pentium-GTI
(tm Intel) with 64 MB memory, running Windows 2010 (tm Microsoft),
in order to really connect to the Net (you can connect to the Net using
a dumb terminal, but providers of such accounts will be more and more rare).
More than that, with such traffic on the Net nowadays, you could surprise
your friends because a big cpu won't make a big difference if you can only
grab a few hundreds of bytes per second...
In order to allow applications running on top of SIP, like mail, ftp, telnet,
www, etc. clients, the smallest memory footprint is targetted.
Design choices
- SIP is single-thread, single-process software !
- This comes from the fact small microprocessors have little or no
provision for multitasking (one can always implements some sort of multitasking
even on 8-bit processors, but this leads to akward software and less efficient
than a pure sequential approach)
- This means that only one application will be running at any time
: you won't be able to ftp in the background, but do you care ? But don't
assume a monolithic software : in order to fit in tight memory requirements,
only necessary layers will reside in memory at once. For example, during
PPP connection, the resident part consists of PPP 's encapsulation and data
link layer but all the LCP, PAP and IPCP stuff resides in a transient application.
Once the connection is established and configured, all this stuff goes out,
leaving space to an IP resident layer, plus *one* transient application
containing (or loading) the needed additional layers : for example, a PING
program comes with the ICMP stuff. So, right, if you play with an UDP application,
the ICMP software won't be in, and your computer won't respond to ICMP requests.
Once again, who cares ?
- A light exception to the rule concerns the lowest layers, which
are interrupt-driven : I don't want to lose bytes coming from the serial
interface...
- This design choice removes the need for buffering in most layers.
Buffering is nice for big multi-tasking platforms, but it consumes a lot
of memory. Instead, SIP only buffers at the lowest layer : since it is single-process
software, application data is carried down the layers to the interrupt-driven
serial emitter, and application GOES DOWN THE LAYERS in order
to get data (this is rather transparent to the application programmer who
don't need to know if the data came from the lowest layers thanks to a lot
of signals or messages, or simply by procedure calls)
- SIP is minimalist !
- Take a look at the size of the IP implementations you find on powerful
platforms : Linux' pppd executable is already 70 KB, and it's only
PPP (and without the HDLC-like framing which is implemented in the kernel).
Take a look at some TCP/IP sources and you might be even more frightened...
- SIP aims to be inter-operable with other IP implementations but
without implementing every option described in the RFCs, without using de-facto
structures introduced by the BSD implementation, and sometimes with simplified
protocol (for example, the LCP automaton is not complete, instead it expects
'normal' behavior from the peer, so it will be less robust to ill-behaved
implementations... but in this fat-software world, other implementations
are supposed to be error-free, aren't they ?-)
First targets,
development environment
Ok, time for you to have a laugh : this project tries to give a second life
to old 8 bit computers, or all those computers people think they aren't
powered enough to run internet software. Here are the two computers I want
to plug to the Net : an 8088 with 64KB memory (it's a PC-XT in fact), and
an Oric Atmos (this one has a 1 MHz 6502, and no serial port, but serial
interface add-ons exist). However, the code could easily serve other 8-bit
platforms than the AppleII, C64, 8-bit Atari's, etc., because most of it
is written in C. Of course, you need a C compiler on your platform. On the
8088, many compilers are available, just pick an old enough version to develop
'tiny model' programs. On the 6502, I use the lcc compiler with my 6502
code generator, the code is very good (some people have reported it is better
than commercial compilers like AD2500's). But I'm also waiting for a 6502
code generator the folks at Franklin Electronic Publishers have developed
for *GCC* !
However, to ease development, the code will be tested on Linux first.
Current state
I'm building the stuff bottom-up, as can be seen from the following :
- RS232 driver
- This piece of code is hardware-dependent, I'm writing it for the ACIA
6551 (I might use a 8250 if I need to do a lot of tests and require a simpler
cross-development environment). The serial interrupt takes the bytes to
emit in a buffer, and fills another buffer with the received bytes. I've
written rs232_send and rs232_rcv routines which put and get bytes in the
buffers.
- There is also an rs232_active_wait (could be renamed one day) routine
that allows for the timeouts required by upper levels (LCP or TCP for example)
: in such a timeout condition, a 'longjmp' returns directly to the high
level without the need for multiple processes...
- Data Link Layer
- I've written hdlc_send and hdlc_rcv routines in C. These routines
provide framing, transparency (ACCM is handled too), and FCS computations
so that the upper PPP part is able to send and receive PPP packets.
- However, I'm now merging the RS232 driver and the framing and transparency
code, so that the interrupt driven code deals with frames that fit in a
255-bytes buffer.
- Multi-protocol PPP encapsulation
- I've written ppp_send and ppp_rcv routines in C. ppp_send does not
do a lot : it just prepend the protocol to the information field. ppp_rcv
is asked a specific protocol packet, and repeatedly asks PPP packet from
the previous layer until it gets a packet with the expected protocol, other
packets are dropped (some accounting is done for LCP, IPCP, IP dropped packets)
- Link Control Protocol
- Not written yet, but here is the overall specification : I intend
to request a MRU of 249 bytes (255 minus address, control and FCS fields
of HDLC, minus protocol field of PPP) and an ACCM of 0 (all control chars
allowed). I will reject every option except Authentication and ACCM, and
will negociate PAP and ACCM.
- The automaton is somewhat modified/simplified: the code will send
a Configure-Req and start a timeout, then requests a LCP packet, re-send
the Configure-Req if the timer expires before receiving a Configure-Ack/Nak/Rej,
answer to Configure-Req, etc. When it seems we enter the Opened state, an
Echo-Req will be sent and the reply waited for, to be sure the peer has
entered Opened state too.
- Password Authentication Protocol
- This one has not been written yet, but it's rather easy.
- IP Control Protocol
- This one not written yet, but will be about the same as the LCP negociation,
refusing to use IP compression, and asking the IP local address from the
peer.
- ARP/RARP
- Ah, ah, easy, there's no need for ARP or RARP on a point-to-point
link.
- IP
- I'm adapting some code from Douglas Comer's book here (the code he
used in Xinu, but adapted for single-process behavior, and different low-level
data structures). The hitch is there's no fragmentation-defragmentation
in his code. Applications which send small datagrams won't be annoyed if
this stuff is missing, so I still wonder I need fragmentation (I surely
need defragmentation with such a small MRU).
- Routing ? easy, all datagrams are sent to the peer...
- Concerning demultiplexing : like the PPP encapsulation, upper layers
will request a specific protocol (ICMP, UDP, TCP), so the IP layer will
request packets from the PPP layer until an IP datagram with the right protocol
is returned. Other datagrams will be dropped (and an accounting of these
dropped packets will be done)
- ICMP
- Adapted from Douglas Comer's book again, only a subset of ICMP datagrams
are recognized, but this allows to 'ping' every host in the world. For diagnostic
purposes, an ICMP 'server' will be written as an application (answering
echo request, etc.).
- UDP
- Adapted from Comer's code again, this piece of code just add ports
to the IP addresses.
- TCP
- I'm asking for help here, I don't want to adapt the code from Wright
& Stevens... If someone has ideas for a small implementation of TCP,
jump in ! A first step might be to not use windows and wait the acknowledge
after every segment sent, however I have not thought a lot about it yet...
- Applications
- On top of UDP are some easy applications to write, exploiting the
classic services (echo, users, day and time, dns, tftp, etc.). Of course,
SIP will only be of interest if TCP is implemented along with clients (servers
too ?-) for ftp, telnet, smtp, pop3, http, etc. (ok, don't hold your breath)
-
I want you !
I have started this development, and should reach UDP and some trivial UDP
applications in 'some time' (don't ask when). If you are interested in making
the project go faster, join in !
If you see flaws in the design, tell me too !
FAQ
This is First Asked Questions, not Frequently Asked Questions yet. As I'm
just making this 'call for contributions' now, no questions have been raised
yet 8-)
Ok, if you want to contribute or ask something, you might need to mail-me.
- What does SIP stand for anyway ?
- Well, IP stands for Internet Protocol of course, but the 'S' is what
you prefer : either Simple, or Small, or Single-process,
or Super ;-)