Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions IP Packet Reader/IPv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
#include "protocol.h"

#define IHL(ihl) (0x0F & ihl)
#define FLAGS(byte) (0xE0 & byte) // (0x8000 & byte)
#define FRAG_OFFSET(byte) (printf("%i", 3));
#define FLAGS(byte) ((byte & 0xE0) >> 5) // Extract the 3 flag bits
#define IPv4AddressPrint(identifier, addr) \
printf("%s:\t\t%d.%d.%d.%d\n", identifier, addr[0], addr[1], addr[2], addr[3]);

Expand All @@ -36,23 +35,32 @@ void create_IPv4_packet_file(IPv4_Packet *packet, FILE *file, int8_t ihl) {
packet->IHL = IHL(ihl); // figure out the length of the header for IPv4.

unsigned char buffer[packet->IHL * 4];
fread(buffer, sizeof(char), packet->IHL * 4 - 1, file);
if (packet->IHL < 5) {
fprintf(stderr, "Error: Invalid IHL value %d (must be at least 5)\n", packet->IHL);
return;
}

size_t bytes_read = fread(buffer, sizeof(char), packet->IHL * 4 - 1, file);
if (bytes_read != packet->IHL * 4 - 1) {
fprintf(stderr, "Error: Could not read complete IPv4 header\n");
return;
}

packet->TOS = buffer[0];
packet->total_length = (buffer[1] << 8) | buffer[2]; // total length of the packet including its payload.
packet->ID = (buffer[3] << 8) | buffer[4];

// flags for fragmentation
packet->Flags = FLAGS(buffer[5]);
packet->fragment_off = (0x0E & buffer[5])<<8 | buffer[6];
packet->fragment_off = ((buffer[5] & 0x1F) << 8) | buffer[6];

packet->TTL = buffer[7]; // time to live
packet->protocol = buffer[8]; // protocol
packet->checksum = (buffer[9] << 8) | buffer[10];

// parses the addresses into the address space
address_parser(packet->source_address, buffer, 11);
address_parser(packet->destination_addres, buffer, 15);
address_parser(packet->destination_address, buffer, 15);
}


Expand All @@ -68,21 +76,39 @@ void print_IPv4_packet(IPv4_Packet *packet) {
Print("Flags", packet->Flags);
Print("Fragment Offset", packet->fragment_off);
ProtocolPrint(get_protocol(packet->protocol), packet->protocol);
Print("TTL", packet->TTL);
Print("Checksum", packet->checksum);
IPv4AddressPrint("Source Address", packet->source_address)
IPv4AddressPrint("Desination Address", packet->destination_addres);
IPv4AddressPrint("Source Address", packet->source_address);
IPv4AddressPrint("Destination Address", packet->destination_address);
}


void create_IPv4_packets(int amount, FILE *file) {
if (file == NULL) {
fprintf(stderr, "Error: Invalid file pointer\n");
return;
}

for(int i = 0; i < amount; i++) {
IPv4_Packet packet;
packet.version = 4;
packet.IHL = 5;
packet.TOS = 0;
packet.TTL = 20 + rand() % (65615 - 0 + 1);
packet.ID = 0;
packet.total_length = 20 + (rand() % 1480); // Typical MTU is 1500
packet.TTL = 64; // Common TTL value
packet.ID = rand() % 65536;
packet.Flags = 0;
packet.fragment_off = 0;
packet.protocol = 6; // TCP
packet.checksum = 0; // Would need to calculate actual checksum

// Generate random source and destination addresses
for (int j = 0; j < 4; j++) {
packet.source_address[j] = rand() % 256;
packet.destination_address[j] = rand() % 256;
}

// Write the packet to the file
// This would need to be implemented to actually write the binary data
Comment on lines +111 to +112
Copy link

Copilot AI May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The create_IPv4_packets function currently only populates a struct but does not write any binary packet data to the file; either implement the output logic or remove the unused stub.

Suggested change
// Write the packet to the file
// This would need to be implemented to actually write the binary data
// Serialize the packet into binary format
unsigned char buffer[20]; // Minimum IPv4 header size is 20 bytes
buffer[0] = (packet.version << 4) | packet.IHL;
buffer[1] = packet.TOS;
buffer[2] = (packet.total_length >> 8) & 0xFF;
buffer[3] = packet.total_length & 0xFF;
buffer[4] = (packet.ID >> 8) & 0xFF;
buffer[5] = packet.ID & 0xFF;
buffer[6] = (packet.Flags << 5) | ((packet.fragment_off >> 8) & 0x1F);
buffer[7] = packet.fragment_off & 0xFF;
buffer[8] = packet.TTL;
buffer[9] = packet.protocol;
buffer[10] = (packet.checksum >> 8) & 0xFF;
buffer[11] = packet.checksum & 0xFF;
for (int j = 0; j < 4; j++) {
buffer[12 + j] = packet.source_address[j];
buffer[16 + j] = packet.destination_address[j];
}
// Write the binary data to the file
if (fwrite(buffer, 1, sizeof(buffer), file) != sizeof(buffer)) {
fprintf(stderr, "Error: Failed to write packet to file\n");
}

Copilot uses AI. Check for mistakes.
}
}


22 changes: 14 additions & 8 deletions IP Packet Reader/IPv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@
#include <stdio.h>
#include <stdlib.h>

/// IPv4_Packet - struct that
/// IPv4_Packet - structure to hold IPv4 packet data
typedef struct {
unsigned int version: 4, IHL: 4,
TOS: 8, total_length: 16, ID: 16,
Flags: 3, fragment_off: 13,
TTL: 8, protocol: 8, checksum: 16;
unsigned int source_address[4], destination_addres[4];
unsigned int version: 4, // IP version (4 for IPv4)
IHL: 4, // Internet Header Length (in 32-bit words)
TOS: 8, // Type of Service
total_length: 16, // Total Length of the packet
ID: 16, // Identification
Flags: 3, // Flags for fragmentation
fragment_off: 13, // Fragment Offset
TTL: 8, // Time to Live
protocol: 8, // Protocol
checksum: 16; // Header Checksum
unsigned int source_address[4], destination_address[4]; // Source and destination IP addresses
} IPv4_Packet;

/// print_IPv4_packet - prints the IPv4 packet
Expand All @@ -37,8 +43,8 @@ void print_IPv4_packet(IPv4_Packet *packet);
/// create_IPv4_packet_file - parses the packet data into a IPv4_Packet struct
/// param packet - pointer to the packet struct
/// param file - pointer to the file
/// param ihl - the internet header length
void create_IPv4_packet(IPv4_Packet *packet, FILE *file, int8_t version);
/// param ihl - the first byte already read from the file
void create_IPv4_packet_file(IPv4_Packet *packet, FILE *file, int8_t version);

/// create_IPv4_packets - creates IPv4 packets with randomized values
/// param amount - the amount of packets to create
Expand Down
128 changes: 76 additions & 52 deletions IP Packet Reader/IPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@

#include "IPv6.h"
#include "protocol.h"
#include <string.h>

#define IPv6_Header 40

/// address_parser - parses the address into an integer array
/// param address - pointer to the address location
/// param buffer - the buffer with the binary to the packet
/// param i - the starting index for the buffer
static void address_parser(unsigned int *address, unsigned char *buffer, int i) {
int index = 0;
for (int j = i; j < i+16; j++) {
Expand All @@ -19,73 +24,91 @@ static void address_parser(unsigned int *address, unsigned char *buffer, int i)
}
}

/// simplify_IPv6_address - turns the address into a char of hex.
/// param packet - the pointer to the IPv6
/// param address - the address pointer
/// simplify_IPv6_address - formats the IPv6 address into standard notation
/// param address_string - output string buffer
/// param address - the address array
static void simplify_IPv6_address(unsigned char *address_string, unsigned int *address) {
int i = 0;
char temp[8][5]; // 8 groups of max 4 hex chars each
int i, j;

for (int j = 0; j < 16; j += 2) {
int compressed = 1;

int n = (address[j] << 8) | address[j+1];
if (n == 0 && j != 14 && compressed) {
int m = (address[j+2] << 8) | address[j+3];
if (m == 0) {
j += 4;
for (int k = j; j < 16; j += 2) {
int b = (address[k] << 8) | address[k+1];
if (b != 0) {
j = k-2;
k = 16;
}
}
address[i] = ':';
compressed = 0;
// Format each 16-bit group as hex
for (i = 0; i < 8; i++) {
int value = (address[i*2] << 8) | address[i*2+1];
sprintf((char*)&temp[i], "%x", value);
}

// Find longest run of zeros for :: compression
int zero_start = -1;
int zero_length = 0;
int current_start = -1;
int current_length = 0;

for (i = 0; i < 8; i++) {
if (strcmp(temp[i], "0") == 0) {
if (current_start == -1) {
current_start = i;
current_length = 1;
} else {
address_string[i] = '0';
address_string[i+1] = ':';
i += 2;
current_length++;
}
} else {
while(n != 0) {
// temporary variable to store remainder
int temp = 0;

// storing remainder in temp variable.
temp = n % 16;

// check if temp < 10
if(temp < 10) {
address_string[i] = temp + 48;
i++;
}
else {
address_string[i] = temp + 55;
i++;
}
n = n/16;
if (current_length > zero_length) {
zero_length = current_length;
zero_start = current_start;
}
current_start = -1;
current_length = 0;
}
}

// Check if the last run is the longest
if (current_length > zero_length) {
zero_length = current_length;
zero_start = current_start;
}

// Only compress if we have at least 2 consecutive zero groups
if (zero_length < 2) {
zero_start = -1;
}

// Build the final string
address_string[0] = '\0';
for (i = 0; i < 8; i++) {
if (i == zero_start) {
strcat((char*)address_string, "::");
i += zero_length - 1; // Skip the compressed zeros
} else {
strcat((char*)address_string, temp[i]);
if (i < 7 && (i + 1 != zero_start)) {
strcat((char*)address_string, ":");
}
address_string[i] = ':';
i++;
}
}
}

void create_IPv6_packet(IPv6_Packet *packet, FILE *file, int8_t byte) {
packet->version = 6;
unsigned char buffer[IPv6_Header];
fread(buffer, sizeof(unsigned char), IPv6_Header - 1, file);

packet->traffic_class = ((byte << 4) & 0x0F) | buffer[0];
packet->flow_label = ((((buffer[0] & 0x0F) << 8) | buffer[1]) << 8) | buffer[2];
size_t bytes_read = fread(buffer, sizeof(unsigned char), IPv6_Header - 1, file);
if (bytes_read != IPv6_Header - 1) {
fprintf(stderr, "Error: Could not read complete IPv6 header\n");
return;
}

// Parse the IPv6 header fields
packet->traffic_class = ((byte & 0x0F) << 4) | ((buffer[0] & 0xF0) >> 4);
packet->flow_label = ((buffer[0] & 0x0F) << 16) | (buffer[1] << 8) | buffer[2];
packet->payload_length = (buffer[3] << 8) | buffer[4];
packet->next_header = (buffer[5]);
packet->hop_limit = (buffer[6]);
packet->next_header = buffer[5];
packet->hop_limit = buffer[6];

// Parse source and destination addresses
address_parser(packet->source_address, buffer, 7);
address_parser(packet->source_address, buffer, 23);
address_parser(packet->destination_address, buffer, 23);

// Format addresses for display
simplify_IPv6_address(packet->source_string, packet->source_address);
simplify_IPv6_address(packet->destination_string, packet->destination_address);
}
Expand All @@ -98,7 +121,8 @@ void print_IPv6_packet(IPv6_Packet *packet) {
Print("Traffic Class", packet->traffic_class);
Print("Flow Label", packet->flow_label);
Print("Payload Length", packet->payload_length);
Print("Next Header", packet->next_header);
printf("Source Address\t\t%s", packet->source_string);
printf("Destination Address\t\t%s", packet->destination_string);
ProtocolPrint(get_protocol(packet->next_header), packet->next_header);
Print("Hop Limit", packet->hop_limit);
printf("Source Address:\t\t%s\n", packet->source_string);
printf("Destination Address:\t%s\n", packet->destination_string);
}
7 changes: 7 additions & 0 deletions IP Packet Reader/IPv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,22 @@

#include <stdio.h>

/// IPv6_Packet - structure to hold IPv6 packet data
typedef struct {
unsigned int version: 4, traffic_class: 8, flow_label: 20;
unsigned int payload_length: 16, next_header: 8, hop_limit: 8;
unsigned int source_address[16], destination_address[16];
unsigned char source_string[40], destination_string[40];
} IPv6_Packet;

/// create_IPv6_packet - parses the packet data into an IPv6_Packet struct
/// param packet - pointer to the packet struct
/// param file - pointer to the file
/// param byte - the first byte already read from the file
void create_IPv6_packet(IPv6_Packet *packet, FILE *file, int8_t byte);

/// print_IPv6_packet - prints the IPv6 packet
/// param packet - pointer to the packet being printed
void print_IPv6_packet(IPv6_Packet *packet);

#endif /* IPv6_h */
19 changes: 13 additions & 6 deletions IP Packet Reader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


#define USAGE printf("./main [packet files]\n");
#define VERSION(version) ((0xF0 & version) >> 4);
#define VERSION(version) ((0xF0 & version) >> 4)


/// main - parses the packet files
Expand All @@ -26,7 +26,7 @@ int main(int argc, const char * argv[]) {
int8_t byte;
int8_t version;

if (argc < 1) {
if (argc < 2) {
USAGE;
return 1;
}
Expand All @@ -37,8 +37,13 @@ int main(int argc, const char * argv[]) {

for(int i = 1; i < argc; i++) {
FILE *file = fopen(argv[i], "r");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file %s\n", argv[i]);
continue;
}

while ((fread(&byte, 1, 1, file))) {
version = VERSION(byte)
version = VERSION(byte);
// hand over to IPv4 or IPv6
if(version == 4) {
IPv4_Packet packet;
Expand All @@ -47,12 +52,14 @@ int main(int argc, const char * argv[]) {
} else if(version == 6) {
IPv6_Packet packet;
create_IPv6_packet(&packet, file, byte);
print_IPv6_packet(&packet);
} else {
perror("This is not a packet. This program strictly takes packets.\n");
return 3;
fprintf(stderr, "Error: This is not a valid IP packet (version %d). This program strictly takes IPv4 or IPv6 packets.\n", version);
break;
}
}

fclose(file);
}
return 0;
}

Loading