HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
adamdunkels
uip
C2014–2024
adamdunkels / uip

uip

The historical uIP sources

4Distinct people
5Mentions
0Explicit recommenders
1.1KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

The historical uIP sources

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year5 dated mentions

Observed mentions: 2014-11-16 23:25:03 UTC to 2024-06-30 11:49:01 UTC.

0122014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20142015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2024

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC101
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC000
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC000
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC000
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC000
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC000
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC000
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC202

What Hacker News says

5 sources
sorry to hear you gave up; how do things like luajit and node handle the x^w thing? also, i thought jonesforth was entirely interpretive; i didn't think it generated new machine code at runtime? a standard approach for target-compiling forth applications onto small machines, as i understand it, is to put some dictionary fields in one memory area and some dictionary fields in another. things like the immediate bit and the name go in memory area a; things like the cfa and dfa go in memory area b. then you only put memory area b in the rom image, thus saving space it seems like, if you want to generate new machine code at runtime in a forth system with x^w, you probably want to do a similar kind of segregation thing where code and (at least mutable) data go in different memory areas. data compiled with c, or , goes in the data area, and
Read the rest
probably things like the immediate bit and the name; newly generated machine code goes in the code area. the header for the word points at the code, as usual, via a pointer (let's say a bare pointer, not a jump; doing this kind of separation with direct threading would be more challenging), the cfa how do you handle switching the page between writable and executable? well, you could do it after every word you compile, just in case the next word calls it as immediate (say, inside of [ ]). but maybe that's too wasteful of pages, because it means each word gets its own page. (and you get terrible instruction cache contention if you put them all at the beginning of the page). probably the forth way would be to have a word you have to call explicitly to make all the previously defined words executable, but the automatic way that occurred to me is to initially point all the cfas at a trampoline routine. the trampoline, when invoked, moves the machine code for the currently-being-compiled word (if any) to a new page, updates the compilation state appropriately, and then changes the protection on all the previously compiled code that's trampolined out from writable to executable, and iterates over all the already-defined words in the dictionary, changing their cfa from pointers to itself to instead point at the new native code it's just made executable; when it reaches the point in the dictionary where it was previously invoked, it stops you say 'actually modify the core compiler itself', but normally you don't modify existing definitions in a forth dictionary; you just add new ones to the end of it, which shadow the previous ones. i think in colorforth and some other nonstandard systems, the global namespace works more like in lisp or python, where, if you redefine an existing word, all the words that called the old definition start calling your new definition instead. this is useful for interactive experimentation because you don't have to forget (or, worse, marker). if you want to implement that, you still don't have to actually change the existing machine code; you can compile your new machine code onto a new page and point the cfa of the old definition to the new definition. this is normally what you'd want to do with a traditional forth dictionary structure anyway because the definitions are packed tightly one after the other, with no padding in between, so if you were to overwrite a definition in place with a new, longer definition, you would also be overwriting the beginning of the definition after it as for tcp/ip, there are a pretty small number of implementations of tcp/ip in history. bsd unix's tcp/ip was copied into basically every unix and also microsoft windows and vax/vms wollongong tcp/ip (though the vax i used was on tgv multinet instead, whose provenance i don't know, though rumor has it 'tgv' was 'two guys and a vax' https://news.ycombinator.com/item?id=28190718). i don't know if cutcp (clarkson university tcp/ip) derived from the bsd code or not. plan9's i'm pretty sure didn't. there have been a few independent reimplementations of tcp/ip, but really a surprisingly small number—not just in forth, in any language. two of them are lwip and uip from contiki; they are small and simple, though uip in particular is hardly rock-solid, and may be good information about the minimal amount you need to implement to have a usable tcp/ip stack uip https://github.com/adamdunkels/uip is 2900 lines of c (uip/uip/ and uip/lib/); its example webclient is another 500. couple that with tweetnacl and you might have a worked example of how to get online lwip is described by wikipedia as 'widely used', and the current version https://github.com/lwip-tcpip/lwip is 125000 lines of c. but if you only count lwip/src/core/, lwip/src/include/, and lwp/src/api/ it's 'only' 41000 lines. of that about 10% is ipv6 support but if you git checkout 3551b2a2 you have version 1.2.0 from 02006 which is 'only' 26000 lines and already supports ip (v4 and v6), arp, tcp, udp, dhcp, snmp, slip, ppp, and ethernet. boehm's cocomo model estimates this as 6.2 person-years of work based on the number of lines of code (generated using david a. wheeler's 'sloccount'), so it's clearly not a career-long research project, and maybe it could be a lot faster if you're cloning an existing working system like this instead of designing something from scratch plausibly in forth you could do a better job, because forth is better at embedded dsls, and as vpri showed, implementing tcp/ip really benefits a lot from embedded dsls
In bigFORTH (1997-)
Something similar from... a while ago. How does it compare? https://web.archive.org/web/20060615041317/http://www.sics.s... uIP is an implementation of the TCP/IP protocol stack intended for small 8-bit and 16-bit microcontrollers. It provides the necessary protocols for Internet communication, with a very small code footprint and RAM requirements - the uIP code size is on the order of a few kilobytes and RAM usage is on the order of a few hundred bytes. https://github.com/adamdunkels/uip https://en.wikipedia.org/wiki/UIP_(software) (I believe uIP was extracted and improved upon from Contiki, a C64 OS with TCP/IP support written in C in 2002: https://www.c64-wiki.com/wiki/Contiki)
In Show HN: MicroTCP, a minimal TCP/IP stack
The CPU architecture is actually the least of your concerns there—I'm pretty sure qemu-user can run httpdito on ARM with less than an order of magnitude performance overhead. There are a lot of embedded systems where an HTTP transaction per second per MHz would be more than sufficient. The bigger problem is that the Raspberry Pico is a dual-core Cortex-M0+, which doesn't have an MMU, so it can't run Linux and especially can't handle fork(). But httpdito is basically scripting the Linux system call interface in assembly language—it needs to run on top of a filesystem, an implementation of multitasking that provides allocation of different memory to different tasks, and a TCP/IP stack. Any one of these is probably a larger amount of complexity than the 296 CPU instructions in httpdito. The smallest TCP/IP stack I know of is Adam Dunkels'
Read the rest
s uIP. Running `sloccount .` in uip/uip cloned from https://github.com/adamdunkels/uip gives a count of 2796 lines of source code ("generated using David A. Wheeler's 'SLOCCount'."). uIP can run successfully on systems with as little as 2KiB of RAM, as long as you have somewhere else to put the code, but for most uses lwIP is a better choice; it minimally needs 10KiB or so. uIP is part of Dunkels's Contiki, which includes a fairly full-featured web server and a somewhat less-full-featured browser. I think he got both the server and the browser to run in 16KiB of RAM on a Commodore PET, but not at the same time. (twIP http://dunkels.com/adam/twip.html is only 139 bytes of C source but doesn't support TCP or any physical-layer protocol such as Ethernet, PPP,or SLIP.) However, Adam Dunkels has also written Miniweb http://dunkels.com/adam/miniweb/, which implements HTTP and enough of TCP and IP to support it, in 400 lines of C. It needs at least 30 bytes of RAM. Like twIP, it doesn't provide a physical layer. But that's solvable.
In An HTTP server in a single .c file
> Not exactly what I would cite for sane code. The uses of goto I saw compensate for C's lack of nested breaks and continues. Reasonable people may differ on this topic, but I'm perfectly fine with it. The real sin is obfuscating the natural control flow of a program by introducing dummy variables like try_again and keep_running, or being forced to split things into multiple functions just so you can use a return in lieu of a nested break. (There are single-exit zealots for whom an early-out return like that would be an equally grievous sin as the goto!) In any case, my point was to demonstrate by example that serious software can be written this way. The point wasn't to hold up uIP or Contiki or anything else as impeccable exemplars of coding style. > P.S. UIP doesn't use the coroutine stuff at all it seems. It's not used in the core bu
Read the rest
t in the protocol servers: https://github.com/adamdunkels/uip/blob/master/apps/webserve.... All the PT and PSOCK code is protothreads.
In Coroutines in C (2000)

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.