October 29, 2022

BSD TCP/IP for Kyu - First stab at a Makefile

This is a first "recon" to see what sorts of issues I am going to get into trying to compile files from the Net/3 sources and include them in Kyu.

First I copy netinet/tcpinput.c to a new directory tcp_bsd. Some fine day I will generate tcp_bsd.o in this directory and link it into Kyu. At least that is the idea.

Include files

Naturally, this is the first issue that arises. After several iterations my Makefile looks like this:
# Makefile for Kyu on the ARM processor
#
# build tcp_bsd
#
# Tom Trebisky  10-29-2022

BSD_NET3 = /u1/BSD/4.4BSD-Lite/usr/src
BSD_SRC = $(BSD_NET3)/sys

INCS = -I. -I..
INCS += -I$(BSD_SRC)

# To get time.h
# /u1/BSD/4.4BSD-Lite/usr/src/include/time.h
INCS += -I$(BSD_NET3)/include

# I get the complaint: machine/endian.h: No such file or directory
#/u1/BSD/4.4BSD-Lite/usr/src/sys/i386/include/endian.h

# to solve this I need a link in the source directory from
# machine --> i386/include

include ../Makefile.inc

OBJS = tcp_input.o

all: ../tcp_bsd.o

../tcp_bsd.o: $(OBJS)
	$(LD) -r -o ../tcp_bsd.o $(OBJS)

clean:
	rm -f *.o
For now I am letting my build script find files in the pristine source directories, but ultimately I will copy the "sys" directory (or part of it). I need to pay attention to which files in "net" and "netinet" I actually need.

The file "machine/endian.h" is architecture specific and as per the note in the makefile, I make a link for the machine directory (pointing to i386/include). Something entirely different will be done for Kyu, perhaps examining the actual macros being used which are already provided in a different way for Kyu.

The file "time.h" comes from an even higher level of the operating system. We add a link that works for now, but will need to look at exactly what this provides. It probably provides a timeval to hold a time of day timestamp. Something Kyu does not at this time provide. The question will be what use Net/3 makes of such a timestamp. Is it just there for debugging and logging or does it in some way play a part in making the protocol work?

Compiler issues

Most of the following went away when I simply defined -DKERNEL and allowed tcp_var.h do what it was supposed to do.

I am using gcc 11.2.1 which I install from the Red Hat package collection for the current version of Fedora. Currently I am running Fedora 35. This compiler views ANSI C as the norm and we are dealing with old traditional C without prototypes. This means we get quite a few warnings.

Here is the first sort:

/u1/BSD/4.4BSD-Lite/usr/src/sys/sys/systm.h:113:51: warning: ‘struct proc’ declared inside parameter list will not be visible outside of this definition or declaration
  113 | int     seltrue __P((dev_t dev, int which, struct proc *p));
      |                                                   ^~~~
/u1/BSD/4.4BSD-Lite/usr/src/sys/sys/cdefs.h:58:25: note: in definition of macro ‘__P’
   58 | #define __P(protos)     protos          /* full-blown ANSI C */
      |                         ^~~~~~
Indeed tcp_input.c includes sys/systm.h and this has the following line:
int     seltrue __P((dev_t dev, int which, struct proc *p));
The __P macro comes from sys/cdefs.h -- It notices that __STDC__ is defined and defines this macro as:
#define __P(protos)     protos
There is nothing at all wrong with the __P macro. The problem is that the prototype is being established before the structure is defined. This is OK to a point, but the warning is entirely valid. The compiler will set up an empty struct, then dissove it immediately after the prototype -- or something like that. The right way to do this is to define the structure being used before trying to use it in a prototype.

So the questions to ask are where "struct proc" gets defined (in sys/proc.h naturally). The next question is whether it is used at all in the tcp code I am working on Answering the first question would let us just include proc.h before systm.h and that would make the compiler happy. The answer to the second questions is "no". Or maybe it is. The file tty_subr.c includes proc.h but never seems to use the proc structure.

For now I just comment out the include of systm.h and I am on to the next issue.

tcp_input.c:66:34: error: ‘tcb’ undeclared here (not in a function); did you mean ‘tcpcb’?
   66 | struct  inpcb *tcp_last_inpcb = &tcb;
Here the code expects to find "tcb" as a global variable. Good old ctags tracks this down for me. This is declared in "netinet/tcp_var.h". Apparently this old style of C just let you reference global variables like this, but these days, you need to supply extern statements. The file tcp_input.c does include tcp_var.h -- so it is just a matter of adding two sections to this file, one to define, the other to declare these globals.

Voila! All of the above (except the extern business) went away when I simply defined -DKERNEL and allowed tcp_var.h do what it was supposed to do.


Have any comments? Questions? Drop me a line!

Kyu / [email protected]