Atom Nieuws 2002 nummer 1
../../../images/back.gif ../../../images/exit.gif ../../../images/forward.gif
pagina 4
TCP/IP en Poorten
door Roland Leurs

Hoe werkt TCP/IP en wat zijn nou die poorten waar iedereen het steeds over heeft? Zijn dat connectoren waar je een steker in stopt en dan communiceren maar of hoe zit dat? Dit zijn een aantal vragen die de grondslag waren voor een presentatie op een van onze regioavonden in Sittard. Op veler verzoek volgt hier nogmaals het verhaal.

De behandelde onderwerpen zijn:
  1. Wat is TCP/IP ?
  2. Wat is een poort ?
  3. Zelf doen !
1. Wat is TCP/IP ?

TCP/IP is een protocol suite die ontwikkelt is door het Amerikaanse Ministerie van Defensie. Deze suite biedt een aantal protocollen, zeg maar afspraken, om computersystemen met elkaar te laten communiceren. Deze systemen kunnen dicht bij elkaar staan en via één kabel met elkaar verbonden zijn, maar ook is het mogelijk dat deze systemen duizenden kilometers uit elkaar staan en dat daar diverse systemen tussen zitten die er wel voor zorgen dat twee systemen met elkaar kunnen communiceren.

TCP/IP is opgebouwd volgens onderstaande lagenstructuur:

Aplicatie
FTP, Telnet, e-mail
Transport
TCP, UDP
Internet
IP, ICMP, RIP, ARP
Host to network
LAN, Packet Radio

Tabel 1:   TCP/IP   model

Kenners herkennen hier meteen het OSI model in, maar dit model wijkt principieel af, de onderste twee lagen van het OSI model zijn samengevoegd in de Host-to-network laag en TCP/IP kent geen session en presentation layers.

Kort omschreven hebben de lagen de volgende functies:
Applicatie:
Dit zijn de programma's waar je mee werkt. Denk hierbij aan downloaden via ftp, surfen over het Internet en e-mailen.
Transport:
Deze laag zorgt voor het overbrengen van datapakketjes. Dit kan op een betrouwbare manier waarbij eerst een verbinding wordt opgebouwd (connection oriented) of op een minder betrouwbare manier (connectionless).
Connection oriented verbindingen (TCP) zijn te vergelijken met een telefoongesprek. Eerst maak je verbinding en dan begin je te praten. Zo nu en dan wat terugkoppeling (ja .... ja .... nee) zorgt ervoor dat spreker en toehoorder met elkaar in contact blijven.
Connectionless verbindingen (UDP) hebben veel weg van een postbezorging. De brief verdwijnt in de brievenbus en je hoopt dat deze aankomt op de plaats van bestemming. Meestal lukt dat, soms niet.
Zijn connection oriented (TCP) verbindingen dan veel betrouwbaarder dan connectionless (UDP) verbindingen? Niet per definitie, de bovenliggende applicatie kan altijd ontvangstbevestigingen vragen en afgeven. UDP is vanwege kleinere pakketgrootte op de lijn en minder overhead meestal wel sneller.
Internet:
Niet te verwarren met het wereldwijde netwerk. Deze laag zorgt ervoor dat communicatie tussen systemen en netwerken mogelijk is. De diverse protocollen zorgen voor het afleveren van data op de juiste plek (IP) en signalering als er iets niet goed gaat (ICMP).
Host to Network:
Deze laag bevat de drivers voor netwerkkaarten (en ook modems) en de fysieke media. Dit kan een koperdraad zijn, maar ook draadloze communicatie is sterk in opkomst: Wifi (draadloos ethernet) en Packet Radio zijn daar bekende voorbeelden van.

2.1 Communicatie tussen systemen op één netwerk
tcp1.gif

A wil bericht sturen naar B, ziet aan adres dat dit lokaal is
A vraagt: "wie is B?"
B antwoordt: "Dat ben ik. Mijn MAC adres is ......."
A stuurt pakket naar B

We zien hier twee systemen die met elkaar willen communiceren. Als basis van de communicatie worden de hardware adressen van de netwerkkaarten gebruikt. Deze adressen zijn 48 bits lang (6 bytes) waarbij de hoogste drie bytes gereserveerd zijn om de fabrikant aan te duiden, en de laagste drie bytes zijn een unieke code die door de fabrikant toegewezen wordt. Indien een fabrikant door zijn codes heen is, kan hij een nieuwe “fabrikant-code” aanvragen.

De software in de tweede laag is in staat om aan de hand van het IP adres te bepalen of een systeem op hetzelfde netwerk aangesloten is of op een extern netwerk zit. Door het ARP (address resolution protocol) wordt de vraag “wie heeft adres x.x.x.x op het netwerk gesteld. Indien een systeem dit adres heeft zal dit antwoorden met: “Dat ben ik, stuur maar naar MAC adres "yy.yy.yy.yy.yy.yy ”. Daarna kan de communicatie beginnen en worden de pakketten verzonden.

tcpip1.gif
In bovenstaande afbeelding is het op vaststellen van het benodigde MAC adres goed zichtbaar.

2.2 Communicatie tussen twee systemen op verschillende netwerken.

In de afbeelding op de volgende pagina worden de twee systemen gescheiden door een router. Dit apparaat is in staat om datapakketjes over te zetten van het ene netwerk naar het andere, waarbij volgens een bepaald protocol een route gekozen wordt. De werking van een router valt buiten het bereik van dit artikel en wordt verder niet behandeld. Voor nu is het voldoende om te begrijpen dat de router zorgt voor het overzetten van datapakketjes naar een ander netwerk.

tcp2.gif
A wil bericht sturen naar B, ziet aan adres dat dit niet lokaal is
A vraagt: "wie is B?"
R antwoordt: "Dat ben ik. Mijn MAC adres is ......."
A stuurt pakket naar R, R stuurt pakket door naar B.
of: A stuurt pakket direct naar R omdat B op ander netwerk zit

Deze communicatie is vergelijkbaar met de communicatie op hetzelfde netwerk. Het verschil zit er in dat systeem A vraagt wie B is, en dat de router R antwoordt dat hij B is. A stuurt dan het pakketje naar R, die het weer doorstuurt naar B. Een andere mogelijkheid is dat A het pakketje rechtstreeks naar R stuurt omdat A weet dat B op een ander netwerk zit, en A weet dat R de pakketjes kan bezorgen. De gekozen werking ligt aan de implementatie van het ARP protocol in de systemen.

3. Adressering

In het algemeen heeft elke manier van communiceren een eigen adressering. Drie bekende protocollen zijn:
  1. NetBeui van Microsoft en IBM; hierbij wordt gebruik gemaakt van NetBIOS namen. NetBeui is het protocol, NetBIOS is de api (application program interface, een manier om systeemfuncties aan te roepen). NetBIOS namen zijn maximaal 15 karakters lang en kennen geen netwerk informatie. Derhalve is NetBeui niet routeerbaar, dat houdt in dat systemen op verschillende netwerken niet met elkaar kunnen communiceren, zonder daarvoor speciale truukjes voor uit te halen.
  2. IPX/SPX van Novell; hierbij worden adressen gebruikt die wel een netwerkdeel en een systeemdeel bevatten. Dit maakt IPX/SPX wel routeerbaar. IPX is net als TCP de connection oriented verbinding, SPX is de connectionless verbinding.
  3. TCP/IP, de algemeen geaccepteerde standaard in communicatie. Een TCP/IP adres kent net als IPX/SPX een netwerkdeel en een systeemdeel. Het IP-adres (zoals dit in de volksmond genoemd wordt) zijn vier getallen, gescheiden door een punt. Het netwerkdeel, ookwel netwerkadres genoemd, wordt vastgelegd door het subnetmasker. Ook dit zijn vier getallen, wederom gescheiden door een punt. De bits in het subnetmasker die gezet (1) zijn, geven aan dat het overeenkomstige bit in het IP-adres tot het netwerkadres gerekend moet worden.

    Bijvoorbeeld:
    IP-adres = 10.61.21.5 Subnetmasker=255.255.255.0
    Het netwerkadres is dan:
    00001010 00111101 00010101 00000101
    11111111 11111111 11111111 00000000
    00001010 00111101 00010101 00000000 = 10.61.21.0

    In dit voorbeeld zijn de getallen in het subnetmasker makkelijk gekozen, maar er is niets op tegen om meer of minder bits voor het netwerkadres te reserveren. Zolang de bits maar binnen de klasse en aaneengesloten blijven is er niets aan de hand. Deze klassen zijn als volgt vastgelegd:

    Klasse:Eerste getal:Voorbeeld:Subnetmasker:
    Klasse A: 0 - 12610.61.21.5255.0.0.0
    Klasse B:128 - 191172.16.43.6255.255.0.0.0
    Klasse C:192 - 223192.168.1.40255.255.255.0
    Klasse D:224 - 239broadcast
    Klasse E:240 - 254 experimental

Over IP-adresseringen zijn al complete boeken geschreven; voor dit artikel is bovenstaande sumiere informatie voldoende. Laten we verder gaan met poorten.....

4. Poorten

Een poort is een 16 bits getal waaraan specifiek proces (service) gekoppeld is en dat het begin en eindpunt van een connectie aangeeft. Met andere woorden, de poort geeft aan welke dienst van een systeem gevraagd wordt en welk programma deze dienst gevraagd heeft.

diensten aangeboden worden. Zo wordt een webserver niet alleen gebruikt om webpagina's aan te bieden via het http protocol, maar vaak ook om bestanden te downloaden met het ftp protocol. Om nu onderscheid te maken welke dienst gevraagd wordt, wordt een poortnummer meegegeven. Andersom, het systeem dat de dienst vraagt kan ook zelf diensten aanbieden en moet derhalve meegegeven naar welke poort de server het antwoord kan sturen.

In onderstaande afbeelding is in regel 3 te zien dat een dienst gevraagd wordt op poort 6502 (destination port). Het antwoord kan gestuurd worden naar poort 32897 (source port).

tcpip2.gif

Een groot aantal poorten zijn officieel vastgelegd. Meestal zijn dit poortnummers < 1024. Dit zijn de zogenaamde well-known ports:
Well known ports zijn vastgelegde definities van poortnummers en de daaraan gekoppelde services. Vastgelegd in RFC1700.

Enkele voorbeelden:
20/21FTP80HTTP
22SSH110POP3
23Telnet443HTTPS
25 SMTP6502NetAtom

Een complete lijst van vastgelegde well-known ports is te vinden op het internet en wel op

"http://www.ietf.org/rfc/rfc1700.txt" .
Op deze site zijn overigens alle rfc's te vinden. In deze rfc's liggen alle afspraken vast die gelden voor het Internet verkeer. Het lezen en begrijpen van deze rfc's is overigens een vak apart.

5. De Atom en TCP/IP

Wat kunnen we met de Atom en TCP/IP beginnen? Op het moment nog niet veel. De echte Atom heeft nog geen software om via TCP/IP te communiceren. Ook voor de Atom-in-PC en de Atom emulatoren zijn er nog geen TCP/IP communicatiemiddelen. Maar er is hoop: Kees van Oss wil wel proberen om via een seriele poort, en wellicht via een netwerkkaart ooit TCP/IP te implementeren op een echte Atom. Op het Internet zijn overigens al verschillende projecten in een ver gevorderd stadium om TCP/IP stacks voor 6502 microprocessoren aan de praat te krijgen. Vooral op Commodore en Atari platformen schijnt er al veel te zijn.

Toch kunnen we met de Atom-in-PC wel wat spelen met TCP/IP. Op de clubavond heb ik een NetAtom server gedemonstreerd. In een PC met Atomkaart draait een klein programma dat op verbinding wacht van een andere PC, de client. Op deze client PC draait een speciale versie van het Atom-in-PC terminal programma. Deze versie communiceert namelijk niet via de ISA bus met de Atom, maar via het netwerk. In onderstaande listing is het server programma weergegeven:

/* atomserver.c */

#include <asm/io.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#define BASEPORT 0x31C

main()
{
int cont,create_socket,new_socket,addrlen;


unsigned int b;
int bufsize = 32;
unsigned char *buffer = malloc(bufsize);
struct sockaddr_in address;

printf("Atom server starting\n");
/* Get access to the ports */
if (ioperm(BASEPORT, 4, 1)) {perror("ioperm"); exit(1);}
if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
printf("The socket was created\n");
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(6502);
if (bind(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)
printf("Binding Socket\n");
listen(create_socket,3);
printf("Waiting for client\n");
addrlen = sizeof(struct sockaddr_in);
new_socket = accept(create_socket,(struct sockaddr *)&address,&addrlen);
if (new_socket > 0){
printf("The Client %s is connected...\n",inet_ntoa(address.sin_addr));
}
strcpy(buffer, "Welcome to NetAtom server\n");
send(new_socket,buffer,bufsize,0);
do{
recv(new_socket,buffer,bufsize,0);
if (buffer[0] < 0x80)
{ // read from port
buffer[0]=inb(BASEPORT+buffer[0]);
}
else
{ // write to port
outb(buffer[1], BASEPORT+(0x7F&buffer[0]) );
}
send(new_socket,buffer,1,0);
}while(strcmp(buffer,"/q")); //user ‘q’ to quit
close(new_socket);
close(create_socket);
/* We don't need the ports anymore */
if (ioperm(BASEPORT, 4, 0)) {perror("ioperm"); exit(1);}
printf("Atom server shut down\n");
}

Het client gedeelte ziet er als volgt uit:

/* atomio.h, included from atom.c */

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>

int create_socket;
int bufsize = 32;
// char *buffer=malloc(bufsize);
struct sockaddr_in address;

unsigned int readport(int port)
{
char buffer[bufsize];
buffer[0]=port; buffer[1]=0x00;
send(create_socket, buffer, 2, 0);
recv(create_socket, buffer, bufsize, 0);
return(buffer[0]);
}

void writeport(unsigned char data, int port)
{
char buffer[bufsize];
buffer[0]=port+0x80; buffer[1]=data;
send(create_socket, buffer, 2, 0);
recv(create_socket, buffer, bufsize, 0);
}

void openatom(char *serveraddr)
{
char buffer[bufsize];
/* Set up TCP connection to server */
printf("Atom client starting\n");
if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
printf("The Socket was created\n");
address.sin_family = AF_INET;
address.sin_port = htons(6502);
inet_pton(AF_INET, serveraddr, &address.sin_addr);
if (connect(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)
printf("The connection was accepted with the server %s...\n",inet_ntoa(address.sin_addr));
recv(create_socket, buffer, bufsize, 0);
printf("%s", buffer);
/* initialize the atom */
writeport(0xB4, 3);
writeport(0x0F, 3);
usleep(100000);
writeport(0x0E, 3);
usleep(100000);
writeport(0x0F, 3);
}

int readbyte(void)
{
while(!(readport(2) & 0x20)) ;
return readport(0);
}

int sendbyte(int byte)
{
while(!(readport(2) & 0x02)) ;
writeport(byte, 1);
return(byte);
}

void closeatom(void)
{
char buffer[bufsize];
buffer[0]='/'; buffer[1]='q';
send(create_socket, buffer, 2, 0);
recv(create_socket, buffer, bufsize, 0);
close(create_socket);
printf("Atom client shut down\n");
}

void resetatom(int msg)
{
if (msg)
{
printf("\n\n\n");
printf("###################################\n");
printf("# PRESS ANY KEY TO RESET THE ATOM #\n");
printf("###################################\n");
getchar();
}
writeport(0x0E, 3);
usleep(100000);
writeport(0x0F, 3);
}
Het schrijven van TCP/IP programma's is redelijk eenvoudig. Bovenstaande voorbeelden laten al zien dat er geen enorme lappen code nodig zijn. Deze voorbeelden zijn overigens gericht op een Linux platform.

Wanneer we echt met de Atom gaan browsen weten we nog niet, maar de basis van de communicatie moet wel enigermate verduidelijkt zijn.

../../../images/back.gif ../../../images/exit.gif ../../../images/forward.gif