char* CSMS::SendMsg( char* szTranId, char* szTranPwd, char* szRcvNum, char* szSendNum, char* szDate, char* szMsg ) { struct hostent *hp; int n,sock, serv_len; // int t, clnt_len, msglen, sendmsglen; struct sockaddr_in serv_addr; // struct sockaddr_in clnt_addr; server_name = "sms.gabia.com"; char* szRtnMsg = new char[256]; BOOL bResult; clientmsg = get_packet_info( szTranId, szTranPwd, szRcvNum, szSendNum, szDate, szMsg, bResult ); if( !bResult ) return clientmsg; if((hp=gethostbyname(server_name)) == NULL) { strcpy( szRtnMsg, "gethostbyname() failed" ); return szRtnMsg; } serv_len=sizeof(serv_addr); memset((char *)&serv_addr, '\0',serv_len); serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(PORTNUM); memcpy((char *)&serv_addr.sin_addr, hp->h_addr, hp->h_length); if((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0) { strcpy( szRtnMsg, "Socket Error" ); return szRtnMsg; } if(connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <0) { strcpy( szRtnMsg, "Connect Error" ); return szRtnMsg; } if( sendto(sock, clientmsg, strlen(clientmsg), 0,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in)) == -1 ) { strcpy( szRtnMsg, "Send Error" ); closesocket( sock ); return szRtnMsg; } if((n=recv(sock, reply, MAXMSG, 0)) < 0) { strcpy( szRtnMsg, "Receive error" ); closesocket( sock ); return szRtnMsg; } else { sprintf( szRtnMsg, "send to server : %s", clientmsg ); closesocket( sock ); return szRtnMsg; } }
static void handle_packet_in( uint64_t datapath_id, packet_in message ) { if ( !packet_type_ether( message.data ) ) { return; } struct key new_key; packet_info packet_info = get_packet_info( message.data ); memcpy( new_key.mac, packet_info.eth_macsa, OFP_ETH_ALEN ); new_key.datapath_id = datapath_id; hash_table *forwarding_db = message.user_data; learn( forwarding_db, new_key, message.in_port ); struct key search_key; memcpy( search_key.mac, packet_info.eth_macda, OFP_ETH_ALEN ); search_key.datapath_id = datapath_id; forwarding_entry *destination = lookup_hash_entry( forwarding_db, &search_key ); if ( destination == NULL ) { do_flooding( message ); } else { send_packet( destination->port_no, message ); } }
void absent_packet_list::request_failed(seqno_t seqno, timestamp_t now, int reRequestDelay) { absent_packet_info* pktInfo = get_packet_info(seqno); BOOST_ASSERT(pktInfo); if (pktInfo) { pktInfo->request_failed(now, reRequestDelay); not_requesting_packets_.insert(seqno); requesting_packets_.erase(seqno); } }
static void flood_packet( uint64_t datapath_id, uint16_t in_port, uint16_t slice, const buffer *packet, list_element *switches ) { uint16_t in_vid = VLAN_NONE; if ( packet_type_eth_vtag( packet ) ) { packet_info packet_info = get_packet_info( packet ); in_vid = packet_info.vlan_vid; } switch_params params; params.packet = packet; params.in_datapath_id = datapath_id; params.in_port = in_port; params.in_vid = in_vid; params.slice = slice; foreach_switch( switches, send_packet_out_for_each_switch, ¶ms ); }
static void handle_packet_in( uint64_t datapath_id, packet_in message ) { UNUSED( datapath_id ); packet_info packet_info = get_packet_info( message.data ); traffic *db = message.user_data; uint8_t *macsa = packet_info.eth_macsa; uint8_t *macda = packet_info.eth_macda; learn_fdb( db->fdb, macsa, message.in_port ); add_counter( db->counter, macsa, 1, message.data->length ); uint16_t out_port = lookup_fdb( db->fdb, macda ); if ( out_port != ENTRY_NOT_FOUND_IN_FDB ) { send_packet_out( datapath_id, &message, out_port ); send_flow_mod( datapath_id, macsa, macda, out_port ); } else { do_flooding( datapath_id, &message ); } }
void redirect( uint64_t datapath_id, uint16_t in_port, const buffer *data ) { debug( "A message received (dpid = %#" PRIx64 ", in_port = %u, length = %zu).", datapath_id, in_port, data->length ); packet_info packet_info = get_packet_info( data ); if ( !packet_type_ipv4( data ) ) { debug( "Cannot redirect the packet which is not IPv4." ); return; } uint8_t *mac = packet_info.eth_macsa; uint32_t ip = packet_info.ipv4_saddr; add_host( mac, ip, datapath_id, in_port ); debug( "Redirecting an IP packet to tun interface." ); assert( packet_info.l3_header != NULL ); // redirect an IP packet to a tun interface send_packet_to_tun( packet_info.l3_header, packet_info.ipv4_tot_len ); }
static void output_packet( const buffer *packet, uint64_t dpid, uint16_t port_no, uint16_t out_vid ) { openflow_actions *actions = create_actions(); uint16_t in_vid = VLAN_NONE; if ( packet_type_eth_vtag( packet ) ) { packet_info packet_info = get_packet_info( packet ); in_vid = packet_info.vlan_vid; } if ( out_vid != in_vid ) { if ( in_vid != VLAN_NONE && out_vid == VLAN_NONE ) { append_action_strip_vlan( actions ); } else { append_action_set_vlan_vid( actions, out_vid ); } } const uint16_t max_len = UINT16_MAX; append_action_output( actions, port_no, max_len ); send_packet_out( dpid, actions, packet ); delete_actions( actions ); }
static void handle_packet_in( uint64_t datapath_id, packet_in message ) { known_switch *sw = lookup_hash_entry( message.user_data, &datapath_id ); if ( sw == NULL ) { warn( "Unknown switch (datapath ID = %#" PRIx64 ")", datapath_id ); return; } packet_info packet_info = get_packet_info( message.data ); learn( sw->forwarding_db, message.in_port, packet_info.eth_macsa ); forwarding_entry *destination = lookup_hash_entry( sw->forwarding_db, packet_info.eth_macda ); if ( destination == NULL ) { do_flooding( message ); } else { send_packet( destination->port_no, message ); } }
int main(int argc, char **argv) { int n,sockfd, on=1,i,j,maxfdp,optval=1; char recvline[LINE_MAX], in_packet[PACKET_LEN]; client_config_t config; int num_ifi = 0; pthread_t tid; thread_arg* arg; bool done = FALSE, is_probe = FALSE, is_error = FALSE; unsigned int ack_seq, seq, timestamp; unsigned short curr_win; circ_buffer_t rcv_buffer; ifi_t *ifi_array[IFI_MAX]; read_client_config("client.in", &config); print_client_config(&config); num_ifi = get_ifi(ifi_array); print_ifi(ifi_array, num_ifi); srand(config.seed); init_circular_buffer(&rcv_buffer, config.window_size); rtt_init(&rttinfo); if (connection_setup(&sockfd, ifi_array, num_ifi, &rcv_buffer, &config) < 0) err_sys("[Error] Connection Setup Error, Terminating..\n"); /* TODO: Recv ACK and connect to the new port */ arg = (thread_arg*)calloc(1, sizeof(thread_arg)); arg->rcv_buf = &rcv_buffer; arg->config = &config; arg->sockfd = sockfd; Pthread_create(&tid, NULL, &consumer_thread, arg); /* Below is the Producer Logic which reads from the socket and fills * up the receive Buffer. */ while (!done) { if ((n = read(sockfd, in_packet, PACKET_LEN)) < 0) { if (errno == EINTR) continue; else err_sys("[Error] Unknown Read Error"); } packet_info_t *pkt_info = get_packet_info(in_packet, n); if (!IS_DATA(pkt_info) && !(is_probe = IS_PROBE(pkt_info)) && !(is_error = IS_ERR(pkt_info))) { free_pkt_info(pkt_info); continue; } if (consume_random_packet(pkt_info, config.prob_loss, TRUE)) { free_pkt_info(pkt_info); continue; } if(IS_EOF(pkt_info) || is_error) done = TRUE; Pthread_mutex_lock(&buf_mutex); /* Special Handling for Probes & Errors, send an ACK, don't store in buffer */ if(!is_probe && !is_error) { write_to_buffer(&rcv_buffer , pkt_info); } /* Save off these values as we are releasing the lock below */ curr_win = window_size(&rcv_buffer); ack_seq = NEXT_ACK(&rcv_buffer); seq = pkt_info->seq; timestamp = pkt_info->timestamp; Pthread_mutex_unlock(&buf_mutex); if(is_probe) printf("[Info] Persist Timer Response [Ack:%u] [Window Size:%hu]\n", ack_seq, curr_win); else printf("[Info] Received [Seq: %u] Responding with [Ack:%u] [Window Size:%hu]\n", seq, ack_seq, curr_win); send_ack(sockfd, curr_win, seq, ack_seq, timestamp, config.prob_loss); } pthread_exit(NULL); }
/* This routine does the first phase of the client-server Setup. * On successfule return, the out parameter sockfd will have the * connection socket fd. * */ int connection_setup(int *sockfd, ifi_t *ifi_array[], int num_ifi, circ_buffer_t *rcv_buf, client_config_t *config) { packet_t *send_pkt; int n, optval=1; char in_packet[PACKET_LEN],client_ip[IP_MAX]; struct sockaddr_in serv_addr, cliaddr, tempaddr; unsigned int ack_seq; unsigned short curr_win; bool is_error = FALSE; packet_info_t *rcv_pkt_info, *send_pkt_info = calloc(1, sizeof(packet_info_t)); *sockfd = Socket(AF_INET, SOCK_DGRAM, 0); if(server_on_same_subnet(config->server_ip,ifi_array, num_ifi, client_ip)) { printf("server on same subnet, SO_DONTROUTE set\n"); //printf("client ip set to: %s\n",client_ip); setsockopt(*sockfd,SOL_SOCKET, SO_DONTROUTE, &optval, sizeof(optval)); } //update cli_ip after if it's on the same host or n/w bzero(&cliaddr, sizeof(cliaddr)); cliaddr.sin_family = AF_INET; cliaddr.sin_port = 0; inet_pton(AF_INET,client_ip,&cliaddr.sin_addr); Bind(*sockfd, (SA*) &cliaddr, sizeof(cliaddr)); //cli addr and port using getsockname int cli_port; char cli_ip[IP_MAX]; socklen_t len = sizeof(tempaddr); bzero(&tempaddr, sizeof(tempaddr)); getsockname(*sockfd, (SA*) &tempaddr, &len); Inet_ntop(AF_INET, &tempaddr.sin_addr, cli_ip, IP_MAX); printf("[Info]client bound to ip:%s\n",cli_ip); cli_port = ntohs(tempaddr.sin_port); //connect bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(config->server_port); Inet_pton(AF_INET, config->server_ip, &serv_addr.sin_addr); Connect(*sockfd, (SA *)&serv_addr, sizeof(serv_addr)); assert(send_pkt_info); Signal(SIGALRM, sig_alarm); rtt_newpack(&rttinfo); /* initialize for this packet */ /* Prepare to send file name */ send_pkt_info->seq = 0; send_pkt_info->ack = 0; send_pkt_info->window_size = config->window_size; SET_FILE_FLAG(send_pkt_info); send_pkt_info->data = strdup(config->file_name); send_pkt_info->data_len = strlen(config->file_name) + 1; printf("[Info] Sending file name %s to server ..\n", send_pkt_info->data); sendagain: send_pkt_info->timestamp = rtt_ts(&rttinfo); send_pkt = build_packet(send_pkt_info); Write(*sockfd, (char *)send_pkt, send_pkt_info->data_len+HEADER_SIZE); /* set alarm for RTO seconds using setitimer */ set_alarm(rtt_start(&rttinfo)); if (sigsetjmp(jmpbuf, 1) != 0) { if (rtt_timeout(&rttinfo)) { printf("[Error] Timed out Sending File Name, giving Up\n"); free_pkt_info(send_pkt_info); free(send_pkt); errno = ETIMEDOUT; return -1; } printf("[Timeout] Retransmitting file name, next RTO:%d ms\n", rttinfo.rtt_rto); free(send_pkt); goto sendagain; } /* Now Attempt to read the Port message from the Server */ while (1) { if ((n = read(*sockfd, in_packet, PACKET_LEN)) < 0) { if (errno == EINTR) continue; else err_sys("[Error] Read Error while waiting for Port number"); } rcv_pkt_info = get_packet_info(in_packet, n); if (consume_random_packet(rcv_pkt_info, config->prob_loss, TRUE)) { free_pkt_info(rcv_pkt_info); continue; } if (IS_ACK(rcv_pkt_info) && (rcv_pkt_info->ack == (send_pkt_info->seq+1))) { break; } else { free_pkt_info(rcv_pkt_info); continue; } } set_alarm(0); /* Turn off the Alarm */ free_pkt_info(send_pkt_info); free(send_pkt); assert(rcv_pkt_info->data_len == sizeof(short)); /* Fetch the new port from the server message */ memcpy(&serv_addr.sin_port, rcv_pkt_info->data, sizeof(short)); printf("[Info] Received new Port number %hu from Server.\n", ntohs(serv_addr.sin_port)); /* Connect to the new port of the server child process */ if (connect(*sockfd, (SA *)&serv_addr, sizeof(serv_addr)) < 0) { printf("[Error] Connect failure to server child: [%s : %hu]\n", config->server_ip, ntohs(serv_addr.sin_port)); return -1; } printf("[Info] Connected to server's child process.\n"); /* Advance the Circular buffer's read/write pointers to rcv_pkt_info->seq+1. * Basically, we are simulating the producer/consumer behavior here, in that we * have written and read from the buffer. * Note: The server has to continue the file transfer starting from rcv_pkt_info->seq+1 * as we will not accept anything lower than this sequence for this session * This is similar to the SYN+ACK in TCP */ rcv_buf->next_read_seq = rcv_buf->next_contig_write_seq = rcv_pkt_info->seq+1; printf("rcv_buf->next_read_seq = rcv_buf->next_contig_write_seq = %u", rcv_pkt_info->seq+1); curr_win = window_size(rcv_buf); ack_seq = NEXT_ACK(rcv_buf); /* Exit if the file does not exist on the server after sending ACK. * In the event this ACK is lost, the server ichild timeout mechanism will kick in * and eventually it will timeout and give up */ if(is_error = IS_ERR(rcv_pkt_info)) { printf("[Info] Received Error message from server [Seq: %u] Responding with [Ack:%u] [Window Size:%hu]\n", rcv_pkt_info->seq, ack_seq, curr_win); } else { printf("[Info] Received Port message [Seq: %u] Responding with [Ack:%u] [Window Size:%hu]\n", rcv_pkt_info->seq, ack_seq, curr_win); } /* Simulate Loss On Tx */ if (!consume_random_packet(rcv_pkt_info, config->prob_loss, FALSE)) { send_ack(*sockfd, curr_win, rcv_pkt_info->seq, ack_seq, rcv_pkt_info->timestamp, config->prob_loss); } free_pkt_info(rcv_pkt_info); if(is_error) { printf("[Error] File %s does not exist, terminating..\n", config->file_name); errno = EBADF; return -1; } printf("[Info] Successful Connection Setup with [%s:%u], ready for file reception\n", config->server_ip, ntohs(serv_addr.sin_port)); return 0; }
void tcp_data_handler::on_read(int fd) { do { int recv_len = recv(fd,m_rbuf.space(),m_rbuf.space_size(),0) ; if(recv_len >0) { m_rbuf.push_data(recv_len) ; while(m_rbuf.data_size() > 0) { packet_info pi = {0} ; int ret = 0 ; if((ret=get_packet_info(m_rbuf.data(),m_rbuf.data_size(),&pi))!=0) { handle_error(ret); return ; } if( pi.size < 1 || pi.size > 4194304 ) { handle_error(ERROR_TYPE_REQUEST) ; return ; } if(m_rbuf.data_size() >= pi.size ) { if((ret=process_packet(&pi)) !=0 ) { handle_error(ret) ; return ; } m_rbuf.pop_data(pi.size) ; } else { if(m_rbuf.space_size() < pi.size - m_rbuf.data_size()) { if(m_rbuf.resize(m_rbuf.capacity() + pi.size )!=0) { handle_error(ERROR_TYPE_MEMORY) ; return ; } } break ; } } m_rbuf.adjust() ; } else if(recv_len == 0) { //peer close handle_error(ERROR_TYPE_PEER_CLOSE) ; return ; } else { if (errno != EAGAIN && errno != EINTR) { handle_error(ERROR_TYPE_SYSTEM) ; return ; } break ; } }while(m_options & OPTION_READALL) ; }
static bool if_packet_type( const buffer *frame, const uint32_t type ) { die_if_NULL( frame ); packet_info packet_info = get_packet_info( frame ); return ( ( packet_info.format & type ) == type ); }
static bool if_igmp_type( const buffer *frame, const uint32_t type ) { die_if_NULL( frame ); packet_info packet_info = get_packet_info( frame ); return ( packet_info.igmp_type == type ); }
static bool if_arp_opcode( const buffer *frame, const uint32_t opcode ) { die_if_NULL( frame ); packet_info packet_info = get_packet_info( frame ); return ( packet_info.arp_ar_op == opcode ); }
static void handle_packet_in( uint64_t datapath_id, uint32_t transaction_id, uint32_t buffer_id, uint16_t total_len, uint16_t in_port, uint8_t reason, const buffer *data, void *user_data ) { assert( in_port != 0 ); assert( data != NULL ); assert( user_data != NULL ); routing_switch *routing_switch = user_data; debug( "Packet-In received ( datapath_id = %#" PRIx64 ", transaction_id = %#lx, " "buffer_id = %#lx, total_len = %u, in_port = %u, reason = %#x, " "data_len = %u ).", datapath_id, transaction_id, buffer_id, total_len, in_port, reason, data->length ); const port_info *port = lookup_port( routing_switch->switches, datapath_id, in_port ); if ( port == NULL ) { debug( "Ignoring Packet-In from unknown port." ); return; } packet_info packet_info = get_packet_info( data ); const uint8_t *src = packet_info.eth_macsa; const uint8_t *dst = packet_info.eth_macda; if ( in_port > OFPP_MAX && in_port != OFPP_LOCAL ) { error( "Packet-In from invalid port ( in_port = %u ).", in_port ); return; } if ( !port->external_link || port->switch_to_switch_reverse_link ) { if ( !port->external_link && port->switch_to_switch_link && port->switch_to_switch_reverse_link && !is_ether_multicast( dst ) && lookup_fdb( routing_switch->fdb, src, &datapath_id, &in_port ) ) { debug( "Found a Packet-In from switch-to-switch link." ); } else { debug( "Ignoring Packet-In from not external link." ); return; } } if ( !update_fdb( routing_switch->fdb, src, datapath_id, in_port ) ) { return; } if ( !authenticate( src ) ) { if ( packet_type_ipv4( data ) ) { if ( packet_type_ipv4_udp( data ) ) { if ( ( packet_info.udp_src_port == 67 ) || ( packet_info.udp_src_port == 68 ) || ( packet_info.udp_dst_port == 67 ) || ( packet_info.udp_dst_port == 68 ) ) { // DHCP/BOOTP is allowed by default goto authenticated; } if ( ( packet_info.udp_src_port == 53 ) || ( packet_info.udp_dst_port == 53 ) ) { // DNS is allowed by default goto authenticated; } } else if ( packet_type_ipv4_tcp( data ) ) { if ( ( packet_info.tcp_src_port == 53 ) || ( packet_info.tcp_dst_port == 53 ) ) { // DNS is allowed by default goto authenticated; } } redirect( datapath_id, in_port, data ); } else if ( packet_type_arp( data ) ) { // ARP request/reply is allowed goto authenticated; } return; } authenticated: { uint16_t out_port; uint64_t out_datapath_id; if ( lookup_fdb( routing_switch->fdb, dst, &out_datapath_id, &out_port ) ) { // Host is located, so resolve path and send flowmod if ( ( datapath_id == out_datapath_id ) && ( in_port == out_port ) ) { // in and out are same return; } make_path( routing_switch, datapath_id, in_port, out_datapath_id, out_port, data ); } else { // Host's location is unknown, so flood packet flood_packet( datapath_id, in_port, data, routing_switch->switches ); } } }
void radiotap(unsigned char* data, int rd) { struct ieee80211_radiotap_header* rth; struct ieee80211_frame* wh; char* body; struct node_info node; int8_t signal_dbm, noise_dbm; uint8_t signal_db, noise_db; int dbm = 0; int signal = 0; int i; rd -= 4; // 802.11 CRC // radiotap rth = (struct ieee80211_radiotap_header*) data; // 802.11 wh = (struct ieee80211_frame*) ((char*)rth + rth->it_len); rd -= rth->it_len; assert (rd >= 0); // body body = (char*) wh + sizeof(*wh); rd -= sizeof(*wh); if (!get_packet_info(wh, body, rd, &node)) return; // signal and noise body = (char*) rth + sizeof(*rth); signal_dbm = noise_dbm = signal_db = noise_db = 0; for (i = IEEE80211_RADIOTAP_TSFT; i <= IEEE80211_RADIOTAP_EXT; i++) { if (!(rth->it_present & (1 << i))) continue; switch (i) { case IEEE80211_RADIOTAP_TSFT: body += sizeof(uint64_t); break; case IEEE80211_RADIOTAP_FLAGS: case IEEE80211_RADIOTAP_RATE: body += sizeof(uint8_t); break; case IEEE80211_RADIOTAP_CHANNEL: body += sizeof(uint16_t)*2; break; case IEEE80211_RADIOTAP_FHSS: body += sizeof(uint16_t); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: signal_dbm = *body; body++; dbm = 1; break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: noise_dbm = *body; body++; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: signal_db = *((unsigned char*)body); body++; break; case IEEE80211_RADIOTAP_DB_ANTNOISE: noise_db = *((unsigned char*)body); body++; break; case IEEE80211_RADIOTAP_EXT: abort(); break; } } if (dbm) { signal = signal_dbm - noise_dbm; } else { signal = signal_db - noise_db; } if (signal < 0) signal = 0; node.signal = signal; #if 0 if (node.signal > 100 || node.signal < 0) { mvprintw(25,25, "sig=%d", node.signal); } #else assert (node.signal <= 100 && node.signal >= 0); #endif update_node(&node); }
static void handle_packet_in( uint64_t datapath_id, uint32_t transaction_id, uint32_t buffer_id, uint16_t total_len, uint16_t in_port, uint8_t reason, const buffer *data, void *user_data ) { assert( in_port != 0 ); assert( data != NULL ); assert( user_data != NULL ); sliceable_switch *sliceable_switch = user_data; debug( "Packet-In received ( datapath_id = %#" PRIx64 ", transaction_id = %#lx, " "buffer_id = %#lx, total_len = %u, in_port = %u, reason = %#x, " "data_len = %u ).", datapath_id, transaction_id, buffer_id, total_len, in_port, reason, data->length ); if ( in_port > OFPP_MAX && in_port != OFPP_LOCAL ) { error( "Packet-In from invalid port ( in_port = %u ).", in_port ); return; } const port_info *port = lookup_port( sliceable_switch->switches, datapath_id, in_port ); if ( port == NULL ) { debug( "Ignoring Packet-In from unknown port." ); return; } packet_info packet_info = get_packet_info( data ); const uint8_t *src = packet_info.eth_macsa; const uint8_t *dst = packet_info.eth_macda; if ( !port->external_link || port->switch_to_switch_reverse_link ) { if ( !port->external_link && port->switch_to_switch_link && port->switch_to_switch_reverse_link && !is_ether_multicast( dst ) && lookup_fdb( sliceable_switch->fdb, src, &datapath_id, &in_port ) ) { debug( "Found a Packet-In from switch-to-switch link." ); } else { debug( "Ignoring Packet-In from non-external link." ); return; } } uint16_t vid = VLAN_NONE; if ( packet_type_eth_vtag( data ) ) { vid = packet_info.vlan_vid; } if ( !update_fdb( sliceable_switch->fdb, src, datapath_id, in_port ) ) { return; } char match_str[ 1024 ]; struct ofp_match match; set_match_from_packet( &match, in_port, 0, data ); match_to_string( &match, match_str, sizeof( match_str ) ); uint16_t slice = lookup_slice( datapath_id, in_port, vid, src ); if ( slice == SLICE_NOT_FOUND ) { warn( "No slice found ( dpid = %#" PRIx64 ", vid = %u, match = [%s] ).", datapath_id, vid, match_str ); goto deny; } int action = filter( datapath_id, in_port, slice, data ); switch ( action ) { case ALLOW: debug( "Filter: ALLOW ( dpid = %#" PRIx64 ", slice = %#x, match = [%s] ).", datapath_id, slice, match_str ); goto allow; case DENY: debug( "Filter: DENY ( dpid = %#" PRIx64 ", slice = %#x, match = [%s] ).", datapath_id, slice, match_str ); goto deny; case LOCAL: debug( "Filter: LOCAL ( dpid = %#" PRIx64 ", slice = %#x, match = [%s] ).", datapath_id, slice, match_str ); goto local; default: error( "Undefined filter action ( action = %#x ).", action ); goto deny; } allow: { uint16_t out_port; uint64_t out_datapath_id; if ( lookup_fdb( sliceable_switch->fdb, dst, &out_datapath_id, &out_port ) ) { // Host is located, so resolve path and send flowmod if ( ( datapath_id == out_datapath_id ) && ( in_port == out_port ) ) { debug( "Input port and out port are the same ( datapath_id = %#llx, port = %u ).", datapath_id, in_port ); return; } uint16_t out_vid = vid; bool found = get_port_vid( slice, out_datapath_id, out_port, &out_vid ); if ( found == false ) { uint16_t out_slice = lookup_slice_by_mac( dst ); if ( out_slice != slice ) { debug( "Destination is on different slice ( slice = %#x, out_slice = %#x ).", slice, out_slice ); goto deny; } } make_path( sliceable_switch, datapath_id, in_port, vid, out_datapath_id, out_port, out_vid, data ); } else { if ( lookup_path( datapath_id, match, PRIORITY ) != NULL ) { teardown_path( datapath_id, match, PRIORITY ); } // Host's location is unknown, so flood packet flood_packet( datapath_id, in_port, slice, data, sliceable_switch->switches ); } return; } deny: { // Drop packets for a certain period buffer *flow_mod = create_flow_mod( transaction_id, match, get_cookie(), OFPFC_ADD, 0, FLOW_TIMER, UINT16_MAX, UINT32_MAX, OFPP_NONE, 0, NULL ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); return; } local: { // Redirect to controller's local IP stack redirect( datapath_id, in_port, data ); return; } }
static void handle_packet_in( uint64_t datapath_id, uint32_t transaction_id, uint32_t buffer_id, uint16_t total_len, uint16_t in_port, uint8_t reason, const buffer *data, void *user_data ) { assert( in_port != 0 ); assert( data != NULL ); assert( user_data != NULL ); routing_switch *routing_switch = user_data; debug( "Packet-In received ( datapath_id = %#" PRIx64 ", transaction_id = %#lx, " "buffer_id = %#lx, total_len = %u, in_port = %u, reason = %#x, " "data_len = %u ).", datapath_id, transaction_id, buffer_id, total_len, in_port, reason, data->length ); const port_info *port = lookup_port( routing_switch->switches, datapath_id, in_port ); if ( port == NULL ) { debug( "Ignoring Packet-In from unknown port." ); return; } packet_info packet_info = get_packet_info( data ); const uint8_t *src = packet_info.eth_macsa; const uint8_t *dst = packet_info.eth_macda; if ( in_port > OFPP_MAX && in_port != OFPP_LOCAL ) { error( "Packet-In from invalid port ( in_port = %u ).", in_port ); return; } if ( !port->external_link || port->switch_to_switch_reverse_link ) { if ( !port->external_link && port->switch_to_switch_link && port->switch_to_switch_reverse_link && !is_ether_multicast( dst ) && lookup_fdb( routing_switch->fdb, src, &datapath_id, &in_port ) ) { debug( "Found a Packet-In from switch-to-switch link." ); } else { debug( "Ignoring Packet-In from non-external link." ); return; } } if ( !update_fdb( routing_switch->fdb, src, datapath_id, in_port ) ) { return; } uint16_t out_port; uint64_t out_datapath_id; if ( lookup_fdb( routing_switch->fdb, dst, &out_datapath_id, &out_port ) ) { if ( ( datapath_id == out_datapath_id ) && ( in_port == out_port ) ) { // in and out are same return; } // Host is located, so resolve path and install flow entries make_path( routing_switch, datapath_id, in_port, out_datapath_id, out_port, data ); } else { // Host's location is unknown, so flood packet flood_packet( datapath_id, in_port, data, routing_switch->switches ); } }