I just wrote an exam for the course Technische Informatik III which was about operating systems and network communication. In the exercises throughout the semster, we had to program in C a lot. Naturally, in the exam was one task about interpreting what a C program does.
It was really simple: Listening on a UDP socket and print incoming packets
along with source address and port. The program looked somewhat like this (from
what I remember; also some things were done in a not so clever way on the exercise
sheet, and they had obfuscated the variable names to a non-descriptive
a
, b
, etc.):
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <error.h>
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in listen, incoming;
socklen_t incoming_len;
char buf[1024];
int len; /* of received data */
/* listen on 0.0.0.0:5000 */
listen.sin_family = AF_INET;
listen.sin_addr.s_addr = INADDR_ANY;
listen.sin_port = htons(5000);
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
perror("socket");
if(bind(sockfd, (struct sockaddr *) &listen, sizeof(listen)) == -1)
perror("bind");
while(1) {
len = recvfrom(sockfd, buf, 1024, 0, (struct sockaddr *) &incoming,
&incoming_len);
buf[len] = '\0';
printf("from %s:%d: \"%s\"\n", inet_ntoa(incoming.sin_addr),
ntohs(incoming.sin_port), buf);
}
}
I lol'd so hard when I saw this. It's a classic off-by-one error. (Can you spot it, too?)
If you want to store x bytes of data in a string, reserve x+1
bytes for the NULL termination character. Here, if you send a message
that is exactly 1024 bytes long (or longer, as it'll get truncated),
buf[len]
will actually be the 1025th byte. Which might
just be anything.
And those guys want to teach network and filesystem programming – hilarious. :-D