Here is the code snippet. Since we are building security tools, let’s upgrade our Port Scanner into a Banner Grabber.
When you connect to certain ports (like Port 80 for HTTP web servers), if you send them a specific message, they will reply. Because Linux treats that network socket exactly like a file, we can use the universal write() command to send our message, and read() to capture the server’s reply.
Here is how you talk to a file descriptor in C:
“`c
#include
int main() { // 1. Setup the connection (Same as before, but pointing to a test web server on Port 80) int sock = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in target; target.sin_family = AF_INET; target.sin_port = htons(80); target.sin_addr.s_addr = inet_addr("93.184.216.34”); // IP for example.com
printf(“Connecting…\n”); if (connect(sock, (struct sockaddr *)&target, sizeof(target)) != 0) { printf(“Connection failed.\n”); return 1; }
// ——————————————————— // THE NEW STUFF: Reading and Writing to the File Descriptor // ———————————————————
// 2. Formulate the message to SEND (An HTTP GET Request) char *message = “GET / HTTP/1.1\r\nHost: example.com\r\n\r\n”;
// write(file_descriptor, data_pointer, number_of_bytes) write(sock, message, strlen(message)); printf(“Message sent to the server.\n”);
// 3. Create a BUFFER to catch the reply // We are carving out exactly 1024 bytes of memory to hold the server’s response. char buffer[1024];
// Clear the buffer with zeros so there’s no leftover garbage in memory memset(buffer, 0, sizeof(buffer));
// 4. READ the reply from the socket into the buffer // read(file_descriptor, destination_buffer, max_bytes_to_read) int bytes_received = read(sock, buffer, sizeof(buffer) - 1);
// 5. Print what we caught if (bytes_received > 0) { printf(“Received %d bytes from server:\n\n”, bytes_received); printf(“%s\n”, buffer); // Print the raw string we caught }
close(sock); // Always close the file descriptor! return 0; }
### The Break Down
> **Info Box: The Why and How of Buffers**
> * **The Fact:** Before you can read data from a network (or a file), you must manually reserve a block of memory to put that data into. This is called a "buffer."
> * **The Why:** In Python, if you receive a 10MB file, Python automatically expands its memory to hold it. C does not do this. If you ask C to read data, you must tell it exactly *where* to put it and exactly *how much* space is available. If you receive 2000 bytes but only reserved 1024 bytes, the extra data spills into adjacent memory. This is a **Buffer Overflow**—one of the most critical vulnerabilities in cybersecurity.
> * **The How:** char buffer[1024]; creates an array of 1024 characters. When we call read(sock, buffer, 1023), we are telling the OS: "Read data from socket 3, dump it into the memory address starting at buffer, but absolutely DO NOT write more than 1023 bytes." (We save 1 byte for the null terminator \0 so C knows where the string ends).
>
> **Info Box: The Why and How of read() and write()**
> * **The Fact:** These functions don't return the data itself; they return an integer representing the *number of bytes* they successfully processed.
> * **The Why:** Networks are unreliable. You might ask write() to send 500 bytes, but the network buffer is full, so it only sends 200 bytes. Or, you might read() and get an error (which returns -1).
> * **The How:** Always capture the output of these functions (int bytes_received = read(...)). If it's greater than 0, you got data. If it's 0, the target cleanly closed the connection. If it's -1, something broke.
>
If you compile and run this on your droplet (gcc banner.c -o banner then ./banner), you will see the raw, underlying HTTP HTML and server headers print out on your screen. You just built a rudimentary curl command from scratch.
Now you have the pieces: opening sockets, connecting, reading, and writing. The next logical step for a scanner is **Loops and Arguments**—making the program scan multiple ports automatically, or letting you type ./scanner 192.168.1.1 in the terminal instead of hardcoding the IP. Which piece do you want to tackle next?