Praktikum Internet-Technologie

von Prof. Jürgen Plate

Praktikum Internet-Technologie (Server-Client)

Vorbereitung

Das Praktikum findet im Labor E 204 statt. Informieren Sie sich über den Namen Ihres Rechners (Planeten bzw. Kleinplaneten). Ausserdem spielt der Server blackhole bei einigen Aufgaben eine Rolle.

Die Domain für alle Rechner ist da.private.hm.edu. Dabei steht "da" für den Standort Dachauerstr./Lothstr. und "private" bedeutet, daß der Rechner im privaten (von aussen nicht erreichbaren) Netz steht.

Für einige Aufgaben ist die Root-Berechtigung notwendig. Der Wechsel in die Rolle des Superusers erfolgt mit dem Kommando sudo. Um eine Root-Shell zu erlangen, geben Sie demnach sudo su ein. Der Login auf anderen Rechnern erfolgt mittels der Secure Shell (ssh <user>@<rechner>) und zum Kopieren wird Secure Copy (scp) verwendet.

Falls unterschiedliche Portnummern nötig sein sollten, gilt im E 204 die folgende Zuordnung:

PortRechnerPortRechner PortRechnerPortRechner
1201Merkur1202Venus 1203Erde1204Mars
1205Jupiter1206Saturn 1207Uranus1208Neptun
1209Pluto1210Ceres 1211Eris1212Juno
1213Pallas1214Vesta 1215Xena  

 

Für Ihre Programme genügt in der Regel folgender "Vorspann" mit Header-Dateien:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>

Glückskeks-Server

Der zu programmierende Server kann mittes telnet <Portnummer> angesprochen werden, es ist also nur der Server und kein Client zu programmieren. Der Server gibt nach Verbindungsaufnahme einen zufällige Spruch aus und beendet dann die Verbindung. Die Sprüche befinden sich in Textadateien, die im Verzeichnis beispiele/fortune zu finden sind (Dateiliste siehe unten). Kopieren Sie sich eine oder mehrere dieser Dateien in das Heimatverzeichnis. Das Lesen der jeweiligen Datei und die Ausgabe des Spruchs erledigt die vorgegebene Funktion mfortune(), der drei Parameter übergeben werden: Die Funktion befindet sich in der Datei mfortune.c, die auch die Anwendung erläutert.

Server-Client-Kommunikation

In dieser Aufgabe ist ein passender Client zu programmieren. Der Client soll einen Server auf einem Raspberry-Pi-System ansprechen, der dort entsprechende Aktionen ausführt.

Namen und IP-Adressen
der Raspberry-Systeme:

RechnerIP-Adresse
chiron10.27.210.230
pholus10.27.210.231
nessus10.27.210.232

Als Kommandos des Clients sind möglich:

KommandoGewünschte Daten
SET <LED-Nr> [0|1] Setzen des GPIO-Pins der entprechenden LED auf 0 oder 1
LED-Nr: 1..4, Rückgabe: 'ACK' oder 'NAK'
GET Rückgabe: 'ACK ' und Inhalt der Datei /tmp/motion
(eine Zeile) oder 'NAK'

Die Kommandos des Clients werden als ein String gesendet, z. B. "SET 2 0". Kommandos und Antworten des Servers werden immer mit Newline abgeschlossen.

Schreiben Sie nun einen Client, der eine Verbindung zum Server aufbaut und dann abhüngig von der Kommandozeilenoption eines der Kommandos 'SET' oder 'GET' sendet und die Antwort ausgibt. Als Kommandozeilenoptionen werden zwei Strings übergeben, zuerst der Servetrname und dann der GET- oder SET-Befehl. Denken Sie daran, dass Kommandozeilenparameter, die Leerzeichen enthalten, mit Apostrophen umgeben werden müssen (z. B. ./client pholus 'SET 2 1').

Damit nicht jeder die Systeme ansprechen kann, wird die an den Server gesendete Info verschlüsselt (die Antwort des Servers erfolgt im Klartext). Die Verschlüsselung der Nachricht erfolgt für das Praktikum mit einer einfachen Vigenère-Chiffre (siehe dazu Wikipedia und C-Programm zur Vigènere-Verschlüsselung). Dieses Verfahren wird in der Praktikumsaufgabe als Beispiel für Verschlüsselung verwendet, ist aber keinesfalls sicher genug für ein produktives System im Internet. Die Funktionen zum Codieren und Decodieren finden Sie neben einem Demo-Hauptprogramm unter beispiele/vigenere.c. Es werden alle Zeichen zwischen '0x32' und '0x127' verschlüsselt. Andere Zeichen werden einfach unverändert durchgereicht. Übernehmen Sie die Funktionen zusammen mit den Include-Anweisungen und Konstantendefinitionen in Ihr Clientprogramm. Zusammen mit den notwendigen Include-Dateien für den Client ergibt sich folgender Programmvorspann:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define PORT 7777         /* Port fuer die Requests */
#define BUFSIZE 4096      /* Puffergroesse */

#define SMAX 100          /* maximale Schluessellaenge */
#define ALPHA 96          /* Alphabetlaenge */

int keylen;               /* Laenge des Schluesselwortes */
char key[SMAX];           /* Schluesselwort in Form von Offsets */

char secret[] = "xxx";    /* Codeschluessel, wird im Praktikum bekannt gegeben */
char buffer[BUFSIZE];     /* Textpuffer, Groesse passend waehlen */
Als Basis für Ihr Clientprogramm verwenden Sie beispiele/tcp-client.c.

Hintergrundinfo

Bei den drei RasPi-Systemen, auf denen der Server läuft, sind an vier, als Ausgang geschalteten GPIO-Ports LEDs mit unterschiedlichen Farben angeschlossen, die einzeln per SET-Befehl ein- und ausgeschaltet werden können:

LED 1LED 2LED 3LED 4
GPIO22GPIO23GPIO24GPIO25
ROT GELB GRUEN BLAU

Der Befehl ./client nessus 'SET 3 1' würde beispielsweise die grüne LED einschalten.

An einem weiteren Eingangsport, GPIO 17, ist ein Bewegungsmelder angeschlossen, der per GET-Befehl abgefragt werden soll. Auch hierzu gibt es ein Hilfsprogramm auf dem Server, PIR.py, das den Bewegungsmelder überwacht und beim Erkennen der Bewegung eine Nachricht mit Zeitstempel in die Datei /tmp/motion schreibt ("Bewegung erkannt: " + Zeitstempel). Das Programm wird einmal im Hintergrund gestartet (sudo ./PIR.py &) und läuft ständig. So kann der Netzwerk-Client auch über registrierte Bewegungen in der Vergangenheit informiert werden. Der aktuelle Wert kann mittels ./client nessus 'GET' abgerufen werden.

Angesteuert werden die o. g. LEDs per Python-Programm, so dass im Server kein Zugriff auf die GPIO-Pins erfolgen muss. Dieses Programm läuft nur mit Root-Berechtigung. Im C-Programm des Servers wird das entsprechende Kommando per system()-Funktion gestartet. Für GET genügt lesender Zugriff auf die Datei /tmp/motion.

Zur Information finden Sie beide Programme unter folgendem Link:
Dateiuebersicht