用c语言编写当系统接收到一个IP报文时,判断IP报文是否是有分片,如果未分片的话,则直接返回该报文。否则,进行IP报文重组的处理。 IP报文的重组过程分为以下几个步骤: a)将IP报文存入临时的HASH链表中 这个HASH链表中是等待合并的报文队列头 判断当这一个IP报文分片加入后是否可以构造出一个完整的IP报文,如果可以的话,分配一个新的帧缓冲区,将数据复制入新的帧缓冲区,返回该报文。
时间: 2024-02-06 21:08:49 浏览: 59
以下是一个简单的示例程序,用于接收IP报文并进行重组处理。这个程序假设已经有一个名为"recv_packet()"的函数,用于接收IP报文。你需要根据自己的具体情况进行修改和调整。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define IP_HEADER_SIZE 20
#define MAX_IP_DATAGRAM_SIZE 65535
struct ip_datagram {
unsigned short id;
unsigned short offset;
unsigned short length;
unsigned char *data;
struct ip_datagram *next;
};
struct hash_table {
int size;
struct ip_datagram **table;
};
unsigned int hash(unsigned short id) {
return id % 997;
}
struct hash_table *create_hash_table(int size) {
struct hash_table *ht = (struct hash_table *)malloc(sizeof(struct hash_table));
ht->size = size;
ht->table = (struct ip_datagram **)calloc(size, sizeof(struct ip_datagram *));
return ht;
}
void destroy_hash_table(struct hash_table *ht) {
int i;
for (i = 0; i < ht->size; i++) {
struct ip_datagram *cur = ht->table[i];
while (cur) {
struct ip_datagram *tmp = cur;
cur = cur->next;
free(tmp->data);
free(tmp);
}
}
free(ht->table);
free(ht);
}
struct ip_datagram *find_ip_datagram(struct hash_table *ht, unsigned short id) {
unsigned int h = hash(id);
struct ip_datagram *cur = ht->table[h];
while (cur) {
if (cur->id == id) {
return cur;
}
cur = cur->next;
}
return NULL;
}
void add_ip_datagram(struct hash_table *ht, struct ip_datagram *datagram) {
unsigned int h = hash(datagram->id);
datagram->next = ht->table[h];
ht->table[h] = datagram;
}
struct ip_datagram *remove_ip_datagram(struct hash_table *ht, unsigned short id) {
unsigned int h = hash(id);
struct ip_datagram *cur = ht->table[h];
struct ip_datagram *prev = NULL;
while (cur) {
if (cur->id == id) {
if (prev) {
prev->next = cur->next;
} else {
ht->table[h] = cur->next;
}
cur->next = NULL;
return cur;
}
prev = cur;
cur = cur->next;
}
return NULL;
}
int is_last_fragment(struct ip_datagram *datagram) {
return (datagram->offset & 0x2000) == 0;
}
int is_first_fragment(struct ip_datagram *datagram) {
return datagram->offset == 0;
}
int is_fragmented(struct ip_datagram *datagram) {
return (datagram->offset & 0x3fff) != 0;
}
struct ip_datagram *reconstruct_ip_datagram(struct hash_table *ht, struct ip_datagram *first_fragment) {
int length = first_fragment->length;
struct ip_datagram *cur = first_fragment->next;
while (cur) {
length += cur->length - IP_HEADER_SIZE;
cur = cur->next;
}
struct ip_datagram *datagram = (struct ip_datagram *)malloc(sizeof(struct ip_datagram));
datagram->id = first_fragment->id;
datagram->offset = 0;
datagram->length = length;
datagram->data = (unsigned char *)malloc(length);
memcpy(datagram->data, first_fragment->data + IP_HEADER_SIZE, first_fragment->length - IP_HEADER_SIZE);
cur = first_fragment->next;
while (cur) {
memcpy(datagram->data + first_fragment->length - IP_HEADER_SIZE, cur->data + IP_HEADER_SIZE, cur->length - IP_HEADER_SIZE);
cur = cur->next;
}
return datagram;
}
struct ip_datagram *get_ip_datagram() {
struct ip_datagram *datagram = (struct ip_datagram *)malloc(sizeof(struct ip_datagram));
datagram->id = 0;
datagram->offset = 0;
datagram->length = 0;
datagram->data = NULL;
datagram->next = NULL;
return datagram;
}
void free_ip_datagram(struct ip_datagram *datagram) {
free(datagram->data);
free(datagram);
}
struct ip_datagram *receive_ip_datagram() {
/* receive IP datagram */
return NULL;
}
void send_ip_datagram(struct ip_datagram *datagram) {
/* send IP datagram */
}
void process_ip_datagram(struct hash_table *ht, struct ip_datagram *datagram) {
if (!is_fragmented(datagram)) {
/* not fragmented, send directly */
send_ip_datagram(datagram);
} else if (is_first_fragment(datagram)) {
/* first fragment, add to hash table */
add_ip_datagram(ht, datagram);
} else {
/* subsequent fragment, find first fragment and append */
struct ip_datagram *first_fragment = find_ip_datagram(ht, datagram->id);
if (first_fragment) {
if (first_fragment->length + datagram->length - IP_HEADER_SIZE <= MAX_IP_DATAGRAM_SIZE) {
struct ip_datagram *cur = first_fragment;
while (cur->next) {
cur = cur->next;
}
cur->next = datagram;
if (is_last_fragment(datagram)) {
struct ip_datagram *reconstructed_datagram = reconstruct_ip_datagram(ht, first_fragment);
remove_ip_datagram(ht, datagram->id);
send_ip_datagram(reconstructed_datagram);
free_ip_datagram(reconstructed_datagram);
}
} else {
/* fragment too large, drop */
remove_ip_datagram(ht, datagram->id);
free_ip_datagram(datagram);
}
} else {
/* first fragment not found, drop */
free_ip_datagram(datagram);
}
}
}
int main() {
struct hash_table *ht = create_hash_table(997);
while (1) {
struct ip_datagram *datagram = receive_ip_datagram();
process_ip_datagram(ht, datagram);
}
destroy_hash_table(ht);
return 0;
}
```
阅读全文