Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

Benutzer:Grey/UDP-Testskript EN

UDP-testscript

breadboard constructions

There are different variations of breadboard constructions for FWTEST and the FWAGENT, see here: breadboard constructions

netdate-example

On the basis of an example we want to illustrate an implementation of a testscript. For example, we want to make a draft on the netdate-service of www.heise.de (we don't really to make a draft on www.heise.de, but we only simulate the traffic) for getting the actual time. Netdate exists for UDP and TCP, we take here the UDP-variation.

if we would eavesdrop the traffic with etereal or tcpdump, the packets should look like that they are real and not generated(more to this topic here: Limits of tests).

Basically we are processing following credits:

  1. creating default IP-packet(achen -> bchen)
  2. creating default IP-packet(bchen -> achen)
  3. creating default UDP-packet(achen -> bchen)
  4. creating default UDP-packet(bchen -> achen)
  5. adjusting IP-packet
  6. adjusting UDP-packet
  7. merging IP- and UDP-packets
  8. sending UDP/IP-packets via transceive-function
  9. evaluation



Now we take a closer look at the testscript, at the end will be the link to the complete source code of the netdate-script:

  • At first we have to import our wrapper-classes (with prefix fwt_) and other needed classes:
import fwt_ip      # wrapper-Klasse zum erstellen/ändern von IP-Paketen
import fwt_udp     # wrapper-Klasse zum erstellen/ändern von UDP-Paketen
import fwt_tcp     # wrapper-Klasse zum erstellen/ändern von TCP-Paketen
import posix       # TODO: Erklärung


  • After that we define two variables for debugging. dry_run is for run called dry-run, which do the packet creation, but the finally sending is skipped. The second effects, that only bchen will send their packets, packets from achen are skipped.
dry_run=0	    # if set the transceive function is skipped
response_only=0    # send time protocol response only


  • TODO Wir müssen die Beiden Agenten Achen und Bchen mit einer IP-Adresse festlegen.
ACHEN='10.000.2.2'
BCHEN='10.128.2.2'


  • TODO
FILTER_A="not tcp port 1500 and src " + BCHEN + " and dst " + ACHEN + " or icmp"
FILTER_B="not tcp port 1500 and src " + ACHEN + " and dst " + BCHEN + " or icmp"


  • As basis we need our IP-packet as we generated here. We can use our wrapper-class fwt_ip to create the default IP-packet.
ip_packet = fwt_ip.Packet(fwt_ip.defaultPacket)


  • The default IP-packet has to be modified, e.g. the correct protocol is not set. To do so, we use the set-funcition of our wrapper-class fwt_ip. All fields of the IP-packet can be set by the set-function.
ip_packet.set ({
    fwt_ip.HEADER_PROTOCOL: 17,
})


  • The next step is to calculate the IHL(Internet Header Length) and the Header Checksum. An easy way to do it is to call the FIXUP-function of our wrapper-class. THe FIXUP corrects the fields(TODO: WELCHE?) of IP-packet. Our IP-packet will be loaded later with the SourceIP and the DestinationIP.
ip_packet.fixup (fwt_ip.FIXUP_ALL)


  • Currently we have an IP-packet as basis for both UDP-packets, but be also need the UDP-packets itself. We define with our wrapper-class two UDP-packets, the one for the way from achen to bchen and one for the reversed way. Each of these UDP-packets will be the payload for the IP-packets. They also have now only the base preferences, which have to be modified.
udp_pkt_ab = fwt_udp.Packet(fwt_udp.defaultPacket)
udp_pkt_ba = fwt_udp.Packet(fwt_udp.defaultPacket)


  • The base preferences are good beginning, but the UDP-packets get to be modified now, e.g.: sourceport, destinationport. At first we modify the UDP-packet from achen to bchen...
udp_pkt_ab.set({
    fwt_udp.HEADER_CHECKSUM:      0,
    fwt_udp.HEADER_SOURCEPORT:   53,
    fwt_udp.HEADER_DESTPORT:     37,
    fwt_udp.PAYLOAD:	         '\x0a'
})
  • ...and then from bchen to achen.
udp_pkt_ba.set({
    fwt_udp.HEADER_CHECKSUM:      0,
    fwt_udp.HEADER_SOURCEPORT:   37,
    fwt_udp.HEADER_DESTPORT:     53,
    fwt_udp.PAYLOAD: '\x69\xdc\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x05\x68\x65\x69\x73\x65\x02\x64\x65\x00\x00\x01\x00\x01',
})

Pay attention that you take the right Destination Port of the service you will use. The payload of the UDP-packet have to be hardcode-implemented in hex.


  • Likewise a FIXUP of both UDP-packets have to be done, like the IP-packets. So the length and the Header Checksum will be corrected or changed:
udp_pkt_ab.fixup(fwt_udp.FIXUP_ALL, ACHEN, BCHEN);
udp_pkt_ba.fixup(fwt_udp.FIXUP_ALL, BCHEN, ACHEN);


Nachdem wir nun unser IP-Grundpaket und unseren UDP-Pakete von Achen nach Bchen und zurück erstellt haben, wollen wir die Pakete vereinen. Das IP-Paket von oben dient uns als Vorlage für unser UDP/IP-Paket von Achen nach Bchen. Wir übergeben unserem Konstruktor das IP-Paket als Dictionary.

ip_udp_pkt_ab = fwt_ip.Packet(ip_packet.as_dict())


Das UDP/IP-Paket braucht natürlich das Ziel, daß es ansteuern soll und der Empfänger muß auch wissen wohin er die Antwort schicken müßte. Als Payload, wie schon weiter oben erwähnt, übergeben wir das UDP-Paket in Form eines String.

ip_udp_pkt_ab.set({
    fwt_ip.HEADER_SOURCEIP:	ACHEN,
    fwt_ip.HEADER_DESTIP:	BCHEN,
    fwt_ip.PAYLOAD: udp_pkt_ab.as_str()
})


Da jetzt im IP-Paket die SourceIP- und die DestinationIP-Adresse gesetzt wurde, muß auch die Header Checksum neu berechnet werden. Genau das machen wir mit unserem FIXUP.

ip_udp_pkt_ab.fixup(fwt_ip.FIXUP_ALL)


Das gleiche müsssen wir nun mit dem UDP-Paket von Bchen nach Achen machen.

ip_udp_pkt_ba = fwt_ip.Packet(ip_packet.as_dict())
ip_udp_pkt_ba.set({
    fwt_ip.HEADER_SOURCEIP:	BCHEN,
    fwt_ip.HEADER_DESTIP:	ACHEN,
    fwt_ip.PAYLOAD: udp_pkt_ba.as_str()
})
ip_udp_pkt_ba.fixup(fwt_ip.FIXUP_ALL)


Zum Ausgeben der empfangenen Pakete brauchen wir eine print-Funktion (printResult). Sie prüft, ob an Achen oder Bchen ein Paket ankam und gibt es aus, andernfalls wenn gar kein Paket ankam, wird der Fehler Timeout ausgegeben.

def printResult (result):
    if result[0] is not None:
         print 'Received on A:\n%r\n' % result[0]
    if result[1] is not None:
         print 'Received on B:\n%r\n' % result[1]
    if result[0] is None and result[1] is None:
         print 'Timeout'


Wir schauen, ob die Option dry_run gleich 1 ist. Sollte sie 1 sein, werden lediglich die Pakete auf der Konsole ausgegeben.

if dry_run == 1:
    print 'dry_run: skip all transceive functions'
    print 'Would send IP packet a->b:\n%s\n' % repr(ip_udp_pkt_ab.as_dict())
    print 'Would send IP packet b->a:\n%s\n' % repr(ip_udp_pkt_ba.as_dict())


Ab diesem Punkt wird es ernst und die Pakete werden wirklich gesendet.

TODO

else:
    fwt_ip.set_coarse_filter_and_arp (fwt_ip.IFACE_A, [ ("10.000.0.2", "10.127.255.255")])
    fwt_ip.set_coarse_filter_and_arp (fwt_ip.IFACE_B, [ ("10.128.0.2", "10.255.255.255")])

Auch hier kommt eine der Zwei Variablen von oben ins Spiel, so daß bei response_only gleich 1 nur das UDP/IP-Paket von Bchen nach Achen gesendet wird. Mittels transceive-Funktion wird dann unser UDP/IP-Paket von Bchen nach Achen versendet. Das angekommene Paket wird in result an die erste Stelle gespeichert und ausgegeben. TODO:an welche stelle wird paket in result gespeichert?

    if response_only == 1:
         print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
         result = fwt_ip.transceive (fwt_ip.IFACE_B, ip_udp_pkt_ba, filterA=FILTER_A, filterB=FILTER_B, timeoutA=500, timeoutB=0)
         printResult (result)

Andernfalls wird erst das UDP/IP-Paket von Achen nach Bchen und dann zurück gesendet. Die Ergebnissse werden ebenfalls in result gespeichert.

    else:
         print 'Will send IP packet a->b:\n%r\n' % ip_udp_pkt_ab
         result = fwt_ip.transceive (fwt_ip.IFACE_A, ip_udp_pkt_ab,  filterA=FILTER_A, filterB=FILTER_B, timeoutA=0, timeoutB=500)
         printResult (result)
         if result[1] is not None:
              print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
              result = fwt_ip.transceive (fwt_ip.IFACE_B, ip_udp_pkt_ba, filterA=FILTER_A, filterB=FILTER_B, timeoutA=500, timeoutB=0)
              printResult (result)
         else:
              print 'Lost origin packet -- Skip sending answer'


kompletter Code von netdate.

transceive-Funktion