Protostar 0x0A - Net2
Prev: 0x09 - Net1
Next: 0x0B - Heap0
This level asks us to read in 4 unsigned 32-bit integers, add them up, and send the total back as another 32-bit integer. This is key, as the level reminds us that the total may wrap and thus exceed 32 bits, so we will need to keep this in mind prior to sending.
In the "run" function, the level works as described: four random unsigned integers are loaded into one of four spots in the integer array "quad," and subsequently added to a running total integer "result." They are also sent to us each time via "write." Finally, the input we provide via "read" is compared against this "result" variable, and feedback is provided accordingly.
Using "netstat -l" again as in the prior two levels, we confirm that port 2997 is already listening. Let's build our socket and confirm we connect:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2997))
response = s.recv(1024)
print response
Running this, we get:
$ python net2.py
}6
Great, we get our response, which according to the level's source code should be the first integer. Let's now write a loop which will do two things: (1) unpack the binary integer and (2) sum it to a running total variable called "total."
import socket, struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2997))
response = s.recv(1024)
print response
total = 0
for i in range(4):
integer = struct.unpack("<I", s.recv(1024))[0]
total += integer
print "received %d, total is now %d" % (integer, total)
Running this, we see:
$ python net2.py
received 2087025338, total is now 2087025338
received 2105404850, total is now 4192430188
received 1958671475, total is now 6151101663
received 1544550904, total is now 7695652567
Everything appears to check out! Now, we just need to send it back... but wait! Remember the warning before about the integer wrapping. Before we pack the integer and send it back, we'll need to do a bitwise AND with "0xFFFFFFFF" to ensure it remains 32-bit. Our final code is:
import socket, struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2997))
total = 0
for i in range(4):
integer = struct.unpack("<I", s.recv(1024))[0]
total += integer
print "received %d, total is now %d" % (integer, total)
final = struct.pack("<I", total & 0xFFFFFFFF)
print "sending " + final
s.send(final)
feedback = s.recv(1024)
print feedback
And if we run this, we see:
$ python net2.py
received 362712404, total is now 362712404
received 2109584628, total is now 2472297032
received 296924273, total is now 2769221305
received 546429760, total is now 3315651065
sending Ѡ
you added them correctly
Success!
Prev: 0x09 - Net1
Next: 0x0B - Heap0
Next: 0x0B - Heap0
This level asks us to read in 4 unsigned 32-bit integers, add them up, and send the total back as another 32-bit integer. This is key, as the level reminds us that the total may wrap and thus exceed 32 bits, so we will need to keep this in mind prior to sending.
In the "run" function, the level works as described: four random unsigned integers are loaded into one of four spots in the integer array "quad," and subsequently added to a running total integer "result." They are also sent to us each time via "write." Finally, the input we provide via "read" is compared against this "result" variable, and feedback is provided accordingly.
Using "netstat -l" again as in the prior two levels, we confirm that port 2997 is already listening. Let's build our socket and confirm we connect:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2997))
response = s.recv(1024)
print response
Running this, we get:
$ python net2.py
}6
Great, we get our response, which according to the level's source code should be the first integer. Let's now write a loop which will do two things: (1) unpack the binary integer and (2) sum it to a running total variable called "total."
import socket, struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2997))
response = s.recv(1024)
print response
total = 0
for i in range(4):
integer = struct.unpack("<I", s.recv(1024))[0]
total += integer
print "received %d, total is now %d" % (integer, total)
Running this, we see:
$ python net2.py
received 2087025338, total is now 2087025338
received 2105404850, total is now 4192430188
received 1958671475, total is now 6151101663
received 1544550904, total is now 7695652567
Everything appears to check out! Now, we just need to send it back... but wait! Remember the warning before about the integer wrapping. Before we pack the integer and send it back, we'll need to do a bitwise AND with "0xFFFFFFFF" to ensure it remains 32-bit. Our final code is:
import socket, struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2997))
total = 0
for i in range(4):
integer = struct.unpack("<I", s.recv(1024))[0]
total += integer
print "received %d, total is now %d" % (integer, total)
final = struct.pack("<I", total & 0xFFFFFFFF)
print "sending " + final
s.send(final)
feedback = s.recv(1024)
print feedback
And if we run this, we see:
$ python net2.py
received 362712404, total is now 362712404
received 2109584628, total is now 2472297032
received 296924273, total is now 2769221305
received 546429760, total is now 3315651065
sending Ѡ
you added them correctly
Success!
Prev: 0x09 - Net1
Next: 0x0B - Heap0