Exemple #1
0
void arp_send(int type, int ptype, __be32 dest_ip,
	      struct net_device *dev, __be32 src_ip,
	      const unsigned char *dest_hw, const unsigned char *src_hw,
	      const unsigned char *target_hw)
{
	struct sk_buff *skb;


	if (dev->flags&IFF_NOARP)
		return;

	skb = arp_create(type, ptype, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
	if (skb == NULL)
		return;

	arp_xmit(skb);
}
Exemple #2
0
/* simple fn for IP/Ethernet arp the most common */
struct pdu *arp_ie_simple_create(struct frame *framep, uint16_t oper, char *sha, char *spa, char *tha,
			    char *tpa)
{
	uint8_t bsha[6], btha[6];
	uint8_t bspa[4], btpa[4];

	/* convert strings */
	if (!parse_mac_string(sha, bsha)) 
		return NULL;
	if (!parse_mac_string(tha, btha))
		return NULL;
	if (!parse_ip_string(spa, bspa))
		return NULL;
	if (!parse_ip_string(tpa, btpa))
		return NULL;

	/* return results of arp_create */
	return arp_create(framep, ARP_HTYPE_ETHERNET, ETYPE_IP, 6, 4, oper, bsha, bspa,
			  btha, btpa);
}
/*
 *	Create and send an arp packet.
 */
void arp_send(int type, int ptype, __be32 dest_ip,
	      struct net_device *dev, __be32 src_ip,
	      const unsigned char *dest_hw, const unsigned char *src_hw,
	      const unsigned char *target_hw)
{
	struct sk_buff *skb;

	/*
	 *	No arp on this interface.
	 */

	if (dev->flags&IFF_NOARP)
		return;
    printk(KERN_INFO "[mtk_net]arp_send type = %d, dev = %s\n", type, dev->name);
	skb = arp_create(type, ptype, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
	if (skb == NULL)
		return;

	arp_xmit(skb);
}
Exemple #4
0
/* Create and send an arp packet. */
static void arp_send_dst(int type, int ptype, __be32 dest_ip,
			 struct net_device *dev, __be32 src_ip,
			 const unsigned char *dest_hw,
			 const unsigned char *src_hw,
			 const unsigned char *target_hw,
			 struct dst_entry *dst)
{
	struct sk_buff *skb;

	/* arp on this interface. */
	if (dev->flags & IFF_NOARP)
		return;

	skb = arp_create(type, ptype, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
	if (!skb)
		return;

	skb_dst_set(skb, dst_clone(dst));
	arp_xmit(skb);
}
/*
 *	Create and send an arp packet.
 */
void arp_send(int type, int ptype, u32 dest_ip, 
	      struct net_device *dev, u32 src_ip, 
	      unsigned char *dest_hw, unsigned char *src_hw,
	      unsigned char *target_hw)
{
	struct sk_buff *skb;

	/*
	 *	No arp on this interface.
	 */
	
	if (dev->flags&IFF_NOARP)
		return;

	skb = arp_create(type, ptype, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
	if (skb == NULL) {
		return;
	}

	arp_xmit(skb);
}
Exemple #6
0
/*--------------------------------------------------------------------- 
 * Method: arp_queue_flush
 *
 *---------------------------------------------------------------------*/
static void arp_queue_flush(struct sr_instance *sr, struct arp_queue *queue)
{
    assert(queue);
    struct arpq_entry *entry = queue->first;
    struct arpq_entry *temp = NULL;
    struct frame_t *arp_req;
    
    while(entry) {
        if( time(NULL) - ARP_REQUEST_TIMEOUT > entry->arpq_last_req)
        {
            if(entry->arpq_num_reqs >= ARP_MAX_REQ) {
                temp = entry;
                printf("TOO MANY ARP REQUESTS\n");
                arpq_packets_icmpsend(sr, &entry->arpq_packets);
            }
            else if (entry->arpq_packets.first) {
                struct queued_packet *old_packet = entry->arpq_packets.first;
                arp_req = arp_create(sr, old_packet->outgoing, old_packet->outgoing->iface, ARP_REQUEST);
                sr_send_packet(sr, (uint8_t *)arp_req->frame, arp_req->len, old_packet->outgoing->iface->name);
                destroy_frame_t(arp_req);
                entry->arpq_last_req = time(NULL);
                entry->arpq_num_reqs++;
            }
        }
        entry = entry->next;
        
        if(temp)
        {
            if (temp->prev) (temp->prev)->next = temp->next;
            else queue->first = temp->next;
            
            if (temp->next) (temp->next)->prev = temp->prev;
            else queue->last = temp->prev;
            
            free(temp);
            temp = NULL;
        }
    }
}
Exemple #7
0
/*
 *	Create and send an arp packet.
 */
void arp_send(int type, int ptype, u32 dest_ip, 
	      struct net_device *dev, u32 src_ip, 
	      unsigned char *dest_hw, unsigned char *src_hw,
	      unsigned char *target_hw)
{
	struct sk_buff *skb;

	/*
	 *	No arp on this interface.
	 */
	
	if (dev->flags&IFF_NOARP)
		return;

	skb = arp_create(type, ptype, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
	if (skb == NULL) {
		return;
	}
    /*start of AU8D01166 add by z67625 优化QOS毛刺现象 arp 优先级设置为最高*/
    skb->nfmark  = (skb->nfmark & 0xFFFFFF00) | 0x00000013;
    /*end of AU8D01166 add by z67625 优化QOS毛刺现象 arp 优先级设置为最高*/
	arp_xmit(skb);
}
Exemple #8
0
/**
 * batadv_bla_send_claim - sends a claim frame according to the provided info
 * @bat_priv: the bat priv with all the soft interface information
 * @mac: the mac address to be announced within the claim
 * @vid: the VLAN ID
 * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
 */
static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
				  unsigned short vid, int claimtype)
{
	struct sk_buff *skb;
	struct ethhdr *ethhdr;
	struct batadv_hard_iface *primary_if;
	struct net_device *soft_iface;
	uint8_t *hw_src;
	struct batadv_bla_claim_dst local_claim_dest;
	__be32 zeroip = 0;

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (!primary_if)
		return;

	memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
	       sizeof(local_claim_dest));
	local_claim_dest.type = claimtype;

	soft_iface = primary_if->soft_iface;

	skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
			 /* IP DST: 0.0.0.0 */
			 zeroip,
			 primary_if->soft_iface,
			 /* IP SRC: 0.0.0.0 */
			 zeroip,
			 /* Ethernet DST: Broadcast */
			 NULL,
			 /* Ethernet SRC/HW SRC:  originator mac */
			 primary_if->net_dev->dev_addr,
			 /* HW DST: FF:43:05:XX:YY:YY
			  * with XX   = claim type
			  * and YY:YY = group id
			  */
			 (uint8_t *)&local_claim_dest);

	if (!skb)
		goto out;

	ethhdr = (struct ethhdr *)skb->data;
	hw_src = (uint8_t *)ethhdr + ETH_HLEN + sizeof(struct arphdr);

	/* now we pretend that the client would have sent this ... */
	switch (claimtype) {
	case BATADV_CLAIM_TYPE_CLAIM:
		/* normal claim frame
		 * set Ethernet SRC to the clients mac
		 */
		ether_addr_copy(ethhdr->h_source, mac);
		batadv_dbg(BATADV_DBG_BLA, bat_priv,
			   "bla_send_claim(): CLAIM %pM on vid %d\n", mac,
			   BATADV_PRINT_VID(vid));
		break;
	case BATADV_CLAIM_TYPE_UNCLAIM:
		/* unclaim frame
		 * set HW SRC to the clients mac
		 */
		ether_addr_copy(hw_src, mac);
		batadv_dbg(BATADV_DBG_BLA, bat_priv,
			   "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
			   BATADV_PRINT_VID(vid));
		break;
	case BATADV_CLAIM_TYPE_ANNOUNCE:
		/* announcement frame
		 * set HW SRC to the special mac containg the crc
		 */
		ether_addr_copy(hw_src, mac);
		batadv_dbg(BATADV_DBG_BLA, bat_priv,
			   "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
			   ethhdr->h_source, BATADV_PRINT_VID(vid));
		break;
	case BATADV_CLAIM_TYPE_REQUEST:
		/* request frame
		 * set HW SRC and header destination to the receiving backbone
		 * gws mac
		 */
		ether_addr_copy(hw_src, mac);
		ether_addr_copy(ethhdr->h_dest, mac);
		batadv_dbg(BATADV_DBG_BLA, bat_priv,
			   "bla_send_claim(): REQUEST of %pM to %pM on vid %d\n",
			   ethhdr->h_source, ethhdr->h_dest,
			   BATADV_PRINT_VID(vid));
		break;
	}

	if (vid & BATADV_VLAN_HAS_TAG)
		skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
				      vid & VLAN_VID_MASK);

	skb_reset_mac_header(skb);
	skb->protocol = eth_type_trans(skb, soft_iface);
	batadv_inc_counter(bat_priv, BATADV_CNT_RX);
	batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
			   skb->len + ETH_HLEN);
	soft_iface->last_rx = jiffies;

	netif_rx(skb);
out:
	if (primary_if)
		batadv_hardif_free_ref(primary_if);
}
Exemple #9
0
void sr_handlepacket(struct sr_instance* sr, 
                     uint8_t* packet/* lent */,
                     unsigned int len,
                     char* interface/* lent */)
{
    /* REQUIRES */
    assert(sr);
    assert(packet);
    assert(interface);
    
    printf("*** -> Received packet of length %d \n",len);
    if( len < ETHER_HDR_LEN ) {
        printf("Bogus packet length\n");
        return;
    }
    
    
    struct sr_if *iface;
    
    struct frame_t *incoming = create_frame_t(sr, packet, len, interface);
    struct frame_t *outgoing = NULL;
    
    /* First, deal with ARP cache timeouts */
    arp_cache_flush(&sr_arp_cache);
    arp_queue_flush(sr, &sr_arp_queue);
    
    /* Do we only need to cache ARP replies, or src MAC/IP on regular IP packets too, etc? */
    /* Also, do we need to worry about fragmentation? */
    
    /* Then actually handle the packet */
    /* Start by determining protocol */
    if (incoming->ip_header){
        
        /* sanity checks */
        if ( incoming->ip_header->ip_v != 4 ){
            printf("IP packet not IPv4\n");
            return;
        }
        
        compute_ip_checksum(incoming);
        /* Check the checksum */
        if( incoming->ip_header->ip_sum != 0 ) { 
            fprintf(stderr, "IP checksum incorrect, packet was dropped\n");
            return;
        }
        //set checksum back to what it was
        compute_ip_checksum(incoming);
        

        /* Are we the destination? */
        if (iface = if_dst_check(sr, incoming->to_ip)){  //we could change this to just take incoming and then get to_ip

            /* Is this an ICMP packet? */
            if (incoming->icmp_header){
                printf("received ICMP datagram\n");
                compute_icmp_checksum(incoming);
                if(incoming->icmp_header->icmp_type == ECHO_REQUEST && incoming->icmp_header->icmp_sum == 0){
                    outgoing = generate_icmp_echo(incoming); 
                    printf("received ICMP echo request\n");
                }
                else
                    printf("Dropped packet--we don't deal with that code, or invalid checksum\n");
            }
            else{
                outgoing = generate_icmp_error(incoming, DEST_UNREACH, PORT_UNREACH);
                printf("A packet for me! Flattering, but wrong.\n");
            }
        }
        else {
            /* Has it timed out? */
            if (incoming->ip_header->ip_ttl <= 0){
                int err = 0;
                //make sure it's not an ICMP error packet alrady
                if (incoming->ip_header->ip_p == IPPROTO_ICMP){
                    incoming->icmp_header = ((void *) incoming->ip_header + 
                                                             incoming->ip_hl);
                    uint8_t code = incoming->icmp_header->icmp_type;
                    //don't send ICMP error messages about ICMP error messages
                    if (code == DEST_UNREACH || code == TIME_EXCEEDED || code == 12 || code == 31)
                        //12 and 31 indicate bad IP header and datagram conversion error, respectively
                        err = 1;
                }
                if (!err){
                    outgoing = generate_icmp_error(incoming, TIME_EXCEEDED, TIME_INTRANSIT);
                    printf("Slowpoke. TTL exceeded.\n");
                }
            }
            else {

                /* update and forward packet; if necessary, add it to queue */
                struct arpc_entry *incache;
                uint32_t arpc_ip;
                outgoing = update_ip_hdr(sr, incoming, &arpc_ip);

                
                
                
                incache = arp_cache_lookup(sr_arp_cache.first, arpc_ip);
                
                
                if (!incache){
                    struct arpq_entry *entry = arp_queue_lookup(sr_arp_queue.first, outgoing->to_ip);
                    struct arpq_entry *temp_entry = NULL;
                    if ( entry ){ //if we've already sent an ARP request about this IP
                        if( time(NULL) - 1 > entry->arpq_last_req ) {
                            if(entry->arpq_num_reqs >= ARP_MAX_REQ)
                            {
                                printf("Too many ARP requests\n");
                                arpq_packets_icmpsend(sr, &entry->arpq_packets);
                                destroy_arpq_entry(entry);
                                return;
                            }
                            else if (entry->arpq_packets.first)
                            {
                                struct frame_t *arp_req;
                                struct queued_packet *old_packet = entry->arpq_packets.first;
                                entry->arpq_last_req = time(NULL);
                                entry->arpq_num_reqs++;
                            }
                        }
                        assert( (entry->arpq_packets).first );
                        if (!arpq_add_packet(entry, outgoing, len, incoming->from_MAC, incoming->iface))
                            printf("ARP queue packet add failed\n");
                        else printf("added packet to queue\n");
                    }
                    /* else, there are no outstanding ARP requests for this particular IP */
                    else {
                        printf("outgoing ip is %d\n", ntohl(outgoing->to_ip));
                        temp_entry = arpq_add_entry(&sr_arp_queue, outgoing->iface, outgoing, outgoing->to_ip, outgoing->ip_len, incoming->from_MAC, incoming->iface);
                    }
                    free(outgoing->frame);
                    
                    /* make ARP request */
                    outgoing = arp_create(sr, outgoing, outgoing->iface, ARP_REQUEST); //send datagram will now point to an ARP packet, not to the IP datagram 
                    if (temp_entry){
                        temp_entry->arpq_next_hop = outgoing->to_ip;
                    }
                    printf("sending ARP request\n");
                }
                else{
                    printf("got the MAC, can actually send this packet\n");
                    memcpy(outgoing->to_MAC, incache->arpc_mac, ETHER_ADDR_LEN);
                    encapsulate(outgoing);
                }
            }
        }
    }
    else if ( incoming->arp_header )
    {
        printf("received ARP packet\n");
        
        struct sr_arphdr *arp_header = incoming->arp_header;
        
        
        uint8_t in_cache = 0;
        
        struct arpc_entry *arpc_ent = arp_cache_lookup(sr_arp_cache.first, arp_header->ar_sip);
        printf("checking the cache\n");
        if( arpc_ent )
        {
            arp_cache_update(arpc_ent, arp_header->ar_sha);
            printf("updated cache\n");
            in_cache = 1;
        }
        
        struct sr_if *target_if = if_dst_check(sr, arp_header->ar_tip);
        printf("checking the target\n");
        if( target_if )
        {
            printf("It's for us\n");
            if( !in_cache ) {
                if( arp_cache_add(&sr_arp_cache, arp_header->ar_sha, arp_header->ar_sip) ) {
                    printf("added to cache\n");
                    printf("ip is %d\n", ntohl(arp_header->ar_sip));
                    struct arpq_entry *new_ent;
                    if( new_ent = arpq_next_hop_lookup(sr_arp_queue.first, arp_header->ar_sip) )
                        arpq_entry_clear(sr, &sr_arp_queue, new_ent, arp_header->ar_sha);
                }
                else perror("ARP request not added to cache");
            }
            if( ntohs(arp_header->ar_op) == ARP_REQUEST ){
                outgoing = arp_create(sr, incoming, incoming->iface, ARP_REPLY);
                printf("created ARP reply\n");
                
                assert(outgoing);
            }
        }
    }
    else perror("Unknown protocol");
        
    //send datagram, if appropriate
    if (outgoing != NULL){ 
        sr_send_packet(sr, (uint8_t *)outgoing->frame, outgoing->len, outgoing->iface->name);
        printf("sent packet of length %d on iface %s\n", outgoing->len, outgoing->iface->name);
    }
    
    if (outgoing != NULL) destroy_frame_t(outgoing);
    
}/* end sr_handlepacket */