Exemple #1
0
void sr_add_interface(struct sr_instance* sr, const char* name)
{
    struct sr_vns_if* if_walker = 0;
    
    /* -- REQUIRES -- */
    assert(name);
    assert(sr);
    struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);

    /* -- empty list special case -- */
    if(sub->if_list == 0)
    {
        sub->if_list = (struct sr_vns_if*)malloc(sizeof(struct sr_vns_if));
        assert(sub->if_list);
        sub->if_list->next = 0;
        strncpy(sub->if_list->name,name,SR_NAMELEN);
        return;
    }

    /* -- find the end of the list -- */
    if_walker = sub->if_list;
    while(if_walker->next)
    {if_walker = if_walker->next; }

    if_walker->next = (struct sr_vns_if*)malloc(sizeof(struct sr_vns_if));
    assert(if_walker->next);
    if_walker = if_walker->next;
    strncpy(if_walker->name,name,SR_NAMELEN);
    if_walker->next = 0;
} /* -- sr_add_interface -- */ 
int sr_cpu_output(struct sr_instance* sr /* borrowed */,
		  uint8_t* buf /* borrowed */ ,
		  unsigned int len,
		  const char* iface /* borrowed */)
{
	/* REQUIRES */
	assert(sr);
	assert(buf);
	assert(iface);
	
	fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
	fprintf(stderr, "!!! sr_cpu_output(..) (sr_cpu_extension_nf2.c) called while running in cpu mode !!!\n");
	fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
	
	router_t* router = sr_get_subsystem(sr);
	int written_length = 0;
	int i = 0;
	
	/* log the packet */
// 	pthread_mutex_lock(rs->log_dumper_mutex);//TODO: lock
	sr_log_packet(sr, buf, len);
// 	pthread_mutex_unlock(rs->log_dumper_mutex);
	
	
	char* internal_names[4] = {"eth0", "eth1", "eth2", "eth3"};
	for (i = 0; i < 4; ++i) {
		if (strcmp(iface, internal_names[i]) == 0) {
			break;
		}
	}
	
	/* setup select */
	fd_set write_set;
	FD_ZERO(&write_set);
	
	while (written_length < len) {
		FD_SET(router->sockfd[i], &write_set);
		
// 		struct timeval t;
// 		t.tv_sec = 0;
// 		t.tv_usec = 500; // timeout every half a millisecond
		
		if (select(router->sockfd[i]+1, NULL, &write_set, NULL, NULL) < 0) {
			perror("select");
			exit(1);
		}
		
		if (FD_ISSET(router->sockfd[i], &write_set)) {
			int w = 0;
			if ((w = write(router->sockfd[i], &buf[written_length], len - written_length)) == -1) {
				perror("write");
				exit(1);
			}
			written_length += w;
		}
	}
	
	/* Return the length of the packet on success, -1 on failure */
	return len;
} /* -- sr_cpu_output -- */
Exemple #3
0
void sr_integ_input(struct sr_instance* sr,
        const uint8_t * packet/* borrowed */,
        unsigned int len,
        const char* interface/* borrowed */)
{
    /* -- INTEGRATION PACKET ENTRY POINT!-- */

    printf(" ** sr_integ_input(..) called \n");
    // get global router instance
    struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(sr);
    // get interface object for this interface name
    interface_t *intf = get_interface_name(subsystem, interface);
    printf(" ********************* new packet received with length %u on interface: %s\n", len, intf->name);
    // check if interface is active
    if(intf->enabled == TRUE) {
       // create a copy of the packet
       uint8_t* packet_copy = (uint8_t*) malloc_or_die(len);
       memcpy(packet_copy, packet, len);
       // send to ethernet frame handler
       ethernet_handle_frame(subsystem, packet_copy, len, intf);
    } else  {
       printf(" ** sr_integ_input(..): interface: %s is down. Dropping packet\n", intf->name);
    }

} /* -- sr_integ_input -- */
Exemple #4
0
void sr_integ_hw_setup(struct sr_instance* sr)
{
    printf(" ** sr_integ_hw(..) called \n");
    struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(sr);
    printf(" ** sr_integ_hw(..) adding entries to static rtable \n");
    // read rtable file
    sr_load_rt(sr, sr->rtable);
    // add static entries to routing table
    printf(" ** sr_integ_hw(..) initial state of routing table\n");
    llist_display_all(subsystem->rtable->rtable_list, display_route_t);
    // set link state info
    uint32_t area_id = PWOSPF_AREA_ID;
    uint16_t lsuint = PWOSPF_LSU_INTERVAL;
    set_ls_info_id(subsystem, area_id, lsuint);
    // get hardware fds for each hw interface
    #ifdef _CPUMODE_
    sr_cpu_init_interface_socket(subsystem);
    #endif
     // initialize neighbor db
    neighbor_db_init(subsystem);
    // display initial state of neighbor db
    printf(" ** sr_integ_hw(..) initial state of neighbor db\n");
    display_neighbor_vertices(subsystem);
    // initialize pwospf
    pwospf_init(subsystem);
} /* -- sr_integ_hw_setup -- */
Exemple #5
0
void pwospf_flood_lsu(struct ip* ip_header, pwospf_header_t* pwospf_header, pwospf_lsu_packet_t* lsu_packet, neighbor_t* sending_neighbor, interface_t* intf) {
   printf(" ** pwospf_flood_lsu(..) called\n");
   // decrement ttl
   uint16_t ttl = 0;
   ttl = htons(lsu_packet->ttl);
   ttl = ttl - 1;
   ttl = ntohs(ttl);
   lsu_packet->ttl = ttl;
   pwospf_header->checksum = 0;
   uint16_t pwospf_packet_len = pwospf_header->len;
   // correct order
   pwospf_header->len = htons(pwospf_header->len);
   // generate raw packet 
   byte* pwospf_packet = (byte*) malloc_or_die(pwospf_packet_len);
   memcpy(pwospf_packet, pwospf_header, sizeof(pwospf_header_t));
   memcpy(pwospf_packet + sizeof(pwospf_header_t), lsu_packet, pwospf_packet_len - sizeof(pwospf_header_t));
   printf(" ** pwospf_flood_lsu(..) pwospf packet with len %u generated \n", pwospf_packet_len);
   // generate checksum
   pwospf_header->checksum = htons(htons(inet_chksum((void*) pwospf_packet, pwospf_packet_len)));
   memcpy(pwospf_packet, pwospf_header, sizeof(pwospf_header_t));
   // check if ttl expired
   if(lsu_packet->ttl < 1) {
      printf(" ** pwospf_flood_lsu(..) ttl expired, not flooding\n");
   } else {
      // get instance of router 
      struct sr_instance* sr_inst = get_sr();
      struct sr_router* router = (struct sr_router*)sr_get_subsystem(sr_inst);
      node* first = NULL;
      neighbor_t* neighbor = NULL;
      int i;
      // now iterate through each interface
      for( i = 0; i < router->num_interfaces ; i++) {
         // now iterate this interface's neighbors list
         first = router->interface[i].neighbor_list;
         pthread_mutex_lock(&router->interface[i].neighbor_lock);
         while(first != NULL) {
            // get neighbor
            neighbor = (neighbor_t*) first->data;
            if(neighbor != NULL) {
               // ensure that the sending neighbour is excluded
               if(neighbor->id != sending_neighbor->id) {
                  byte* ip_packet = (byte*) malloc_or_die(ip_header->ip_len);
                  ip_header->ip_dst.s_addr = neighbor->ip;
                  ip_header->ip_len = htons((ip_header->ip_len));
                  ip_header->ip_off = htons((ip_header->ip_off));
                  ip_header->ip_id = htons((ip_header->ip_id));
                  ip_header->ip_sum = htons((ip_header->ip_sum));
                  memcpy(ip_packet, ip_header, ip_header->ip_hl * 4);
                  memcpy(ip_packet + ip_header->ip_hl * 4, pwospf_packet, pwospf_packet_len);
                  ip_look_up_reply(ip_packet, ip_header, intf);
               }

            }  
          first = first->next;
         }
          pthread_mutex_unlock(&router->interface[i].neighbor_lock);
      }
   }
}
Exemple #6
0
void ip_look_up_reply(byte* ip_packet, struct ip* ip_header, interface_t* intf) {
   printf(" ** ip_lookup_reply(..) called \n");
   // get ptr to global router instance
   struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(get_sr());
   // get dst ip object
   addr_ip_t dst_ip;
   memcpy(&dst_ip, &ip_header->ip_dst, 4);
   // look up in routing table
   route_info_t route_info = rrtable_find_route(subsystem->rtable, dst_ip);
   if(route_info.intf == NULL) {
      printf(" ** ip_lookup_reply(..)  Error! No route found \n");
   } else {
   // display output interface
   printf(" ** ip_lookup_reply(..) output interface for ip: %s\n", quick_ip_to_string(dst_ip));
   display_interface(route_info.intf);
      // check if destination same as ip of the source interface and packet didn't originate from one of my interfaces
   if(strcmp(route_info.intf->name, intf->name) == 0 && check_packet_source(ip_header->ip_src, subsystem) == FALSE) {
      printf(" ** make_ip_packet_reply(..) error! destination interface same as source \n");
     // send icmp destination host unreachable
     uint8_t code = ICMP_TYPE_CODE_DST_UNREACH_HOST;
     // reverse order
     ip_header->ip_len = ntohs((ip_header->ip_len));
     ip_header->ip_off = ntohs((ip_header->ip_off));
     ip_header->ip_id = ntohs((ip_header->ip_id));
     ip_header->ip_sum = ntohs((ip_header->ip_sum));
     uint16_t packet_len = ip_header->ip_len;
     icmp_type_dst_unreach_send(&code, ip_packet, &packet_len, ip_header);
   } else {
      // check if ttl expired
      if(ip_header->ip_ttl == 1) {
         printf(" ** ip_lookup_reply(..) ttl expired, sending ICMP ttl error message \n");
         // reverse order
         ip_header->ip_len = ntohs((ip_header->ip_len));
         ip_header->ip_off = ntohs((ip_header->ip_off));
         ip_header->ip_id = ntohs((ip_header->ip_id));
         ip_header->ip_sum = ntohs((ip_header->ip_sum));
         uint8_t code = ICMP_TYPE_CODE_TTL_TRANSIT;
         uint16_t len = ip_header->ip_len;
         icmp_type_ttl_send(&code, ip_packet, &len, ip_header);
      } else {
         printf(" ** ip_lookup_reply(..) decrementing ttl \n");
         // create new ip header
         struct ip* ip_header_ttl = (struct ip*) malloc_or_die(ip_header->ip_hl * 4);
         memcpy(ip_header_ttl, ip_header, ip_header->ip_hl * 4);
         // decrement ttl
         ip_header_ttl->ip_ttl = ip_header_ttl->ip_ttl - 1;
         // generate checksum
         ip_header_ttl->ip_sum = 0;
         ip_header_ttl->ip_sum = htons(htons(inet_chksum((void*)ip_header_ttl, ip_header_ttl->ip_hl * 4)));
         // get payload
         uint16_t payload_len = ntohs(ip_header_ttl->ip_len) - (ip_header_ttl->ip_hl * 4);
         printf(" ** ip_lookup_reply(..) Payload size %u bytes \n", payload_len);
         memcpy(ip_packet, ip_header_ttl, ip_header_ttl->ip_hl * 4);
         // make new ip packet
         send_ip_packet(ip_packet, ip_header_ttl, route_info);
      }
   }
   }
}
Exemple #7
0
void sr_integ_hw_setup(struct sr_instance* sr)
{
    printf(" ** sr_integ_hw(..) called \n");

	/* Get router subsystem */
	struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);

	sr_load_rt(sub,const char*);
	
} /* -- sr_integ_hw_setup -- */
Exemple #8
0
void sr_integ_add_interface(struct sr_instance* sr,
                            struct sr_vns_if* vns_if/* borrowed */)
{
    printf(" ** sr_integ_add_interface(..) called \n");
	/* Get router subsystem */
	struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);
	
	/* Add the interface to our internal router state */
	sr_add_iface_from_vns(sub, vns_if);
	
} /* -- sr_integ_add_interface -- */
Exemple #9
0
void sr_integ_add_interface(struct sr_instance* sr,
                            struct sr_vns_if* vns_if/* borrowed */)
{
    printf(" ** sr_integ_add_interface(..) called \n");
    struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(sr);
    subsystem->interface[subsystem->num_interfaces] = set_interface(vns_if, subsystem->num_interfaces);
#ifdef _CPUMODE_
    write_interface_hw(subsystem);
#endif
    subsystem->num_interfaces = subsystem->num_interfaces + 1;
    printf(" ** sr_integ_add_interface(..) current no. of interfaces: %u\n", subsystem->num_interfaces);
    
} /* -- sr_integ_add_interface -- */
Exemple #10
0
void sr_set_ether_addr(struct sr_instance* sr, const unsigned char* addr)
{
    struct sr_vns_if* if_walker = 0;
   struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);

    /* -- REQUIRES -- */
    assert(sub->if_list);
    
    if_walker = sub->if_list;
    while(if_walker->next)
    {if_walker = if_walker->next; }

    /* -- copy address -- */
    memcpy(if_walker->addr,addr,6);

} /* -- sr_set_ether_addr -- */
Exemple #11
0
void sr_set_ether_ip(struct sr_instance* sr, uint32_t ip_nbo)
{
    struct sr_vns_if* if_walker = 0;
   struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);

    /* -- REQUIRES -- */
    assert(sub->if_list);
    
    if_walker = sub->if_list;
    while(if_walker->next)
    {if_walker = if_walker->next; }

    /* -- copy address -- */
    if_walker->ip = ip_nbo;

} /* -- sr_set_ether_ip -- */
Exemple #12
0
uint32_t sr_integ_findsrcip(uint32_t dest /* nbo */)
{

    /* --
     * e.g.
     *
     * struct sr_instance* sr = sr_get_global_instance();
     * struct my_router* mr = (struct my_router*)
     *                              sr_get_subsystem(sr);
     * return my_findsrcip(mr, dest);
     * -- */
    struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(get_sr());
   // look up in routing table
    route_info_t route_info = rrtable_find_route(subsystem->rtable, dest);

    return route_info.intf->ip;
} /* -- ip_findsrcip -- */
Exemple #13
0
struct sr_vns_if* find_interface(struct sr_instance* sr, uint32_t IP){
   //step through the list trying to find IP, then return name
   struct sr_vns_if* if_walker = 0;
   assert(sr);
   struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);
   assert(sub);
   if_walker = sub->if_list;
   while(if_walker)
   {
         if(if_walker->ip == IP)
            { return if_walker; }
         if_walker = if_walker->next;
   }
              
   return 0;

}
Exemple #14
0
void pwospf_hello_type(struct ip* ip_header, byte* payload, uint16_t payload_len, pwospf_header_t* pwospf_header, interface_t* intf) {
   printf(" ** pwospf_hello_type(..) called \n");
   printf(" ** pwospf_hello_type(..) packet with length: %u \n", payload_len);
   // make hello packet
   pwospf_hello_packet_t* hello_packet = (pwospf_hello_packet_t*) malloc_or_die(sizeof(pwospf_hello_packet_t));
   memcpy(&hello_packet->network_mask, payload, 4);
   memcpy(&hello_packet->helloint, payload + 4, 2);
   memcpy(&hello_packet->padding, payload + 6, 2);
   // display packet
   printf(" ** pwospf_hello_type(..) displayed header contents:\n");
   display_hello_packet(hello_packet);
   // check mask and hello interval
   if(intf->subnet_mask == hello_packet->network_mask && intf->helloint == ntohs(hello_packet->helloint)) {
      printf(" ** pwospf_hello_type(..) network mask and hello interval correct\n");
      // if the interface has no neighbors
      if(intf->neighbor_list == NULL) {
         printf(" ** pwospf_hello_type(..) interface has no neighbors, adding new neighbor\n");
         add_neighbor(intf, pwospf_header->router_id, ip_header->ip_src.s_addr, hello_packet->helloint, hello_packet->network_mask);
      } else { // interface has existing neighbors
         // generate neighbor object
         neighbor_t* neighbor = make_neighbor(pwospf_header->router_id, ip_header->ip_src.s_addr, hello_packet->helloint, hello_packet->network_mask);
         // get last instance so that lsu info can be put back
         pthread_mutex_lock(&intf->neighbor_lock);
         node* ret = llist_find( intf->neighbor_list, predicate_id_neighbor_t,(void*) &pwospf_header->router_id);
         pthread_mutex_unlock(&intf->neighbor_lock);
         if( ret!= NULL) {
            neighbor_t *neighbor_ret = (neighbor_t*) ret->data;
            neighbor->last_adverts = neighbor_ret->last_adverts;
            neighbor->last_lsu_packet = neighbor_ret->last_lsu_packet;
         }
         // lock neighbor list
         pthread_mutex_lock(&intf->neighbor_lock);
         // if exists, then update, otherwise add
         intf->neighbor_list = llist_update_beginning_delete(intf->neighbor_list, predicate_neighbor_t, (void*) neighbor);
         pthread_mutex_unlock(&intf->neighbor_lock);
      }
      // update info in neighbor db
      // get instance of router 
      struct sr_instance* sr_inst = get_sr();
      struct sr_router* router = (struct sr_router*)sr_get_subsystem(sr_inst);
      update_neighbor_vertex_t_rid(router, ip_header->ip_src.s_addr, pwospf_header->router_id);
   } else {
      printf(" ** pwospf_hello_type(..) network mask or hello interval incorrect\n");
   }
}
Exemple #15
0
void send_ip_packet(byte* ip_packet, struct ip* ip_header, route_info_t route_info) {
   printf(" ** send_ip_packet(..) called \n");
   // display generated packet len
   addr_ip_t dst_ip, src_ip;
   memcpy(&dst_ip, &ip_header->ip_dst, 4);   
   memcpy(&src_ip, &ip_header->ip_src, 4);
   if(check_if_local_subnet(dst_ip, src_ip, route_info.intf->subnet_mask) == FALSE) { // non local subnet
      printf(" ** send_ip_packet(..) destination on non-local subnet\n");
      // check if dst directly connected
      if(route_info.ip == 0)
         printf(" ** send_ip_packet(..) destination directly connected\n");
      else
         dst_ip = route_info.ip;
   } else
      printf(" ** send_ip_packet(..) destination on local subnet\n");
   struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(get_sr());
   arp_cache_handle_partial_frame(subsystem, route_info.intf, dst_ip, ip_packet, ntohs(ip_header->ip_len), ETHERTYPE_IP);
}
Exemple #16
0
void ip_look_up(byte* ip_packet, struct ip* ip_header) {
   printf(" ** ip_lookup(..) called \n");
   // get ptr to global router instance
   struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(get_sr());
   // get dst ip object
   addr_ip_t dst_ip;
   memcpy(&dst_ip, &ip_header->ip_dst, 4);
   // look up in routing table
   route_info_t route_info = rrtable_find_route(subsystem->rtable, dst_ip);
   if(route_info.intf == NULL) {
      printf(" ** ip_lookup(..) Error! No route found \n");
   } else {
   // display output interface
   printf(" ** ip_lookup(..) output interface for ip: %s\n", quick_ip_to_string(dst_ip));
   display_interface(route_info.intf);
   // set src ip as the ip of the output interface
   memcpy(&ip_header->ip_src, &route_info.intf->ip, 4);
   memcpy(ip_packet, ip_header, ip_header->ip_hl);
   // check if ttl expired
   if(ip_header->ip_ttl == 1) {
      printf(" ** ip_lookup(..) ttl expired, sending ICMP ttl error message \n");
      uint8_t code = ICMP_TYPE_CODE_TTL_TRANSIT;
      uint16_t len = ntohs(ip_header->ip_len);
      icmp_type_ttl_send(&code, ip_packet, &len, ip_header);
   } else {
      printf(" ** ip_lookup(..) decrementing ttl \n");
      // create new ip header
      struct ip* ip_header_ttl = (struct ip*) malloc_or_die(ip_header->ip_hl * 4);
      memcpy(ip_header_ttl, ip_header, ip_header->ip_hl * 4);
      // decrement ttl
      ip_header_ttl->ip_ttl = ip_header_ttl->ip_ttl - 1;
      // generate checksum
      ip_header_ttl->ip_sum = 0;
      ip_header_ttl->ip_sum = htons(htons(inet_chksum((void*)ip_header_ttl, ip_header_ttl->ip_hl * 4)));
      // get payload
      uint16_t payload_len = ntohs(ip_header_ttl->ip_len) - (ip_header_ttl->ip_hl * 4);
      printf(" ** ip_lookup(..) Payload size %u bytes \n", payload_len);
      memcpy(ip_packet, ip_header_ttl, ip_header_ttl->ip_hl * 4);
      // make new ip packet
      send_ip_packet(ip_packet, ip_header_ttl, route_info);

   }
   }
}
Exemple #17
0
struct sr_vns_if* sr_get_interface(struct sr_instance* sr, const char* name)
{
    struct sr_vns_if* if_walker = 0;

    /* -- REQUIRES -- */
    assert(name);
    assert(sr);
    struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);
    assert(sub);
    if_walker = sub->if_list;
    while(if_walker)
    {
       if(!strncmp(if_walker->name,name,SR_NAMELEN))
        { return if_walker; }
        if_walker = if_walker->next;
    }

    return 0;
} /* -- sr_get_interface -- */
Exemple #18
0
void sr_print_if_list(struct sr_instance* sr)
{
    struct sr_vns_if* if_walker = 0;
   struct sr_router* sub = (struct sr_router*)sr_get_subsystem(sr);

    if(sub->if_list == 0)
    {
        printf(" Interface list empty \n");
        return;
    }

    if_walker = sub->if_list;
    
    sr_print_if(if_walker);
    while(if_walker->next)
    {
        if_walker = if_walker->next; 
        sr_print_if(if_walker);
    }

} /* -- sr_print_if_list -- */
Exemple #19
0
void pwospf_send_lsu() {
    printf(" ** pwospf_send_lsu(..) called\n");
    // get instance of router 
    struct sr_instance* sr_inst = get_sr();
    struct sr_router* router = (struct sr_router*)sr_get_subsystem(sr_inst);    
    int num_adverts = 0;
    byte* ls_adverts = get_ls_adverts_src(router, &num_adverts);
    int i = 0;
    node* first = NULL;
    neighbor_t* neighbor = NULL;
    printf(" ** pwospf_send_lsu(..) number of adverts: %d\n", num_adverts);
    printf(" ** pwospf_send_lsu(..) adverts:\n");
    display_neighbor_vertices_src(router);
    // now create lsu_packet
    pwospf_lsu_packet_t *lsu_packet = (pwospf_lsu_packet_t*) malloc_or_die(sizeof(pwospf_lsu_packet_t));
    //increment lsu sequence
    router->ls_info.lsu_seq = router->ls_info.lsu_seq + 1;
    lsu_packet->seq = htons(router->ls_info.lsu_seq);
    uint16_t ttl = PWOSPF_LSU_TTL;
    lsu_packet->ttl = htons(ttl);
    lsu_packet->no_of_adverts = htonl(num_adverts);
    // calculate length of entire pwospf packet
    uint16_t pwospf_packet_len = sizeof(pwospf_lsu_packet_t) + sizeof(pwospf_header_t) + sizeof(pwospf_ls_advert_t) * num_adverts;
    //make pwospf header
    pwospf_header_t* pwospf_header = (pwospf_header_t*) malloc_or_die(sizeof(pwospf_header_t));
    pwospf_header->version = PWOSPF_VER;
    pwospf_header->type = PWOSPF_TYPE_LSU;
    pwospf_header->len = htons(pwospf_packet_len);
    pwospf_header->router_id = router->ls_info.router_id;
    pwospf_header->area_id = router->ls_info.area_id;
    pwospf_header->checksum = 0;
    pwospf_header->au_type = PWOSPF_AU_TYPE;
    pwospf_header->authentication = PWOSPF_AUTHEN;
    // generate raw packet 
    byte* pwospf_packet = (byte*) malloc_or_die(pwospf_packet_len);
    memcpy(pwospf_packet, pwospf_header, sizeof(pwospf_header_t));
    memcpy(pwospf_packet + sizeof(pwospf_header_t), lsu_packet, sizeof(pwospf_lsu_packet_t));
    memcpy(pwospf_packet + sizeof(pwospf_header_t) + sizeof(pwospf_lsu_packet_t), ls_adverts, sizeof(pwospf_ls_advert_t) * num_adverts);
    // generate checksum
    pwospf_header->checksum = htons(htons(inet_chksum((void*) pwospf_packet, pwospf_packet_len)));
    memcpy(pwospf_packet, pwospf_header, sizeof(pwospf_header_t));
    free(ls_adverts);
    free(lsu_packet);
    free(pwospf_header);
    printf(" ** pwospf_send_lsu(..) pwospf packet with length %u generated\n", pwospf_packet_len);
    // now iterate through each interface
    for( i = 0; i < router->num_interfaces ; i++) {
       // now iterate this interface's neighbors list
       first = router->interface[i].neighbor_list;
       pthread_mutex_lock(&router->interface[i].neighbor_lock);
       while(first != NULL) {
          // get neighbor
          neighbor = (neighbor_t*) first->data;
          if(neighbor != NULL) {
             struct in_addr src, dst;
             src.s_addr = router->interface[i].ip;
             dst.s_addr = neighbor->ip;
             make_ip_packet(pwospf_packet, pwospf_packet_len, dst, src, IP_PROTOCOL_OSPF);
             
          }
          first = first->next;
       }
       pthread_mutex_unlock(&router->interface[i].neighbor_lock);
   }
}
int sr_cpu_input(struct sr_instance* sr)
{
	/* REQUIRES */
	assert(sr);
	
	fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
	fprintf(stderr, "!!!  sr_cpu_input(..) (sr_cpu_extension_nf2.c) called while running in cpu mode     !!!\n");
// 	fprintf(stderr, "!!!  you need to implement this function to read from the hardware                  !!!\n");
	fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
	
	//while (1);
		
	router_t* router = (router_t*) sr_get_subsystem(sr);
	int i;
	char* internal_names[NUM_INTERFACES] = {"eth0", "eth1", "eth2", "eth3"};
	
	/* setup select */
	fd_set read_set;
	FD_ZERO(&read_set);
	int READ_BUF_SIZE = 16384;
	unsigned char readBuf[READ_BUF_SIZE];
	
	while (1) {
		for (i = 0; i < NUM_INTERFACES; ++i) {
			FD_SET(router->sockfd[i], &read_set);
		}
		
// 		struct timeval t;
// 		t.tv_usec = 500; // timeout every half a millisecond
		
		int nfd = array_max(router->sockfd, NUM_INTERFACES) + 1;
		if (select(nfd, &read_set, NULL, NULL, NULL) < 0) {
			perror("select");
			exit(1);
		}
		
		for (i = 0; i < NUM_INTERFACES; ++i) {
			if (FD_ISSET(router->sockfd[i], &read_set)) {
				printf("\n\n Something on %s \n", internal_names[i]);
				// assume each read is a full packet
				int read_bytes = read(router->sockfd[i], readBuf, READ_BUF_SIZE);
				
				/* log packet */
//				pthread_mutex_lock(rs->log_dumper_mutex); //TODO: lock
				sr_log_packet(sr, (unsigned char*)readBuf, read_bytes);
//				pthread_mutex_unlock(rs->log_dumper_mutex);
				
				/* send packet */
				sr_integ_input(sr, readBuf, read_bytes, internal_names[i]);
			}
		}
	}
	
	//assert(0);
	
	/*
	 * TODO: Read packet from the hardware and pass to sr_integ_input(..)
	 *       e.g.
	 *
	 *  sr_integ_input(sr,
	 *          packet,   * lent *
	 *          len,
	 *          "eth2" ); * lent *
	 */
	
	/*
	 * Note: To log incoming packets, use sr_log_packet from sr_dumper.[c,h]
	 */
	
	/* RETURN 1 on success, 0 on failure.
	 * Note: With a 0 result, the router will shut-down
	 */
	return 1;
	
} /* -- sr_cpu_input -- */
Exemple #21
0
void pwospf_lsu_type(struct ip* ip_header, byte* payload, uint16_t payload_len, pwospf_header_t* pwospf_header, interface_t* intf) {
   printf(" ** pwospf_lsu_type(..) called \n");
   printf(" ** pwospf_lsu_type(..) packet with length: %u \n", payload_len);
   struct sr_instance* sr_inst = get_sr();
   struct sr_router* router = (struct sr_router*)sr_get_subsystem(sr_inst);
   // make lsu packet
   pwospf_lsu_packet_t* lsu_packet = (pwospf_lsu_packet_t*) malloc_or_die(sizeof(pwospf_lsu_packet_t));
   memcpy(&lsu_packet->seq, payload, 2);
   memcpy(&lsu_packet->ttl, payload + 2, 2);
   memcpy(&lsu_packet->no_of_adverts, payload + 4, 4);
   // display packet
   printf(" ** pwospf_lsu_type(..) displayed header contents:\n");
   display_lsu_packet(lsu_packet);
   // calculate number of adverts
   int num_adverts = ((payload_len - 8)/sizeof(pwospf_ls_advert_t));
   printf(" ** pwospf_lsu_type(..) number of adverts: %d\n", num_adverts);
   // check if I generated the LSU
   if(pwospf_header->router_id != intf->router_id) {
      // not generated by self
      // check if neighbor ever sent hello packet
       pthread_mutex_lock(&intf->neighbor_lock);
       node* ret = llist_find( intf->neighbor_list, predicate_id_neighbor_t,(void*) &pwospf_header->router_id);
       pthread_mutex_unlock(&intf->neighbor_lock);
       if(ret != NULL) {
       // have received a hello packet from this neighbor in the recent past
          neighbor_t *neighbor = (neighbor_t*) ret->data;
          display_neighbor_t((void*) neighbor);
          // check if lsu received for first time
          if(neighbor->last_adverts == NULL) {
             printf(" ** pwospf_lsu_type(..) first lsu received from this neighbor\n");
             neighbor->last_lsu_packet = *lsu_packet;
             neighbor->last_adverts = (byte*) malloc_or_die(payload_len - 8);
             memcpy(neighbor->last_adverts, payload + 8, payload_len - 8);
             // add to list
             pthread_mutex_lock(&intf->neighbor_lock);  
             intf->neighbor_list = llist_update_beginning_delete(intf->neighbor_list, predicate_id_neighbor_t_neighbor_t, (void*) neighbor);
             pthread_mutex_unlock(&intf->neighbor_lock);
             display_neighbor_t((void*) neighbor);
             // create router entry
             router_entry_t router_entry;
             router_entry.router_id = neighbor->id;
             router_entry.area_id = 0;
             //add vertex with router entry info
             add_neighbor_vertex_t(router, router_entry);
             //create subnet entry
             subnet_entry_t* subnet_entry;
             //add adverts to db
             printf(" ** pwospf_lsu_type(..) adding adverts to neighbor db\n");
             int i;
             pwospf_ls_advert_t* ls_advert = (pwospf_ls_advert_t*) malloc_or_die(sizeof(pwospf_ls_advert_t));
             for(i = 0; i < ntohl(lsu_packet->no_of_adverts) ; i++) {
                memcpy(&ls_advert->subnet, payload + sizeof(pwospf_lsu_packet_t) + sizeof(pwospf_ls_advert_t) * i, 4);         
                memcpy(&ls_advert->mask, payload + sizeof(pwospf_lsu_packet_t) + 4 + sizeof(pwospf_ls_advert_t) * i, 4);
                memcpy(&ls_advert->router_id, payload + sizeof(pwospf_lsu_packet_t) + 8 + sizeof(pwospf_ls_advert_t) * i, 4);
                display_ls_advert(ls_advert);
                subnet_entry = create_subnet_entry_t_advert(ls_advert);
                add_subnet_entry_t(router, router_entry, subnet_entry);
             }
             // update vertices
             update_neighbor_vertex_t(router, router_entry);
             //calculate new routing table via Dijkstra
             calculate_routing_table(router);
             //check if route/multipath is enabled
             if(router->reroute_multipath_status == TRUE) {
                //run multipath
                reroute_multipath(router);
             }
             //dijkstra2(router); 
             //free(lsu_packet);
             //free(ret);
             //free(neighbor);
             //free(ls_advert);
          } else {
          // check if the previous seq was same
          if(neighbor->last_lsu_packet.seq != lsu_packet->seq) {
             // nope, new seq
             neighbor->last_lsu_packet = *lsu_packet;
             // flood to all neighbors
             pwospf_flood_lsu(ip_header, pwospf_header, lsu_packet, neighbor, intf);
             // check if content the same
             printf("last adverts :%s\n",  (char*) neighbor->last_adverts);
             printf("new: %s\n", (char*) (payload + 8));
             if(memcmp(neighbor->last_adverts, payload + 8, payload_len - 8) != 0) {
                // nope new content
                printf(" ** pwospf_lsu_type(..) new content neighbor db\n");
                if(ntohl(neighbor->last_lsu_packet.no_of_adverts) != ntohl(lsu_packet->no_of_adverts)) {
                   // free mem, as new adverts might need different memory
                   free(neighbor->last_adverts);
                   // now allocate new mem space
                   neighbor->last_adverts = (byte*) malloc_or_die(payload_len - 8);
                }
                memcpy(neighbor->last_adverts, payload + 8, payload_len - 8);
                neighbor->last_lsu_packet = *lsu_packet;
                // update packet info in neighbor list
                pthread_mutex_lock(&intf->neighbor_lock);
                intf->neighbor_list = llist_update_beginning_delete(intf->neighbor_list, predicate_id_neighbor_t_neighbor_t, (void*) neighbor);
                pthread_mutex_unlock(&intf->neighbor_lock);
                // check if entry exists in DB
                // create router entry
                router_entry_t router_entry;
                router_entry.router_id = neighbor->id;
                router_entry.area_id = 0;
                //refresh vertex with router entry info, clear previous subnets
                refresh_neighbor_vertex_t(router, router_entry);
               //create subnet entry
                subnet_entry_t* subnet_entry;

             	int i;
             	pwospf_ls_advert_t* ls_advert = (pwospf_ls_advert_t*) malloc_or_die(sizeof(pwospf_ls_advert_t));
             	if(check_neighbor_vertex_t_router_entry_t_id(router, neighbor->id) == 1) {
                   printf(" ** pwospf_lsu_type(..) neighbor already known, checking if any new adverts\n");
                   //neighbor present in db, check if any new adverts
                   for(i = 0; i < ntohl(lsu_packet->no_of_adverts) ; i++) {
                      memcpy(&ls_advert->subnet, payload + sizeof(pwospf_lsu_packet_t) + sizeof(pwospf_ls_advert_t) * i, 4);
                      memcpy(&ls_advert->mask, payload + sizeof(pwospf_lsu_packet_t) + 4
 + sizeof(pwospf_ls_advert_t) * i, 4);
                      memcpy(&ls_advert->router_id, payload + sizeof(pwospf_lsu_packet_t) + 8 + sizeof(pwospf_ls_advert_t) * i, 4);
                         display_ls_advert(ls_advert);
                         subnet_entry = create_subnet_entry_t_advert(ls_advert);
                	 add_subnet_entry_t(router, router_entry, subnet_entry);
                   }    
                   // update vertices
             	   update_neighbor_vertex_t(router, router_entry);
                } 
                  //run Djikstra's algo to calculate new routing table
                  calculate_routing_table(router);
                  //check if route/multipath is enabled
                  if(router->reroute_multipath_status == TRUE) {
                     //run multipath
                     reroute_multipath(router);
                  }
                  //dijkstra2(router);
                } else {
                     printf(" ** pwospf_lsu_type(..) error, content same as previous from this neighbor, only updating time stamp in DB\n");  
                     // update timestamp
                     // create router entry
	             router_entry_t router_entry;
                     router_entry.router_id = neighbor->id;
                     router_entry.area_id = 0;
                     update_neighbor_vertex_t_timestamp(router, router_entry);

             }
          } else {
              printf(" ** pwospf_lsu_type(..) error, seq same as previous one from this neighbor, dropping\n");
          }
       }
       } else {
          printf(" ** pwospf_lsu_type(..) error, neighbor hasn't said hello recently, dropping\n");
       }
   } else {
      //drop packet
      printf(" ** pwospf_lsu_type(..) error, LSU generated by self. dropping\n");
      //free stuff
     free(lsu_packet);
   } 
}
Exemple #22
0
int sr_load_rt(struct sr_instance* sr,const char* filename)
{
    FILE* fp;
    char  line[BUFSIZ];
    char  dest[32];
    char  gw[32];
    char  mask[32];
    char  iface[32];
    struct in_addr dest_addr;
    struct in_addr gw_addr;
    struct in_addr mask_addr;
    interface_t* intf;

    /* -- REQUIRES -- */
    assert(filename);
    if( access(filename,R_OK) != 0)
    {
        perror("access");
        return -1;
    }

    fp = fopen(filename,"r");
    struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(sr);


    while( fgets(line,BUFSIZ,fp) != 0)
    {
        printf("%s\n", line);
        sscanf(line,"%s %s %s %s",dest,gw,mask,iface);
        if(inet_aton(dest,&dest_addr) == 0)
        {
            fprintf(stderr,
                    "Error loading routing table, cannot convert %s to valid IP\n",
                    dest);
            return -1;
        }
        if(inet_aton(gw,&gw_addr) == 0)
        {
            fprintf(stderr,
                    "Error loading routing table, cannot convert %s to valid IP\n",
                    gw);
            return -1;
        }
        if(inet_aton(mask,&mask_addr) == 0)
        {
            fprintf(stderr,
                    "Error loading routing table, cannot convert %s to valid IP\n",
                    mask);
            return -1;
        }
        intf =  get_interface_name(subsystem, iface);
        if(intf == NULL) {
            fprintf(stderr,
                    "Error! Invalid interface: %s\n", iface);
        } else {
            rrtable_route_add( subsystem->rtable,
                               dest_addr.s_addr,
                               gw_addr.s_addr,
                               mask_addr.s_addr,
                               intf,
                               's' );

        }

    } /* -- while -- */

    return 0; /* -- success -- */
} /* -- sr_load_rt -- */