i think i should post my code to make it easier(or harder???) for u guys to understand
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "bool.h"
#include "layer2.h"
#include "layer3.h"
/* The Layer 3 PDU length is the MTU of Layer 3. */
/* (even though we can't really put all that into one packet) */
#define L3_PDU_MAXLENGTH L3_MTU
/* the fill in for other headers which need to be set to zero*/
#define ZERO 0x00;
/* a global varible for identification */
static int identificator = 0;
/* the branch linked list */
struct nodebranch{
unsigned int offset;
unsigned char data[130];
struct nodebranch *next;
};
struct node{
unsigned int id;
struct nodebranch *branch;
struct node *next;
};
/* the linked list we use to store different msgs before send them*/
static void insertToList(struct node **msgBuffer, L2_IDU l2idu);
static void insertToBranch(struct nodebranch **bufferNode, L2_IDU l2idu);
static int countLength(struct nodebranch **branch);
/* the function to check if all the packets have been stored, if is
* sort and send the msg and return a 1, else return 0
*/
void StoreAndSendMessage(struct nodebranch * branch, int branchLength, int lastPacketDataLength);
void checkAndSend(struct nodebranch **branch, L2_IDU l2idu);
//void insert( NodePtr *sPtr, char value);
//void delete( NodePtr *sPtr, char value);
/* the packet is a Layer 3 protocol data unit */
typedef unsigned char L3_PDU[L3_PDU_MAXLENGTH];
int L3_connected=FALSE;
/* the function that Layer 2 calls */
static void L3_receiveL2_IDU(L2_IDU l2idu);
/* the pointer to a function, to call when giving a DU to Layer 4 */
static void (* receiveL3_IDU)(L3_IDU l3idu);
/**
* Place your function header and description here.
* - describe how you implemented the reassembly
* - describe any data structures you used
* - etc.
*/
static void L3_receiveL2_IDU(L2_IDU l2idu)
{
/* the linked list of linked list which store all the packets
* before sending them
*/
printf("show something before the seg fault!!\n");
struct node *msgBuffer = NULL;
insertToList(&msgBuffer, l2idu);
}
void insertToList(struct node **Buffer, L2_IDU l2idu){
int id; /* identification */
/* check if the linked list already have node with the same
* identificaton
*/
struct node *currentList; /*currentListList pointer*/
struct node *new; /*use to add new node*/
struct node *preList; /*point to one before msgBuffer*/
/*allocate memory to new*/
new = malloc(sizeof(struct node));
/* get id */
id = ((l2idu.data[4]<<8) | l2idu.data[5]);
/* if there s space, insert packet*/
if(new != NULL){
preList = NULL;
currentList = *Buffer;
/* loop to the last node in the list or the node which got
* the same id no. with the packet*/
while(currentList != NULL && currentList->id != id){
preList = currentList;
currentList = currentList->next;
}
/*case 1, there s a node in the list have same id */
if(currentList != NULL && preList!=NULL){
/* insert the packet into the node */
insertToBranch(&(currentList->branch), l2idu);
printf("out of insertToBranch function01");
}
/* otherwise, the list comes to the end, and we ll add the packet
* on the end of the list*/
else{
new->id = id;
insertToBranch(&(currentList->branch), l2idu);
printf("out of insertToBranch function02");
new->next = NULL; /*node doesnt link to other node*/
/* case 3, empty list */
if (preList == NULL){
new->next = *Buffer;
*Buffer = new;
/* point currentList to new */
currentList = new;
}
/* case 2, no id in the list, add to the end of list */
else {
preList->next = new;
new->next = currentList;
/* point currentList to new */
currentList = new;
}
}
}
else {
printf("%c not inserted. No memory available.\n", id );
}
/* after insert the packet, we need to check if the branch which
* just insert the packet has a MF set to true. if its true, means
* there s chance the whole msg has been recieved. if its so, store
* and send the msg, and clear the branch free the memory.
*/
checkAndSend(¤tList->branch, l2idu);
if(currentList->branch == NULL){
preList->next = currentList->next;
free(currentList);
}
}
/*insert the packet into the node with same id, along
* with data, a offset and a counter will be saved as well
* for later use. after the packet has been saved onto branch,
* check if all the packets has been recieved, by check if
* the count equl to the offset/16. sort and send them and
* make branch to NULL and free the memory.
* the packet with MF = 0 (the last packet) will be inserted
* on the end of the list while others will be inserted in the
* front.
*/
void insertToBranch(struct nodebranch **bufferNode, L2_IDU l2idu){
printf("in the insertToBranch function\n");
int offset; /* the offset of incoming packet l2idu*/
int i; /* counter i */
int length; /* totle length of the packet */
int lastPacketDataLength = 0; /* the data length of the last packet(where MP=0)*/
struct nodebranch * newNode; /* newNode to add into branch */
struct nodebranch * pre; /* a linked list point one node before current*/
struct nodebranch * current;
/* current point to bufferNode */
current = *bufferNode;
/* get the offset, while the MF is 1, need to change that bit
* into 0 1st.
*/
printf("the current is pointed to *bufferNode\n");
if( (l2idu.data[6] ^ (1<<5)) > l2idu.data[6]){
offset = ((l2idu.data[6]<<8) | l2idu.data[7]);
printf("the offset is : %d \n", offset);
}
else {
offset = ( ( (l2idu.data[6] ^ (1<<5)) <<8) | l2idu.data[7]);
printf("the offset is : %d \n", offset);
}
/* get totle length of the packet */
length = ((l2idu.data[2]<<8) | l2idu.data[3]);
/* asign memory to the new node */
newNode = malloc(sizeof(struct nodebranch));
/*if the MF = 0, the bufferNode->MF will be set to TRUE
*/
if((l2idu.data[6] ^ (1<<5)) > l2idu.data[6]) {
/* the data length of packet which have MF=0 */
lastPacketDataLength = length - 20;
}
/* for all the packets, will be inserted into a sorted list */
/* loop to get the sorted position of the packet */
while(current != NULL && offset > current->offset){
pre = current;
current = current->next;
}
/* put packet into a new node */
newNode->offset = offset;
for(i=0; i<(length-20); i++){
newNode->data[i] = l2idu.data[20+i];
}
/* for empty list */
if(pre == NULL){
newNode->next = *bufferNode;
*bufferNode = newNode;
}
/* if list s not empty, insert new node */
else{
pre->next = newNode;
newNode->next = current;
}
}