Rev 1737 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1737 | clevermous | 1 | What is implemented |
2 | =================== |
||
3 | |||
4 | The following features are present in the TCP/IP stack code: |
||
5 | |||
6 | IP layer. |
||
7 | ICMP. |
||
8 | TCP layer. |
||
9 | UDP layer. |
||
10 | local loopback. |
||
11 | Realtek 8029 PCI ethernet interface. |
||
12 | Realtek 8139 PCI ethernet interface. |
||
13 | Intel i8255x PCI ethernet interface. |
||
14 | Dynamic ARP table. |
||
15 | PPP dialer |
||
16 | |||
17 | And the following internet applcations are implemented |
||
18 | |||
19 | HTTP Server |
||
20 | Telnet |
||
21 | POP Client |
||
22 | DNS Name resolver |
||
23 | MP3 Server |
||
24 | TFTP Client |
||
25 | IRC Client |
||
26 | |||
27 | There are also a number of experimental applications for streaming music |
||
28 | and performing interprocess communication via sockets. A Web broswer is in |
||
29 | development |
||
30 | |||
31 | |||
32 | What is not implemented |
||
33 | ======================= |
||
34 | |||
35 | The IP layer does not process header options. |
||
36 | The IP layer does not support routing. |
||
37 | Packet fragmentation is not supported. |
||
38 | |||
39 | |||
40 | How to configure Kolibri for PPP |
||
41 | =============================== |
||
42 | |||
43 | See ppp.txt |
||
44 | |||
45 | |||
46 | How to configure Kolibri for Ethernet |
||
47 | ==================================== |
||
48 | |||
49 | First, you need to have a supported ethernet card fitted, or present |
||
50 | on your motherboard. If you are uncertain what type of hardware you |
||
51 | have, try to configue the stack. If you have supported hardware it |
||
52 | will be found, and enabled. |
||
53 | |||
54 | Setting Up the ARP Table |
||
55 | ------------------------ |
||
56 | |||
57 | Kolibri's ARP table is dynamically created and maintained; You can see what |
||
58 | hosts Kolibri has communicated with by running the ARPSTAT application. |
||
59 | |||
60 | Enabling Ethernet |
||
61 | ----------------- |
||
62 | |||
63 | Boot Kolibri, then select STACKCFG from the NET menu. |
||
64 | Press the 'Read' Button, then select 'Packet Driver'. |
||
65 | Press 'Change' next to the IP address, and enter the IP address you want |
||
66 | to use. Make sure it is on the same sub-net as the LAN to which you are |
||
67 | connected. |
||
68 | Press 'Apply' to action the changes. |
||
69 | Close the program. |
||
70 | |||
71 | |||
72 | The stack is now running, which you can test by pinging Kolibri from a |
||
73 | remote host. |
||
74 | |||
75 | |||
76 | The simplest way to connect two PC's together is using a 'Null Modem' |
||
77 | Ethernet cable. These simply cross certain wires over. They can be |
||
78 | purchased from PC stores, but are simple to make. Details can be found |
||
79 | on the web. Look on google for 'ethernet cross over cable' or similar. |
||
80 | |||
81 | |||
82 | How to use TCP/IP locally, with no Network |
||
83 | ========================================== |
||
84 | |||
85 | Kolibri supports a form of local loopback that means applications on the |
||
86 | same PC can communicate with each other via sockets as though they |
||
87 | were on separate hosts. To connect to an application on the same machine, |
||
88 | specify the local IP address as the destination address. You do not even |
||
89 | need to configure the stack for ethernet; local loopback will work without |
||
90 | any network hardware. It's great for development and testing. |
||
91 | |||
92 | |||
93 | Application Programming Interface |
||
94 | ================================= |
||
95 | |||
96 | The developer can access the stack through interrupt 0x40, function 53. |
||
97 | The file TFTPC.ASM gives a good example of how to use the programming |
||
98 | interface ( at least, for UDP), but as network communication is complex |
||
99 | I'll give an overview. |
||
100 | |||
101 | |||
102 | Sockets |
||
103 | ======= |
||
104 | |||
105 | Applications connect to each other and pass information between themselves |
||
106 | through a mechanism called a 'socket'. Sockets are end-points for |
||
107 | communication; You need one at each application to communicate. |
||
108 | |||
109 | Using sockets is a little like using files on an OS; You open them, read |
||
110 | and write to them, then close them. The only thing that makes life slightly |
||
111 | more complicated is that unlike with a file, you have something intelligent |
||
112 | at the other end ( which for example may not want to close when you do! ) |
||
113 | |||
114 | Lets deal with the terminology before we go any further. |
||
115 | |||
116 | socket A unique identifier used by the application for communication. |
||
117 | local port A number that identifies this application on the local host. |
||
118 | Ports are a way to allow multiple applications to communicate |
||
119 | with other hosts without the data becoming mixed up. ( The |
||
120 | technical term is 'multiplex' ). Port numbers are 16 bit. |
||
121 | remote port A number that identifies the application on the remote host |
||
122 | to which we are communicating with. To the remote host, this is |
||
123 | it's 'local port'. Port numbers are 16 bit. |
||
124 | IP Address A 32 bit number that identifies the remote host PC that we are |
||
125 | communicating with. |
||
126 | Passive Refers to the mode by which a socket is opened; When opening in |
||
127 | passive mode, the local PC is awaiting an incoming connection. |
||
128 | Active Refers to the mode by which a socket is opened; When opening in |
||
129 | active mode, the local PC will attempt to connect to a remote |
||
130 | PC. |
||
131 | |||
132 | When you connect to a socket on a remote PC, you need to specify more than |
||
133 | just the IP address, otherwise the remote stack will not know to which |
||
134 | application it should send your data. You must fully qualify the address, |
||
135 | which means you specify the IP address and the port number. This would be |
||
136 | written like this |
||
137 | |||
138 | 192.168.1.10:80 ; Connect to port 80 on the machine 192.168.1.10 |
||
139 | |||
140 | Port numbers are important. Some are 'well known' and provide access to |
||
141 | common applications. For example port 80 is used by HTTP servers; That |
||
142 | way I can connect to a webserver on a host without having to find out |
||
143 | what port number the application is listening on. |
||
144 | |||
145 | This brings me to the way in which you open a socket; As I said earlier, |
||
146 | there are two modes, Passive and Active. A webserver would open a passive |
||
147 | socket, as it is waiting for incoming connection requests. A web browser |
||
148 | would open an active socket because it is attempting to connect to a |
||
149 | specified remote host. |
||
150 | |||
151 | |||
152 | Access to programming interface |
||
153 | =============================== |
||
154 | The developer accesses the stack functions through interrupt 0x40, |
||
155 | function 53. Some functions may be accessed through function 52, but these |
||
156 | are mainly for stack configuration. |
||
157 | Here is a summary of the functions that you may use and the parameter |
||
158 | definitions. |
||
159 | |||
160 | |||
161 | Get Local IP Address |
||
162 | -------------------- |
||
163 | eax = 52 |
||
164 | ebx = 1 |
||
165 | |||
166 | IP address returned in eax ( in internet byte order ) |
||
167 | |||
168 | |||
169 | Write to stack input queue |
||
170 | -------------------------- |
||
171 | eax = 52 |
||
172 | ebx = 6 |
||
173 | edx = number of bytes to write |
||
174 | esi = pointer to data ( in application space ) |
||
175 | |||
176 | On return, eax holds 0 for OK, or 0xFFFFFFFF for error. |
||
177 | This interface is for slow network drivers only ( PPP, SLIP ) |
||
178 | |||
179 | |||
180 | Read data from network output queue |
||
181 | ----------------------------------- |
||
182 | eax = 52 |
||
183 | ebx = 8 |
||
184 | esi = pointer to data ( in application space ) |
||
185 | |||
186 | On return, eax holds number of bytes transferred. |
||
187 | This interface is for slow network drivers only ( PPP, SLIP ) |
||
188 | |||
189 | |||
190 | Open a UDP socket |
||
191 | ----------------- |
||
192 | eax = 53 |
||
193 | ebx = 0 |
||
194 | ecx = local port |
||
195 | edx = remote port |
||
196 | esi = remote ip address ( in internet byte order ) |
||
197 | |||
198 | The socket number allocated is returned in eax. |
||
199 | A return value of 0xFFFFFFFF means no socket could be opened. |
||
200 | |||
201 | |||
202 | Open a TCP socket |
||
203 | ----------------- |
||
204 | eax = 53 |
||
205 | ebx = 5 |
||
206 | ecx = local port |
||
207 | edx = remote port |
||
208 | esi = remote ip address ( in internet byte order ) |
||
209 | edi = mode : SOCKET_PASSIVE or SOCKET_ACTIVE ( defined in stack.inc ) |
||
210 | |||
211 | The socket number allocated is returned in eax. |
||
212 | A return value of 0xFFFFFFFF means no socket could be opened. |
||
213 | |||
214 | |||
215 | Close a socket (UDP Only ) |
||
216 | -------------------------- |
||
217 | eax = 53 |
||
218 | ebx = 1 |
||
219 | ecx = socket number |
||
220 | |||
221 | On return, eax holds 0 for OK, or 0xFFFFFFFF for error. |
||
222 | |||
223 | |||
224 | Close a socket (TCP Only ) |
||
225 | -------------------------- |
||
226 | eax = 53 |
||
227 | ebx = 8 |
||
228 | ecx = socket number |
||
229 | |||
230 | On return, eax holds 0 for OK, or 0xFFFFFFFF for error. |
||
231 | |||
232 | |||
233 | Poll socket |
||
234 | ----------- |
||
235 | eax = 53 |
||
236 | ebx = 2 |
||
237 | ecx = socket number |
||
238 | |||
239 | On return, eax holds the number of bytes in the receive buffer. |
||
240 | |||
241 | |||
242 | Read socket data |
||
243 | ---------------- |
||
244 | eax = 53 |
||
245 | ebx = 3 |
||
246 | ecx = socket number |
||
247 | |||
248 | On return, eax holds the number of bytes remaining, bl holds a data byte. |
||
249 | |||
250 | |||
251 | Write to socket ( UDP only ) |
||
252 | ---------------------------- |
||
253 | eax = 53 |
||
254 | ebx = 4 |
||
255 | ecx = socket number |
||
256 | edx = number of bytes to write |
||
257 | esi = pointer to data ( in application space ) |
||
258 | |||
259 | On return, eax holds 0 for OK, or 0xFFFFFFFF for error. |
||
260 | |||
261 | |||
262 | Return socket status ( TCP only ) |
||
263 | --------------------------------- |
||
264 | eax = 53 |
||
265 | ebx = 6 |
||
266 | ecx = socket number |
||
267 | |||
268 | On return, eax holds the sockets TCP status. |
||
269 | This function can be used to determine when a socket has actually connected |
||
270 | to another socket - data cannot be written to a socket until the connection |
||
271 | is established (TCB_ESTABLISHED). The states a socket can be in are defined |
||
272 | in stack.inc as TCB_ |
||
273 | |||
274 | |||
275 | Write to socket ( TCP only ) |
||
276 | ---------------------------- |
||
277 | eax = 53 |
||
278 | ebx = 7 |
||
279 | ecx = socket number |
||
280 | edx = number of bytes to write |
||
281 | esi = pointer to data ( in application space ) |
||
282 | |||
283 | On return, eax holds 0 for OK, or 0xFFFFFFFF for error. |
||
284 | |||
285 | |||
286 | Check port number |
||
287 | ----------------- |
||
288 | eax = 53 |
||
289 | ebx = 9 |
||
290 | ecx = port number |
||
291 | |||
292 | This function is used to determine if a port number |
||
293 | is in use by any sockets as a local port number. Local |
||
294 | port numbers are normally unique. |
||
295 | |||
296 | On return, eax is 1 for port number not in use, 0 otherwise. |
||
297 | |||
298 | |||
299 | Opening a TCP socket in Kolibri |
||
300 | =============================== |
||
301 | |||
302 | There are two ways to open a socket - Passive or Active. |
||
303 | |||
304 | In a Passive connection your application 'listens' for incoming |
||
305 | requests from remote applications. Typically this will be done when |
||
306 | you are implementing a server application that allows any other |
||
307 | application to connect to it. You would specify a 'known' local |
||
308 | port number, such as 80 for a web server. You would leave the |
||
309 | remote IP and remote port number as 0, which indicates any |
||
310 | remote application may connect. |
||
311 | |||
312 | Once the socket has been opened you would wait for an incoming |
||
313 | connection before doing anything. This can be by either checking |
||
314 | the socket status for TCB_ESTABLISHED, or waiting for data in the |
||
315 | receive buffer. |
||
316 | |||
317 | In an Active connection, you are making a connection to a specified |
||
318 | remote port. The remote IP and remote port parameters must be filled |
||
319 | in with non-zero values ( otherwise, what are you connecting to? ). |
||
320 | You also specify a unique local port number so the remote application |
||
321 | can uniquely identify you - after all, there may be several applications |
||
322 | on your machine connected to the same remote host. See below for finding |
||
323 | a unique port number. |
||
324 | |||
325 | |||
326 | How to find an unused local port number |
||
327 | ======================================= |
||
328 | |||
329 | Typically when you are creating an active connection to a remote |
||
330 | socket you will want to choose a unique local port number. Local |
||
331 | port numbers normally start from 1000; The following code may |
||
332 | be used to obtain an unused port number prior to making the |
||
333 | open socket call. |
||
334 | |||
335 | mov ecx, 1000 ; local port starting at 1000 |
||
336 | |||
337 | getlp: |
||
338 | inc ecx |
||
339 | push ecx |
||
340 | mov eax, 53 |
||
341 | mov ebx, 9 |
||
342 | int 0x40 |
||
343 | pop ecx |
||
344 | cmp eax, 0 ; is this local port in use? |
||
345 | jz getlp ; yes - so try next |
||
346 | |||
347 | ; ecx contains a free local port number |
||
348 | |||
349 | |||
350 | |||
351 | Writing data to a socket |
||
352 | ======================== |
||
353 | |||
354 | There are two functions available depending on whether the socket |
||
355 | was opened for TCP or UDP protocol; The call parameters are the |
||
356 | same however. When the socket is being opened for TCP, use the |
||
357 | status function to poll for a connection - data cannot be written |
||
358 | to a socket until another socket has connected to it, and the |
||
359 | state of the socket is TCB_ESTABLISHED. |
||
360 | |||
361 | When you write data, the call results in a single IP packet being |
||
362 | created and transmitted. Thus the user application is responsible for |
||
363 | the size of transmitted packets. Keep the packet sizes under 768 bytes. |
||
364 | If you are writing a terminal program like telnet, you may want to send |
||
365 | a packet for each keystroke ( inefficient ) or use a timer to send data |
||
366 | periodically ( say, every second ). |
||
367 | |||
368 | |||
369 | Reading data from a socket |
||
370 | ========================== |
||
371 | |||
372 | There is one function to read data from a sockets receive buffer. This |
||
373 | function retrieves one byte at a time. You can use the poll function to |
||
374 | test the receive buffer for data. |
||
375 | |||
376 | |||
377 | Closing a socket |
||
378 | ================ |
||
379 | |||
380 | Simply call the appropriate function - there is one for TCP, and another |
||
381 | for UDP. When closing a TCP socket, don't forget that the other end |
||
382 | may continue to send data, so the socket may remain active for a |
||
383 | few seconds after your call. |
||
384 | |||
385 | |||
386 | If you have any questions or have suggestions for improving this |
||
387 | document please contact me at mikeh@oceanfree.net. |