int rtm_console_listening_test(struct rtm_console *console, uint32_t *index, uint32_t *param_id) { if (console->type == RTM_TYPE_CONSOLE) { return 0; } uint8_t buf[500]; memset(buf, 0, 500); sprintf((char *) buf, "l%u_%d", *index, *param_id); int32_t val; if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) { return val == VALUE_TRUE; } sprintf((char *) buf, "l%u_%d", *index, -1); if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) { return val == VALUE_TRUE; } sprintf((char *) buf, "l%u_%d", 32, *param_id); if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) { return val == VALUE_TRUE; } sprintf((char *) buf, "l%u_%d", 32, -1); if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) { return val == VALUE_TRUE; } return 0; }
int readFrom_fins(int senderid,int sockfd,u_char **buf,int *buflen,int symbol,struct sockaddr_in *address, int block_flag) { /**TODO MUST BE FIXED LATER * force symbol to become zero */ symbol = 0; struct finsFrame *ff=NULL; int index; uint16_t srcport; uint32_t srcip; struct sockaddr_in * addr_in= (struct sockaddr_in * )address; index = findjinniSocket(senderid,sockfd); PRINT_DEBUG("index = %d",index); /** * It keeps looping as a bad method to implement the blocking feature * of recvfrom. In case it is not blocking then the while loop should * be replaced with only a single trial ! * */ PRINT_DEBUG(); if (block_flag == 1) { PRINT_DEBUG(); do { sem_wait(&(jinniSockets[index].Qs)); // PRINT_DEBUG(); ff= read_queue(jinniSockets[index].dataQueue); // ff = get_fake_frame(); // PRINT_DEBUG(); sem_post(&(jinniSockets[index].Qs)); } while(ff == NULL); PRINT_DEBUG(); } else { PRINT_DEBUG(); sem_wait(&(jinniSockets[index].Qs)); //ff= read_queue(jinniSockets[index].dataQueue); /** ff = get_fake_frame(); print_finsFrame(ff); */ ff= read_queue(jinniSockets[index].dataQueue); sem_post(&(jinniSockets[index].Qs)); } if (ff == NULL) { //free(ff); return(0); } PRINT_DEBUG("PDU lenght %d",ff->dataFrame.pduLength); //*buf = (u_char *)malloc(sizeof(ff->dataFrame.pduLength)); //memcpy(*buf,ff->dataFrame.pdu,ff->dataFrame.pduLength); memcpy(buf,ff->dataFrame.pdu,ff->dataFrame.pduLength); *buflen = ff->dataFrame.pduLength; PRINT_DEBUG(); if (symbol == 0) { // address = NULL; PRINT_DEBUG(); // freeFinsFrame(ff); return (1); } PRINT_DEBUG(); if (metadata_readFromElement(ff->dataFrame.metaData,"hostport",&srcport) == 0 ) { address->sin_port = 0; return (1); } if (metadata_readFromElement(ff->dataFrame.metaData,"hostip",&srcip) == 0 ) { address->sin_addr.s_addr =0; return (1); } addr_in->sin_port = srcport; addr_in->sin_addr.s_addr = srcip; /**TODO Free the finsFrame * This is the final consumer * call finsFrame_free(Struct finsFrame** ff) */ PRINT_DEBUG(); //freeFinsFrame(ff); /** Finally succeeded * */ return(1); } //end of readFrom_fins
void ipv4_exec_reply(struct finsFrame *ff) { PRINT_DEBUG("Entered: ff=%p, meta=%p", ff, ff->metaData); int ret = 0; metadata *params = ff->metaData; if (params) { switch (ff->ctrlFrame.param_id) { case EXEC_ARP_GET_ADDR: PRINT_DEBUG("param_id=EXEC_ARP_GET_ADDR (%d)", ff->ctrlFrame.param_id); if (ff->ctrlFrame.ret_val) { uint64_t src_mac, dst_mac; ret += metadata_readFromElement(params, "src_mac", &src_mac) == META_FALSE; ret += metadata_readFromElement(params, "dst_mac", &dst_mac) == META_FALSE; if (ret) { PRINT_ERROR("ret=%d", ret); //TODO send nack } else { //ipv4_exec_reply_get_addr(ff, src_mac, dst_mac); struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num); if (store) { PRINT_DEBUG("store=%p, ff=%p, serial_num=%u", store, store->ff, store->serial_num); store_list_remove(store); uint32_t ether_type = IP4_ETH_TYPE; metadata_writeToElement(store->ff->metaData, "send_ether_type", ðer_type, META_TYPE_INT32); metadata_writeToElement(store->ff->metaData, "send_dst_mac", &dst_mac, META_TYPE_INT64); metadata_writeToElement(store->ff->metaData, "send_src_mac", &src_mac, META_TYPE_INT64); PRINT_DEBUG("recv frame: dst=0x%12.12llx, src=0x%12.12llx, type=0x%x", dst_mac, src_mac, ether_type); //print_finsFrame(fins_frame); ipv4_to_switch(store->ff); store->ff = NULL; store_free(store); freeFinsFrame(ff); } else { PRINT_ERROR("todo error"); } } } else { //TODO error sending back FDF as FCF? saved pdu for that PRINT_ERROR("todo error"); } break; default: PRINT_ERROR("Error unknown param_id=%d", ff->ctrlFrame.param_id); //TODO implement? freeFinsFrame(ff); break; } } else { //TODO send nack PRINT_ERROR("Error fcf.metadata==NULL"); freeFinsFrame(ff); } }
void IP4_receive_fdf(void) { struct finsFrame* pff = NULL; uint32_t protocol; do { sem_wait(&Switch_to_IPv4_Qsem); pff = read_queue(Switch_to_IPv4_Queue); sem_post(&Switch_to_IPv4_Qsem); } while (ipv4_running && pff == NULL); if (!ipv4_running) { return; } if (pff->dataOrCtrl == CONTROL) { PRINT_DEBUG("Received frame: D/C: %d, DestID=%d, ff=%p, meta=%p", pff->dataOrCtrl, pff->destinationID.id, pff, pff->metaData); ipv4_fcf(pff); } else if (pff->dataOrCtrl == DATA) { PRINT_DEBUG("Received frame: D/C: %d, DestID=%d, ff=%p, meta=%p", pff->dataOrCtrl, pff->destinationID.id, pff, pff->metaData); PRINT_DEBUG("PDU Length: %d", pff->dataFrame.pduLength); PRINT_DEBUG("Data direction: %d", pff->dataFrame.directionFlag); PRINT_DEBUG("pdu=%p", pff->dataFrame.pdu); if (pff->dataFrame.directionFlag == UP) { PRINT_DEBUG("IP4_in"); IP4_in(pff, (struct ip4_packet*) pff->dataFrame.pdu, pff->dataFrame.pduLength); } else if (pff->dataFrame.directionFlag == DOWN) { PRINT_DEBUG("IP4_out"); metadata *params = pff->metaData; if (params == NULL) { PRINT_ERROR("todo error"); freeFinsFrame(pff); return; } int ret = 0; ret += metadata_readFromElement(params, "send_protocol", &protocol) == META_FALSE; if (ret) { PRINT_ERROR("metadata read error: ret=%d", ret); } PRINT_DEBUG("%lu", my_ip_addr); PRINT_DEBUG("Transport protocol going out passed to IPv4: protocol=%u", protocol); switch (protocol) { case IP4_PT_ICMP: IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_ICMP); break; case IP4_PT_TCP: IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_TCP); break; case IP4_PT_UDP: IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_UDP); break; default: PRINT_ERROR("invalid protocol: protocol=%u", protocol); /** * TODO investigate why the freeFinsFrame below create segmentation fault */ freeFinsFrame(pff); break; } } else { PRINT_ERROR("Error: Wrong value of fdf.directionFlag"); freeFinsFrame(pff); } } else { PRINT_ERROR("Error: Wrong pff->dataOrCtrl value"); freeFinsFrame(pff); } }
//extern struct ip4_packet *construct_packet_buffer; void IP4_out(struct finsFrame *ff, uint16_t length, IP4addr source, uint8_t protocol) { PRINT_DEBUG(""); //print_finsFrame(ff); char *data = (char *) ((ff->dataFrame).pdu); PRINT_DEBUG(""); uint8_t more_fragments = 1; uint16_t offset = 0; IP4addr destination; struct ip4_next_hop_info next_hop; struct ip4_fragment fragment; struct ip4_packet_header construct_packet; struct ip4_packet *construct_packet_buffer; //construct_packet_buffer = &construct_packet; construct_packet_buffer = (struct ip4_packet *)&construct_packet; PRINT_DEBUG(""); metadata_readFromElement(ff->dataFrame.metaData, "dstip", &destination); PRINT_DEBUG(""); IP4_const_header(construct_packet_buffer, source, destination, protocol); PRINT_DEBUG(""); /** TODO * finding out what is wrong with the fragmentation and reimplement it * correctly * Notice that the current implementation support mutlithreading * while the basic opf the implemented fragmentation is based on having one * global packet to hold the contents */ /** while (more_fragments) { fragment = IP4_fragment_data(data, length, offset, IP4_PCK_LEN - IP4_MIN_HLEN); memcpy(fragment.data, construct_packet_buffer->ip_data, fragment.data_length); construct_packet_buffer->ip_fragoff = htons(fragment.first >> 3); construct_packet_buffer->ip_len = htons(fragment.data_length + IP4_MIN_HLEN); more_fragments = fragment.more_fragments; next_hop = IP4_next_hop(destination); if (next_hop.interface>=0) { stats.outfragments++; PRINT_DEBUG(""); print_finsFrame(ff); IP4_send_fdf_out(ff, construct_packet_buffer, next_hop, fragment.data_length); } else { PRINT_DEBUG("No route to the destination, packet discarded"); } more_fragments = fragment.more_fragments; offset = fragment.last + 1; } */ construct_packet_buffer->ip_fragoff = htons(0); construct_packet_buffer->ip_id = htons(0); construct_packet_buffer->ip_len = htons(length + IP4_MIN_HLEN); construct_packet_buffer->ip_cksum = 0; construct_packet_buffer->ip_cksum = IP4_checksum(construct_packet_buffer, IP4_MIN_HLEN); next_hop = IP4_next_hop(destination); if (next_hop.interface >= 0) { //stats.outfragments++; PRINT_DEBUG(""); //print_finsFrame(ff); IP4_send_fdf_out(ff, construct_packet_buffer, next_hop, length); } else { PRINT_DEBUG("No route to the destination, packet discarded"); } }
int UDPreadFrom_fins(unsigned long long uniqueSockID, u_char *buf, int *buflen, int symbol, struct sockaddr_in *address, int block_flag, int multi_flag) { /**TODO MUST BE FIXED LATER * force symbol to become zero */ //symbol = 0; struct finsFrame *ff = NULL; struct finsFrame *ff_copy = NULL; int index; uint16_t srcport; uint32_t srcip; struct sockaddr_in * addr_in = (struct sockaddr_in *) address; int i; sem_wait(&jinniSockets_sem); index = findjinniSocket(uniqueSockID); sem_post(&jinniSockets_sem); PRINT_DEBUG("index = %d", index); /** * It keeps looping as a bad method to implement the blocking feature * of recvfrom. In case it is not blocking then the while loop should * be replaced with only a single trial ! * TODO Replace the dataqueue with a pipeline (file) this will make it easier * to emulate the file characteristics of the socket such as blocking and non-blocking * */ PRINT_DEBUG(); if (block_flag == 1) { PRINT_DEBUG(); int value; sem_getvalue(&(jinniSockets[index].Qs), &value); PRINT_DEBUG("uniqID=%llu sem: ind=%d, val=%d", uniqueSockID, index, value); PRINT_DEBUG("block=%d, multi=%d, threads=%d", block_flag, multi_flag, jinniSockets[index].threads); do { sem_wait(&jinniSockets_sem); if (jinniSockets[index].uniqueSockID != uniqueSockID) { PRINT_DEBUG("Socket closed, canceling read block."); sem_post(&jinniSockets_sem); return (0); } sem_wait(&(jinniSockets[index].Qs)); // PRINT_DEBUG(); ff = read_queue(jinniSockets[index].dataQueue); // ff = get_fake_frame(); // PRINT_DEBUG(); if (ff && multi_flag) { PRINT_DEBUG("index=%d threads=%d replies=%d", index, jinniSockets[index].threads, jinniSockets[index].replies); if (jinniSockets[index].replies) { jinniSockets[index].replies--; } else { jinniSockets[index].replies = jinniSockets[index].threads - 1; for (i = 0; i < jinniSockets[index].replies; i++) { PRINT_DEBUG("adding frame copy, threads=%d", jinniSockets[index].threads); ff_copy = (struct finsFrame *) malloc( sizeof(struct finsFrame)); cpy_fins_to_fins(ff_copy, ff); //copies pointers, freeFinsFrame doesn't free pointers if (!write_queue_front(ff_copy, jinniSockets[index].dataQueue)) { ; //error } } } } sem_post(&(jinniSockets[index].Qs)); sem_post(&jinniSockets_sem); } while (ff == NULL); PRINT_DEBUG(); } else { PRINT_DEBUG(); sem_wait(&jinniSockets_sem); if (jinniSockets[index].uniqueSockID != uniqueSockID) { PRINT_DEBUG("Socket closed, canceling read block."); sem_post(&jinniSockets_sem); return (0); } sem_wait(&(jinniSockets[index].Qs)); //ff= read_queue(jinniSockets[index].dataQueue); /** ff = get_fake_frame(); print_finsFrame(ff); */ ff = read_queue(jinniSockets[index].dataQueue); if (ff && multi_flag) { PRINT_DEBUG("index=%d threads=%d replies=%d", index, jinniSockets[index].threads, jinniSockets[index].replies); if (jinniSockets[index].replies) { jinniSockets[index].replies--; } else { jinniSockets[index].replies = jinniSockets[index].threads - 1; for (i = 0; i < jinniSockets[index].replies; i++) { PRINT_DEBUG("adding frame copy, threads=%d", jinniSockets[index].threads); ff_copy = (struct finsFrame *) malloc( sizeof(struct finsFrame)); cpy_fins_to_fins(ff_copy, ff); //copies pointers, freeFinsFrame doesn't free pointers if (!write_queue_front(ff_copy, jinniSockets[index].dataQueue)) { ; //error } } } } sem_post(&(jinniSockets[index].Qs)); sem_post(&jinniSockets_sem); } if (ff == NULL) { //free(ff); return (0); } PRINT_DEBUG("recv'd uniqID=%llu ind=%d", uniqueSockID, index); PRINT_DEBUG("PDU length %d", ff->dataFrame.pduLength); if (metadata_readFromElement(ff->dataFrame.metaData, "portsrc", (uint16_t *) &srcport) == 0) { addr_in->sin_port = 0; } if (metadata_readFromElement(ff->dataFrame.metaData, "ipsrc", (uint32_t *) &srcip) == 0) { addr_in->sin_addr.s_addr = 0; } /** * making sure that the datagram coming from the destination we are connected to it * in case of connection previously done */ sem_wait(&jinniSockets_sem); if (jinniSockets[index].uniqueSockID != uniqueSockID) { PRINT_DEBUG("Socket closed, canceling read block."); sem_post(&jinniSockets_sem); return (0); } PRINT_DEBUG("Rest of read for index=%d.", index); if (jinniSockets[index].connection_status > 0) { if ((srcport != jinniSockets[index].dstport) || (srcip != jinniSockets[index].dst_IP)) { PRINT_DEBUG( "Wrong address, the socket is already connected to another destination"); sem_post(&jinniSockets_sem); return (0); } } sem_post(&jinniSockets_sem); //*buf = (u_char *)malloc(sizeof(ff->dataFrame.pduLength)); //memcpy(*buf,ff->dataFrame.pdu,ff->dataFrame.pduLength); memcpy(buf, ff->dataFrame.pdu, ff->dataFrame.pduLength); *buflen = ff->dataFrame.pduLength; PRINT_DEBUG(); if (symbol == 0) { // address = NULL; PRINT_DEBUG(); // freeFinsFrame(ff); return (1); } PRINT_DEBUG(); addr_in->sin_port = srcport; addr_in->sin_addr.s_addr = srcip; /**TODO Free the finsFrame * This is the final consumer * call finsFrame_free(Struct finsFrame** ff) */ PRINT_DEBUG(); //freeFinsFrame(ff); /** Finally succeeded * */ return (1); } //end of readFrom_fins
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); }