Benutzer:Grey/UDP-Testskript EN
Inhaltsverzeichnis
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:
- creating default IP-packet(achen -> bchen)
- creating default IP-packet(bchen -> achen)
- creating default UDP-packet(achen -> bchen)
- creating default UDP-packet(bchen -> achen)
- adjusting IP-packet
- adjusting UDP-packet
- merging IP- and UDP-packets
- sending UDP/IP-packets via transceive-function
- 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);
- After we created our default IP-packet and our modified default UDP-packets, we want to merge these packets to an UDP/IP-packet froma achen to bchen and reverse. The IP-packet listed befor act as a template for the UDP/IP-packet from achen to bchen. The constructor get the IP-packet as a dictionary and retruns a UDP/IP-packet.
ip_udp_pkt_ab = fwt_ip.Packet(ip_packet.as_dict())
- The UDP/IP-packet needs a destination- and source-IP. As the payload, mentioned above, we refer the UDP-packet(as string).
ip_udp_pkt_ab.set({ fwt_ip.HEADER_SOURCEIP: ACHEN, fwt_ip.HEADER_DESTIP: BCHEN, fwt_ip.PAYLOAD: udp_pkt_ab.as_str() })
- Yet we have set the IP-packet with the destination- and source-IP, but the Header Checksum must be generate as once again. This will do the FIXUP.
ip_udp_pkt_ab.fixup(fwt_ip.FIXUP_ALL)
- The same must be done for the UDP-packet from bchen to achen.
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'