void switch_process_ff(struct fins_module *module, struct finsFrame *ff) { PRINT_DEBUG("Entered: module=%p, ff=%p", module, ff); if (ff->metaData == NULL) { PRINT_ERROR("Error fcf.metadata==NULL"); exit(-1); } PRINT_WARN("TODO: switch process received frames: ff=%p, meta=%p", ff, ff->metaData); print_finsFrame(ff); if (ff->dataOrCtrl == FF_CONTROL) { switch_fcf(module, ff); PRINT_DEBUG(""); } else if (ff->dataOrCtrl == FF_DATA) { if (ff->dataFrame.directionFlag == DIR_UP) { //switch_in_fdf(module, ff); PRINT_WARN("todo"); freeFinsFrame(ff); } else if (ff->dataFrame.directionFlag == DIR_DOWN) { //switch_out_fdf(ff); PRINT_WARN("todo"); freeFinsFrame(ff); } else { PRINT_ERROR("todo error"); exit(-1); } } else { PRINT_ERROR("todo error: dataOrCtrl=%u", ff->dataOrCtrl); exit(-1); } }
void *switch_loop(void *local) { struct fins_module *module = (struct fins_module *) local; PRINT_DEBUG("Entered: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name); struct switch_data *md = (struct switch_data *) module->data; uint32_t i; int ret; //int32_t val; struct finsFrame *ff; //uint8_t index; int counter = 0; while (module->state == FMS_RUNNING) { secure_sem_wait(module->event_sem); //TODO uncomment, for testing //secure_sem_wait(module->input_sem); secure_sem_wait(&md->overall->sem); for (i = 0; i < MAX_MODULES; i++) { if (md->overall->modules[i] != NULL) { //helgrind says is race condition, though there will always be FF when post to event_sem if (!IsEmpty(md->overall->modules[i]->output_queue)) { //added as optimization /* //can possibly cause switch to be "behind" ret = sem_getvalue(md->overall->modules[i]->output_sem, &val); if (ret) { PRINT_ERROR("sem get value prob: src module_index=%u, ret=%d", i, ret); exit(-1); } //*/ //if (val != 0) { while ((ret = sem_wait(md->overall->modules[i]->output_sem)) && errno == EINTR) ; if (ret != 0) { PRINT_ERROR("sem wait prob: src module_index=%u, ret=%d", i, ret); exit(-1); } ff = read_queue(md->overall->modules[i]->output_queue); sem_post(md->overall->modules[i]->output_sem); //if (ff != NULL) { //shouldn't occur counter++; //index = ff->destinationID; if (ff->destinationID < 0 || ff->destinationID > MAX_MODULES) { PRINT_ERROR("dropping ff: illegal destination: src module_index=%u, dst module_index=%u, ff=%p, meta=%p", i, ff->destinationID, ff, ff->metaData); //TODO if FCF set ret_val=0 & return? or free or just exit(-1)? freeFinsFrame(ff); } else { //if (i != id) //TODO add this? if (md->overall->modules[ff->destinationID] != NULL) { PRINT_DEBUG("Counter=%d, from='%s', to='%s', ff=%p, meta=%p", counter, md->overall->modules[i]->name, md->overall->modules[ff->destinationID]->name, ff, ff->metaData); //TODO decide if should drop all traffic to switch input queues, or use that as linking table requests if (ff->destinationID == module->index) { switch_process_ff(module, ff); } else { while ((ret = sem_wait(md->overall->modules[ff->destinationID]->input_sem)) && errno == EINTR) ; if (ret != 0) { PRINT_ERROR("sem wait prob: dst index=%u, ff=%p, meta=%p, ret=%d", ff->destinationID, ff, ff->metaData, ret); exit(-1); } if (write_queue(ff, md->overall->modules[ff->destinationID]->input_queue)) { sem_post(md->overall->modules[ff->destinationID]->event_sem); sem_post(md->overall->modules[ff->destinationID]->input_sem); } else { sem_post(md->overall->modules[ff->destinationID]->input_sem); PRINT_ERROR("Write queue error: dst index=%u, ff=%p, meta=%p", ff->destinationID, ff, ff->metaData); freeFinsFrame(ff); } } } else { PRINT_ERROR("dropping ff: destination not registered: src index=%u, dst index=%u, ff=%p, meta=%p", i, ff->destinationID, ff, ff->metaData); print_finsFrame(ff); //TODO if FCF set ret_val=0 & return? or free or just exit(-1)? freeFinsFrame(ff); } //} //} } } } } //sem_post(module->input_sem); sem_post(&md->overall->sem); } PRINT_DEBUG("Exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name); return NULL; }
void udp_out(struct finsFrame* ff) { struct finsFrame* newFF; struct udp_metadata_parsed parsed_meta; /* read the FDF and make sure everything is correct*/ if (ff->dataOrCtrl != DATA) { // release FDF here return; } if (ff->dataFrame.directionFlag != DOWN) { // release FDF here return; } if (ff->destinationID.id != UDPID) { // release FDF here return; } PRINT_DEBUG("UDP_out"); print_finsFrame(ff); struct udp_header packet; struct udp_packet check_packet; u_char test[100]; metadata* meta = (ff->dataFrame).metaData; u_char *udp_dataunit = (u_char *)malloc( (ff->dataFrame).pduLength + U_HEADER_LEN ); /** constructs the UDP packet from the FDF and the meta data */ PRINT_DEBUG("%d", ff->dataFrame.pduLength); uint32_t dstbuf; uint32_t srcbuf; uint32_t dstip; uint32_t srcip; PRINT_DEBUG("UDP_out"); metadata_readFromElement(meta,"dstport",&dstbuf); metadata_readFromElement(meta,"srcport",&srcbuf); metadata_readFromElement(meta,"dstip",&dstip); metadata_readFromElement(meta,"srcip",&srcip); /** fixing the values because of the conflict between uint16 type and * the 32 bit META_INT_TYPE */ packet.u_dst = dstbuf; packet.u_src = srcbuf; PRINT_DEBUG("%d, %d", (packet.u_dst),(packet.u_src)); (packet.u_dst) = htons(packet.u_dst); (packet.u_src) = htons(packet.u_src); /* calculates the UDP length by adding the UDP header length to the length of the data */ int packet_length; packet_length= ( ((ff->dataFrame).pduLength) + U_HEADER_LEN );; packet.u_len = htons( ((ff->dataFrame).pduLength) + U_HEADER_LEN ); /** TODO ignore the checksum for now * Will be fixed later */ /** Invalidation disabled value = 0xfed2*/ parsed_meta.u_destPort = htons( packet.u_dst); parsed_meta.u_srcPort = htons( packet.u_src); parsed_meta.u_IPdst = htonl( dstip); parsed_meta.u_IPsrc = htonl( dstip); parsed_meta.u_pslen = htons( packet_length); parsed_meta.u_prcl = htons( UDP_PROTOCOL); packet.u_cksum = 0; memcpy(&check_packet,&packet,U_HEADER_LEN); memcpy(&check_packet,ff->dataFrame.pdu,ff->dataFrame.pduLength); packet.u_cksum = UDP_checksum(&check_packet,&parsed_meta); /* stores a value of zero in the checksum field so that it can be calculated */ PRINT_DEBUG("%d,%d,%d,%d", packet.u_src,packet.u_dst,packet.u_len,packet.u_cksum); // packet.u_cksum = UDP_checksum(&packet, meta); /* calculates ands stores the real checksum in the checksum field */ /* need to be careful in the line ^ above ^, the metadata needs to have the source and destination IPS in order to calculate the checksum */ //printf("The checksum Value is %d", packet.u_cksum); int i=0; while (i < ff->dataFrame.pduLength) { PRINT_DEBUG("%d",ff->dataFrame.pdu[i]); i++; } PRINT_DEBUG("UDP_out"); memcpy(udp_dataunit, &packet, U_HEADER_LEN); /* copies the UDP packet into the memory that has been allocated for the PDU */ // PRINT_DEBUG("%d, %d",(ff->dataFrame).pdu, ff->dataFrame.pduLength); memcpy(udp_dataunit + U_HEADER_LEN ,(ff->dataFrame).pdu, ff->dataFrame.pduLength); /* moves the pointer 8 bytes to account for those empty 8 bytes*/; // PRINT_DEBUG("%d",packet.u_len); /** memcpy(test, udp_dataunit, packet_length); test [packet_length] = '\0'; i=0; while (i < packet_length) { PRINT_DEBUG("%d",test[i]); i++; } //free (ff->dataFrame.pdu); PRINT_DEBUG("%s",test); PRINT_DEBUG("%d",udp_dataunit); */ ff->dataFrame.pdu = udp_dataunit; /* creates a new FDF to be sent out */ PRINT_DEBUG("%d",ff->dataFrame.pdu); PRINT_DEBUG("UDP_out"); newFF = create_ff(DATA, DOWN, IPV4ID, packet_length, ff->dataFrame.pdu, ff->dataFrame.metaData); PRINT_DEBUG("%d",newFF->dataFrame.pdu); print_finsFrame(newFF); udpStat.totalSent++; PRINT_DEBUG("UDP_out"); sendToSwitch(newFF); }