コード例 #1
0
ファイル: arpspoof.c プロジェクト: Affix/dsniff
static void
cleanup(int sig)
{
	int i;
	int rounds = (cleanup_src_own*5 + cleanup_src_host*5);

	fprintf(stderr, "Cleaning up and re-arping targets...\n");
	for (i = 0; i < rounds; i++) {
		struct host *target = hosts;
		for(;target->ip;target++) {
			uint8_t *src_ha = NULL;

			if (!(target->flags & HOST_TARGET)) continue;
			if (!(target->flags & HOST_ACTIVE)) continue;

			struct host *model = hosts;
			for(;model->ip;model++) {
				if (!(model->flags & HOST_ACTIVE)) continue;
				int fw = arp_find(target->ip, &target->mac);
				int bw = poison_reverse;

				if (!(model->flags & HOST_MODEL)) continue;

				if (cleanup_src_own && (i%2 || !cleanup_src_host)) {
					src_ha = my_ha;
				}
				/* XXX - on BSD, requires ETHERSPOOF kernel. */
				if (fw) {
					arp_send(l, ARPOP_REPLY,
						 (u_int8_t *)&model->mac, model->ip,
						 (target->ip ? (u_int8_t *)&target->mac : brd_ha),
						 target->ip,
						 src_ha);
					/* we have to wait a moment before sending the next packet */
					usleep(ARP_PAUSE);
				}
				if (bw) {
					arp_send(l, ARPOP_REPLY,
						 (u_int8_t *)&target->mac, target->ip,
						 (u_int8_t *)&model->mac,
						 model->ip,
						 src_ha);
					usleep(ARP_PAUSE);
				}
			}
		}
	}

	exit(0);
}
コード例 #2
0
ファイル: arpspoof.c プロジェクト: 8003178550/dsploit
static void cleanup(int sig)
{
	killed = 1;

	printf( "Restoring arp table ...\n" );
	int i, j;
	struct ether_addr gateway_mac;

	if( netmap == NULL )
	{
		if( arp_lookup( gateway_ip, &gateway_mac, iface ) == 0 )
		{
			for( i = 0; i < 3; i++ )
			{
				/* XXX - on BSD, requires ETHERSPOOF kernel. */
				arp_send( lnet, ARPOP_REPLY, (unsigned char *)&gateway_mac, gateway_ip, (unsigned char *)&target_mac, target_ip );
				sleep(1);
			}
		}
	}
	else
	{
		if( arp_lookup( gateway_ip, &gateway_mac, iface ) == 0 )
		{
			for( i = 0; i < 3; i++ )
			{
				for( j = 0; j < netmap->bucketCount; j++ )
				{
					Entry* hentry = netmap->buckets[j];
					while( hentry != NULL )
					{
						Entry 					*next  = hentry->next;
						network_entry_t *entry = ( network_entry_t * )hentry->value;

						arp_send( lnet, ARPOP_REPLY, (unsigned char *)&gateway_mac, gateway_ip, entry->mac, entry->address );

						hentry = next;
					}
				}

				sleep(1);
			}
		}

		hashmapFree( netmap );
	}

	exit(0);
}
コード例 #3
0
ファイル: ARP.C プロジェクト: david6610/DDNSByMobile
//------------------------------------------------------------------------
// This re-sends an ARP request if there was no response to
// the first one.	 It is called every 0.5 seconds.  If there
// is no response after 2 re-tries, the datagram that IP was 
// trying to send is deleted
//-----------------------------------------------------------------------
void arp_retransmit(void)
{
	static UCHAR idata retries = 0; 
	
	if ((waiting_for_arp) && (wait.timer))
	{
		wait.timer--;
		if (wait.timer == 0)
		{
			retries++;
			if (retries <= 2)
			{
				if (debug) serial_send("ARP: Re-sending ARP broadcast\r");
	 			arp_send(NULL, wait.ipaddr, ARP_REQUEST);
				wait.timer = ARP_TIMEOUT;
			}
			else
			{	
				if (debug) serial_send("ARP: Gave up waiting for response\r");
	 			wait.timer = 0;
				waiting_for_arp = 0;
				free(wait.buf);
			}
		}
	}
}
コード例 #4
0
ファイル: arp.c プロジェクト: John677/Kernal_k3note
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
	__be32 saddr = 0;
	u8 dst_ha[MAX_ADDR_LEN], *dst_hw = NULL;
	struct net_device *dev = neigh->dev;
	__be32 target = *(__be32 *)neigh->primary_key;
	int probes = atomic_read(&neigh->probes);
	struct in_device *in_dev;

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(dev);
	if (!in_dev) {
		rcu_read_unlock();
		return;
	}
	switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
	default:
	case 0:		/* By default announce any local IP */
		if (skb && inet_addr_type(dev_net(dev),
					  ip_hdr(skb)->saddr) == RTN_LOCAL)
			saddr = ip_hdr(skb)->saddr;
		break;
	case 1:		/* Restrict announcements of saddr in same subnet */
		if (!skb)
			break;
		saddr = ip_hdr(skb)->saddr;
		if (inet_addr_type(dev_net(dev), saddr) == RTN_LOCAL) {
			/* saddr should be known to target */
			if (inet_addr_onlink(in_dev, target, saddr))
				break;
		}
		saddr = 0;
		break;
	case 2:		/* Avoid secondary IPs, get a primary/preferred one */
		break;
	}
	rcu_read_unlock();

	if (!saddr)
		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);

	probes -= neigh->parms->ucast_probes;
	if (probes < 0) {
		if (!(neigh->nud_state & NUD_VALID))
			pr_debug("trying to ucast probe in NUD_INVALID\n");
		neigh_ha_snapshot(dst_ha, neigh, dev);
		dst_hw = dst_ha;
	} else {
		probes -= neigh->parms->app_probes;
		if (probes < 0) {
#ifdef CONFIG_ARPD
			neigh_app_ns(neigh);
#endif
			return;
		}
	}

	arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
		 dst_hw, dev->dev_addr, NULL);
}
コード例 #5
0
ファイル: Arp.c プロジェクト: cqqqh/CK_keil_cankao
//------------------------------------------------------------------------
// Find the ethernet hardware address for the given ip address
// If destination IP is on my subnet then we want the eth
// address	of destination, otherwise we want eth addr of gateway. 
// Look in ARP cache first.  If not found there, send ARP request.
// Return pointer to the hardware address or NULL if not found
// See "TCP/IP Illustrated, Volume 1" Sect 4.5
//------------------------------------------------------------------------
UCHAR xdata * arp_resolve(ULONG dest_ipaddr)
{
   UCHAR i;
      
   // If destination IP is not on my subnet then we really want eth addr
	// of gateway, not destination IP
	if ((dest_ipaddr ^ my_ipaddr) & my_subnet)
	{
		if (gateway_ipaddr == 0)
		{
			return (NULL);	
	 	}
	 	else dest_ipaddr = gateway_ipaddr;
	}
	
	   
   // See if IP addr of interest is in ARP cache
   for (i=0; i < CACHESIZE; i++)
   {
      if (arp_cache[i].ipaddr == dest_ipaddr)
         return (&arp_cache[i].hwaddr[0]);
   }

	// Not in cache so broadcast ARP request
  	arp_send(NULL, dest_ipaddr, ARP_REQUEST);
     	   
   // Set a flag to indicate that an IP datagram is waiting
   // to be sent
   waiting_for_arp = TRUE;
				      
   // Null means that we have sent an ARP request
   return (NULL); 
}
コード例 #6
0
ファイル: sr_router.c プロジェクト: c2birlar/yah
/*Does all handling of incoming ARP packets, returns 1 if successful*/
int handle_ARP_packet(struct sr_instance* sr, 
		      uint8_t* packet,
		      int len, 
		      char* interface){
  int minLenARP = sizeof(struct sr_ethernet_hdr) + sizeof(struct sr_arp_hdr); 
  if (len < minLenARP){
      fprintf(stderr, "Failed to access ARP header, too small\n");
      drop_packet = 1;
      //return;
    }
    if (drop_packet == 0){
      if (destinedToRouter(dest_ip)){
	sr_ethernet_hdr_t* ethernet_hdr = (sr_ethernet_hdr_t*)packet;
	sr_arp_hdr_t* arp_header = (sr_arp_hdr_t*)(packet + (uint8_t) eth_size);

	if (ntohl(arp_header->ar_op) == arp_op_reply){//We have a ARP reply
	  //process reply
	  //move entries from ARP request queue to ARP cache
	  struct sr_arpreq* req;
	  req = sr_arpcache_insert(&(sr->cache), arp_header->ar_sha,
				   ntohl(arp_header->ar_sip));
	  if (req!=NULL){
	     struct sr_packet* traverser = req->packets;
	     while(traverser != NULL){
	       //normal IP forward, no errors detected
	       //change old contents
	       struct sr_arpentry *arp_entry;
	       arp_entry = sr_arpcache_lookup(&(sr->cache),dest_ip);
	       sr_ip_hdr_t* ip_header = (sr_ip_hdr_t*)(packet + (uint8_t) eth_size);
	       sr_ethernet_hdr_t* out_eth = (sr_ethernet_hdr_t*)packet;
	       uint16_t modCksum = cksum(ip_header, sizeof(struct sr_ip_hdr));
	       int ret = ip_forward(sr,packet,len,out_eth,arp_entry->mac,
				    dest_ip, modCksum,interface);
	       if (ret!= 0){
		 fprintf(stderr, "Didn't send ip packet properly\n");

	       }

	       traverser = traverser->next;
	     }
	     sr_arpreq_destroy(&(sr->cache), req);
	  }
	}else{
	  //process ARP request and send reply 
	  //(they want our MAC address) so sends reply packet
	  int ret =  arp_send(sr,packet,len,
			      ethernet_hdr,arp_header,dest_ip);
	  if (ret!= 0){
	    fprintf(stderr, "Didn't send arp packet properly\n");

	  }
	}
      }else{
	//pass
	//forward packet
      }
    }
    return 1;
}
コード例 #7
0
ファイル: arpspoof.c プロジェクト: shelmesky/linux_tools
int
main(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	char pcap_ebuf[PCAP_ERRBUF_SIZE];
	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
	int c;
	
	intf = NULL;
	spoof_ip = target_ip = 0;
	
	while ((c = getopt(argc, argv, "i:t:h?V")) != -1) {
		switch (c) {
		case 'i':
			intf = optarg;
			break;
		case 't':
			if ((target_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
				usage();
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	
	if (argc != 1)
		usage();
	
	if ((spoof_ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
		usage();
	
	if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL)
		errx(1, "%s", pcap_ebuf);
	
	if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL)
		errx(1, "%s", libnet_ebuf);
	
	if (target_ip != 0 && !arp_find(target_ip, &target_mac))
		errx(1, "couldn't arp for host %s",
		     libnet_addr2name4(target_ip, LIBNET_DONT_RESOLVE));
	
	signal(SIGHUP, cleanup);
	signal(SIGINT, cleanup);
	signal(SIGTERM, cleanup);
	
	for (;;) {
		arp_send(l, ARPOP_REPLY, NULL, spoof_ip,
			 (target_ip ? (u_int8_t *)&target_mac : NULL),
			 target_ip);
		sleep(2);
	}
	/* NOTREACHED */
	
	exit(0);
}
コード例 #8
0
ファイル: br_input.c プロジェクト: 513855417/linux
static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
			    u16 vid, struct net_bridge_port *p)
{
	struct net_device *dev = br->dev;
	struct neighbour *n;
	struct arphdr *parp;
	u8 *arpptr, *sha;
	__be32 sip, tip;

	BR_INPUT_SKB_CB(skb)->proxyarp_replied = false;

	if (dev->flags & IFF_NOARP)
		return;

	if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
		dev->stats.tx_dropped++;
		return;
	}
	parp = arp_hdr(skb);

	if (parp->ar_pro != htons(ETH_P_IP) ||
	    parp->ar_op != htons(ARPOP_REQUEST) ||
	    parp->ar_hln != dev->addr_len ||
	    parp->ar_pln != 4)
		return;

	arpptr = (u8 *)parp + sizeof(struct arphdr);
	sha = arpptr;
	arpptr += dev->addr_len;	/* sha */
	memcpy(&sip, arpptr, sizeof(sip));
	arpptr += sizeof(sip);
	arpptr += dev->addr_len;	/* tha */
	memcpy(&tip, arpptr, sizeof(tip));

	if (ipv4_is_loopback(tip) ||
	    ipv4_is_multicast(tip))
		return;

	n = neigh_lookup(&arp_tbl, &tip, dev);
	if (n) {
		struct net_bridge_fdb_entry *f;

		if (!(n->nud_state & NUD_VALID)) {
			neigh_release(n);
			return;
		}

		f = __br_fdb_get(br, n->ha, vid);
		if (f && ((p->flags & BR_PROXYARP) ||
			  (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)))) {
			arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip,
				 sha, n->ha, sha);
			BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
		}

		neigh_release(n);
	}
}
コード例 #9
0
ファイル: cfg.c プロジェクト: millken/zhuxianB30
s32 mpls_echo_info_get(void * buf)
{
    s32 err = 0;
    struct fib_mg_res ret = {0};
	mpls_echo_sys_req * req = (mpls_echo_sys_req *)buf ;
	mpls_echo_sys_res * res = (mpls_echo_sys_res *)buf;

    err = fib_mg_lookup(req->vrfid, req->addr, req->plen, &ret);
    if (err)
    {
        res->count = 0;
        return err;
    }

    if (!ret.neigh)
    {
        ret.neigh = __neigh_arp_lookup(&arp_tbl, &ret.nexthop, NULL, ret.dev, NEIGHBOUR_CREAT);
        read_lock_bh(&ret.neigh->lock);
        if (!(ret.neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
        {
            res->saddr = inet_select_addr(ret.dev, ret.nexthop, RT_SCOPE_LINK);
            arp_send(ARPOP_REQUEST, ETH_P_ARP, ret.nexthop, ret.dev, res->saddr,
               ret.neigh->ha, ret.dev->dev_addr, NULL);
            read_unlock_bh(&ret.neigh->lock);
            return 0;
        }
        read_unlock_bh(&ret.neigh->lock);
    }

    memcpy((void *)res->dest, (void *)ret.neigh->ha, ETH_ALEN);

    if (ret.dev)
    {
        res->oif = ret.dev->ifindex;
        res->saddr = inet_select_addr(ret.dev, ret.nexthop, RT_SCOPE_LINK);
        memcpy((void *)res->source, (void *)ret.dev->dev_addr, ret.dev->addr_len);
    }

    res->nexthop = ret.nexthop;

    res->count = ret.count;
    if (FIB_MG_TYPE_FTN_BASIC == ret.type)
    {
        res->labels[0] = ret.glabel;
        res->labels[1] = ret.glabel2;
    }
    else
    {
        res->labels[0] = ret.label;
        res->labels[1] = ret.glabel;
        res->labels[1] = ret.glabel2;
    }
    
    return 0;
}
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
	u32 saddr = 0;
	u8  *dst_ha = NULL;
	struct net_device *dev = neigh->dev;
	u32 target = *(u32*)neigh->primary_key;
	int probes = atomic_read(&neigh->probes);
	struct in_device *in_dev = in_dev_get(dev);

	if (!in_dev)
		return;

	switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
	default:
	case 0:		/* By default announce any local IP */
		if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
			saddr = skb->nh.iph->saddr;
		break;
	case 1:		/* Restrict announcements of saddr in same subnet */
		if (!skb)
			break;
		saddr = skb->nh.iph->saddr;
		if (inet_addr_type(saddr) == RTN_LOCAL) {
			/* saddr should be known to target */
			if (inet_addr_onlink(in_dev, target, saddr))
				break;
		}
		saddr = 0;
		break;
	case 2:		/* Avoid secondary IPs, get a primary/preferred one */
		break;
	}

	if (in_dev)
		in_dev_put(in_dev);
	if (!saddr)
		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);

	if ((probes -= neigh->parms->ucast_probes) < 0) {
		if (!(neigh->nud_state&NUD_VALID))
			printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
		dst_ha = neigh->ha;
		read_lock_bh(&neigh->lock);
	} else if ((probes -= neigh->parms->app_probes) < 0) {
#ifdef CONFIG_ARPD
		neigh_app_ns(neigh);
#endif
		return;
	}

	arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
		 dst_ha, dev->dev_addr, NULL);
	if (dst_ha)
		read_unlock_bh(&neigh->lock);
}
コード例 #11
0
ファイル: send_garp.c プロジェクト: stroboscope/send_garp
/* function taken from net/ipv4/devinet.c */
static void inetdev_send_gratuitous_arp(struct net_device *dev,
	struct in_device *in_dev)
{
	struct in_ifaddr *ifa;
	
	for (ifa = in_dev->ifa_list; ifa;
	     ifa = ifa->ifa_next) {
		arp_send(ARPOP_REQUEST, ETH_P_ARP,
			ifa->ifa_local, dev,
			ifa->ifa_local, NULL,
			dev->dev_addr, NULL);
	}
}
コード例 #12
0
static void
cleanup(int sig)
{
	int i;
	
	if (arp_find(spoof_ip, &spoof_mac)) {
		for (i = 0; i < 3; i++) {
			/* XXX - on BSD, requires ETHERSPOOF kernel. */
			arp_send(l, ARPOP_REPLY,
				 (u_int8_t *)&spoof_mac, spoof_ip,
				 (target_ip ? (u_int8_t *)&target_mac : NULL),
				 target_ip);
			sleep(1);
		}
	}
	exit(0);
}
コード例 #13
0
static void
rlb_update_client(struct rlb_client_info *client_info)
{
	int i = 0;

	if (client_info->slave == NULL) {
		return;
	}

	for (i=0; i<RLB_ARP_BURST_SIZE; i++) {
		arp_send(ARPOP_REPLY, ETH_P_ARP,
			 client_info->ip_dst,
			 client_info->slave->dev,
			 client_info->ip_src,
			 client_info->mac_dst,
			 client_info->slave->dev->dev_addr,
			 client_info->mac_dst);
	}
}
コード例 #14
0
static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
   const struct net_device *in, const struct net_device *out,
   const void *data, unsigned int datalen)
{
	struct ebt_arpreply_info *info = (void *)data;
	const __be32 *siptr, *diptr;
	__be32 _sip, _dip;
	const struct arphdr *ap;
	struct arphdr _ah;
	const unsigned char *shp;
	unsigned char _sha[ETH_ALEN];

	ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
	if (ap == NULL)
		return EBT_DROP;

	if (ap->ar_op != htons(ARPOP_REQUEST) ||
	    ap->ar_hln != ETH_ALEN ||
	    ap->ar_pro != htons(ETH_P_IP) ||
	    ap->ar_pln != 4)
		return EBT_CONTINUE;

	shp = skb_header_pointer(skb, sizeof(_ah), ETH_ALEN, &_sha);
	if (shp == NULL)
		return EBT_DROP;

	siptr = skb_header_pointer(skb, sizeof(_ah) + ETH_ALEN,
				   sizeof(_sip), &_sip);
	if (siptr == NULL)
		return EBT_DROP;

	diptr = skb_header_pointer(skb,
				   sizeof(_ah) + 2 * ETH_ALEN + sizeof(_sip),
				   sizeof(_dip), &_dip);
	if (diptr == NULL)
		return EBT_DROP;

	arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)in,
		 *diptr, shp, info->mac, shp);

	return info->target;
}
コード例 #15
0
ファイル: ebt_arpreply.c プロジェクト: AshishNamdev/linux
static unsigned int
ebt_arpreply_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
	const struct ebt_arpreply_info *info = par->targinfo;
	const __be32 *siptr, *diptr;
	__be32 _sip, _dip;
	const struct arphdr *ap;
	struct arphdr _ah;
	const unsigned char *shp;
	unsigned char _sha[ETH_ALEN];

	ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
	if (ap == NULL)
		return EBT_DROP;

	if (ap->ar_op != htons(ARPOP_REQUEST) ||
	    ap->ar_hln != ETH_ALEN ||
	    ap->ar_pro != htons(ETH_P_IP) ||
	    ap->ar_pln != 4)
		return EBT_CONTINUE;

	shp = skb_header_pointer(skb, sizeof(_ah), ETH_ALEN, &_sha);
	if (shp == NULL)
		return EBT_DROP;

	siptr = skb_header_pointer(skb, sizeof(_ah) + ETH_ALEN,
				   sizeof(_sip), &_sip);
	if (siptr == NULL)
		return EBT_DROP;

	diptr = skb_header_pointer(skb,
				   sizeof(_ah) + 2 * ETH_ALEN + sizeof(_sip),
				   sizeof(_dip), &_dip);
	if (diptr == NULL)
		return EBT_DROP;

	arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr,
		 (struct net_device *)xt_in(par),
		 *diptr, shp, info->mac, shp);

	return info->target;
}
コード例 #16
0
ファイル: arpspoof.c プロジェクト: Affix/dsniff
static int
arp_find(in_addr_t ip, struct ether_addr *mac)
{
	int i = 0;

	do {
		if (arp_cache_lookup(ip, mac, intf) == 0)
			return (1);
#ifdef __linux__
		/* XXX - force the kernel to arp. feh. */
		arp_force(ip);
#else
		arp_send(l, ARPOP_REQUEST, NULL, 0, NULL, ip, NULL);
#endif
		usleep(10000);
	}
	while (i++ < 3);

	return (0);
}
コード例 #17
0
ファイル: arp.c プロジェクト: forest1040/kozos
static int arp_proc(struct netbuf *buf)
{
  int ret = 0;

  switch (buf->cmd) {
  case ARP_CMD_MACADDR:
    memcpy(my_macaddr, buf->option.common.macaddr.addr, MACADDR_SIZE);
    break;
  case ARP_CMD_IPADDR:
    my_ipaddr = buf->option.common.ipaddr.addr;
    break;
  case ARP_CMD_RECV:
    ret = arp_recv(buf);
    break;
  case ARP_CMD_SEND:
    ret = arp_send(buf);
    break;
  default:
    break;
  }

  return ret;
}
コード例 #18
0
ファイル: Arp.c プロジェクト: cqqqh/CK_keil_cankao
//------------------------------------------------------------------------
// This re-sends an ARP request if there was no response to
// the first one.	 It is called every 0.5 seconds.  If there
// is no response after 2 re-tries, the datagram that IP was 
// trying to send is deleted
//-----------------------------------------------------------------------
void arp_retransmit(void)
{
	static UCHAR idata retries = 0; 
	
	if ((waiting_for_arp) && (wait.timer))
	{
		wait.timer--;
		if (wait.timer == 0)
		{
			retries++;
			if (retries <= 2)
			{
	 			arp_send(NULL, wait.ipaddr, ARP_REQUEST);
				wait.timer = ARP_TIMEOUT;
			}
			else
			{	
	 			wait.timer = 0;
				waiting_for_arp = 0;
//				free(wait.buf);
			}
		}
	}
}
コード例 #19
0
ファイル: arp.c プロジェクト: 274914765/C
static int arp_process(struct sk_buff *skb)
{
    struct net_device *dev = skb->dev;
    struct in_device *in_dev = in_dev_get(dev);
    struct arphdr *arp;
    unsigned char *arp_ptr;
    struct rtable *rt;
    unsigned char *sha;
    __be32 sip, tip;
    u16 dev_type = dev->type;
    int addr_type;
    struct neighbour *n;
    struct net *net = dev_net(dev);

    /* arp_rcv below verifies the ARP header and verifies the device
     * is ARP'able.
     */

    if (in_dev == NULL)
        goto out;

    arp = arp_hdr(skb);

    switch (dev_type) {
    default:
        if (arp->ar_pro != htons(ETH_P_IP) ||
            htons(dev_type) != arp->ar_hrd)
            goto out;
        break;
    case ARPHRD_ETHER:
    case ARPHRD_IEEE802_TR:
    case ARPHRD_FDDI:
    case ARPHRD_IEEE802:
        /*
         * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802
         * devices, according to RFC 2625) devices will accept ARP
         * hardware types of either 1 (Ethernet) or 6 (IEEE 802.2).
         * This is the case also of FDDI, where the RFC 1390 says that
         * FDDI devices should accept ARP hardware of (1) Ethernet,
         * however, to be more robust, we'll accept both 1 (Ethernet)
         * or 6 (IEEE 802.2)
         */
        if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
             arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
            arp->ar_pro != htons(ETH_P_IP))
            goto out;
        break;
    case ARPHRD_AX25:
        if (arp->ar_pro != htons(AX25_P_IP) ||
            arp->ar_hrd != htons(ARPHRD_AX25))
            goto out;
        break;
    case ARPHRD_NETROM:
        if (arp->ar_pro != htons(AX25_P_IP) ||
            arp->ar_hrd != htons(ARPHRD_NETROM))
            goto out;
        break;
    }

    /* Understand only these message types */

    if (arp->ar_op != htons(ARPOP_REPLY) &&
        arp->ar_op != htons(ARPOP_REQUEST))
        goto out;

/*
 *    Extract fields
 */
    arp_ptr= (unsigned char *)(arp+1);
    sha    = arp_ptr;
    arp_ptr += dev->addr_len;
    memcpy(&sip, arp_ptr, 4);
    arp_ptr += 4;
    arp_ptr += dev->addr_len;
    memcpy(&tip, arp_ptr, 4);
/*
 *    Check for bad requests for 127.x.x.x and requests for multicast
 *    addresses.  If this is one such, delete it.
 */
    if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
        goto out;

/*
 *     Special case: We must set Frame Relay source Q.922 address
 */
    if (dev_type == ARPHRD_DLCI)
        sha = dev->broadcast;

/*
 *  Process entry.  The idea here is we want to send a reply if it is a
 *  request for us or if it is a request for someone else that we hold
 *  a proxy for.  We want to add an entry to our cache if it is a reply
 *  to us or if it is a request for our address.
 *  (The assumption for this last is that if someone is requesting our
 *  address, they are probably intending to talk to us, so it saves time
 *  if we cache their address.  Their address is also probably not in
 *  our cache, since ours is not in their cache.)
 *
 *  Putting this another way, we only care about replies if they are to
 *  us, in which case we add them to the cache.  For requests, we care
 *  about those for us and those for our proxies.  We reply to both,
 *  and in the case of requests for us we add the requester to the arp
 *  cache.
 */

    /* Special case: IPv4 duplicate address detection packet (RFC2131) */
    if (sip == 0) {
        if (arp->ar_op == htons(ARPOP_REQUEST) &&
            inet_addr_type(net, tip) == RTN_LOCAL &&
            !arp_ignore(in_dev, sip, tip))
            arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
                 dev->dev_addr, sha);
        goto out;
    }

    if (arp->ar_op == htons(ARPOP_REQUEST) &&
        ip_route_input(skb, tip, sip, 0, dev) == 0) {

        rt = skb->rtable;
        addr_type = rt->rt_type;

        if (addr_type == RTN_LOCAL) {
            n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
            if (n) {
                int dont_send = 0;

                if (!dont_send)
                    dont_send |= arp_ignore(in_dev,sip,tip);
                if (!dont_send && IN_DEV_ARPFILTER(in_dev))
                    dont_send |= arp_filter(sip,tip,dev);
                if (!dont_send)
                    arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);

                neigh_release(n);
            }
            goto out;
        } else if (IN_DEV_FORWARD(in_dev)) {
                if (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
                 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) {
                n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
                if (n)
                    neigh_release(n);

                if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
                    skb->pkt_type == PACKET_HOST ||
                    in_dev->arp_parms->proxy_delay == 0) {
                    arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
                } else {
                    pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);
                    in_dev_put(in_dev);
                    return 0;
                }
                goto out;
            }
        }
    }

    /* Update our ARP tables */

    n = __neigh_lookup(&arp_tbl, &sip, dev, 0);

    if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) {
        /* Unsolicited ARP is not accepted by default.
           It is possible, that this option should be enabled for some
           devices (strip is candidate)
         */
        if (n == NULL &&
            arp->ar_op == htons(ARPOP_REPLY) &&
            inet_addr_type(net, sip) == RTN_UNICAST)
            n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
    }

    if (n) {
        int state = NUD_REACHABLE;
        int override;

        /* If several different ARP replies follows back-to-back,
           use the FIRST one. It is possible, if several proxy
           agents are active. Taking the first reply prevents
           arp trashing and chooses the fastest router.
         */
        override = time_after(jiffies, n->updated + n->parms->locktime);

        /* Broadcast replies and request packets
           do not assert neighbour reachability.
         */
        if (arp->ar_op != htons(ARPOP_REPLY) ||
            skb->pkt_type != PACKET_HOST)
            state = NUD_STALE;
        neigh_update(n, sha, state, override ? NEIGH_UPDATE_F_OVERRIDE : 0);
        neigh_release(n);
    }
コード例 #20
0
ファイル: echo.c プロジェクト: millken/zhuxianB30
s32 mpls_echo_input(struct sk_buff * skb)
{
    s32 err = 0;
    s32 temp = 0;
    u32 saddr = 0;
    struct timeval tv;
    mpls_echo_hdr * echo;
    struct ethhdr * eth ;
    struct fib_mg_res res ;
    struct iphdr *iph = skb->nh.iph;
    struct udphdr * udph = skb->h.uh;
    
    echo = (mpls_echo_hdr *)(skb->data + sizeof(struct udphdr));
    skb_push(skb, iph->ihl * 4);
    err = fib_mg_lookup(if_dev_vrf(skb->dev)->vrf_id, iph->saddr, 32, &res);   
    if (err)
    {
        printk("mpls_echo_input -fib_mg_lookup drop.\n");
        goto drop;
    }
    
    temp = iph->daddr;
    iph->daddr = iph->saddr;
    if (res.dev)
    {
        iph->saddr = inet_select_addr(res.dev, res.nexthop, RT_SCOPE_LINK);
    }
    else
    {
        iph->saddr = temp;
    }
    iph->ttl = 255;
    iph->check = 0;
    iph->check = ip_fast_csum(iph, iph->ihl);

    echo->type = MPLS_ECHO_REPLY;
    do_gettimeofday(&tv);
    echo->t_rcvd[0] = htonl(tv.tv_sec+JAN_1970);
    echo->t_rcvd[1] = NTPFRAC(tv.tv_usec);

    temp = udph->source;
    udph->source = udph->dest;
    udph->dest = temp;
    
    if (MPLS_MODE_DO_NOT_REPLY == echo->mode)
    {
        printk("mpls_echo_input -not reply mode drop.\n");
        goto drop;
    }
    
    if (MPLS_MODE_IPX_UDP_ALERT == echo->mode)
    {
        //Push router alert to ip option.
    }

    skb->protocol = htons(ETH_P_IP);
    if (FIB_MG_TYPE_FTN_BASIC == res.type)
    {
        if (MPLS_IMPLICIT_NULL != MPLS_LABEL(res.glabel))
        {
            skb->protocol = htons(ETH_P_MPLS_UC) ;
            skb_push_label(skb, 128, res.glabel, 1);
        }

        if (2 == res.count)
        {
            if (MPLS_IMPLICIT_NULL != MPLS_LABEL(res.glabel2))
            {
                skb->protocol = htons(ETH_P_MPLS_UC) ;
                skb_push_label(skb, 128, res.glabel2, 0);
            }
        }
    }
    else
    {
        skb->protocol = htons(ETH_P_MPLS_UC) ;
        skb_push_label(skb, 128, res.label, 1);
        
        if (MPLS_IMPLICIT_NULL != MPLS_LABEL(res.glabel))
        {
            skb_push_label(skb, 128, res.glabel, 0);
        }

        if (3 == res.count)
        {
            if (MPLS_IMPLICIT_NULL != MPLS_LABEL(res.glabel2))
            {
                skb->protocol = htons(ETH_P_MPLS_UC) ;
                skb_push_label(skb, 128, res.glabel2, 0);
            }
        }
    }

    if (MPLS_MODE_CTRL_CHANNEL == echo->mode)
    {
        skb_push_label(skb, 128, 1, 0);
    }

    skb->nh.raw = skb->data;
    
    skb->dev = res.dev;

    if (!res.neigh)
    {
        res.neigh = __neigh_arp_lookup(&arp_tbl, &res.nexthop, NULL, res.dev, NEIGHBOUR_CREAT);
    }
    
    read_lock_bh(&res.neigh->lock);
    
    if (!(res.neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
    {
        saddr = inet_select_addr(res.dev, res.nexthop, RT_SCOPE_LINK);
    
        arp_send(ARPOP_REQUEST, ETH_P_ARP, res.nexthop, res.dev, saddr,
           res.neigh->ha, res.dev->dev_addr, NULL);
        read_unlock_bh(&res.neigh->lock);
        printk("mpls_echo_input -neigh invalid drop.\n");
        goto drop;
    }

    eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
    eth->h_proto = (ETH_P_802_3 != skb->protocol) ? htons(skb->protocol) : htons(skb->len);
    memcpy(eth->h_source, res.dev->dev_addr, res.dev->addr_len);
    memcpy(eth->h_dest, res.neigh->ha, res.dev->addr_len);
    skb->mac.raw = skb->data ;
    skb->mac_len = ETH_HLEN; 

    read_unlock_bh(&res.neigh->lock);
        
    neigh_release(res.neigh);
    dev_queue_xmit(skb);
    
    return 0;
drop:
    kfree_skb(skb);
    return -1;
}
コード例 #21
0
ssize_t psock_tcp_send(FAR struct socket *psock,
                       FAR const void *buf, size_t len)
{
  FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn;
  struct send_s state;
  net_lock_t save;
  int err;
  int ret = OK;

  /* Verify that the sockfd corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      ndbg("ERROR: Invalid socket\n");
      err = EBADF;
      goto errout;
    }

  /* If this is an un-connected socket, then return ENOTCONN */

  if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
    {
      ndbg("ERROR: Not connected\n");
      err = ENOTCONN;
      goto errout;
    }

  /* Make sure that we have the IP address mapping */

  conn = (FAR struct tcp_conn_s *)psock->s_conn;
  DEBUGASSERT(conn);

#if defined(CONFIG_NET_ARP_SEND) || defined(CONFIG_NET_ICMPv6_NEIGHBOR)
#ifdef CONFIG_NET_ARP_SEND
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
  if (psock->s_domain == PF_INET)
#endif
    {
      /* Make sure that the IP address mapping is in the ARP table */

      ret = arp_send(conn->u.ipv4.raddr);
    }
#endif /* CONFIG_NET_ARP_SEND */


#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
#ifdef CONFIG_NET_ARP_SEND
  else
#endif
    {
      /* Make sure that the IP address mapping is in the Neighbor Table */

      ret = icmpv6_neighbor(conn->u.ipv6.raddr);
    }
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */

  /* Did we successfully get the address mapping? */

  if (ret < 0)
    {
      ndbg("ERROR: Not reachable\n");
      err = ENETUNREACH;
      goto errout;
    }
#endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */

  /* Set the socket state to sending */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);

  /* Perform the TCP send operation */

  /* Initialize the state structure.  This is done with interrupts
   * disabled because we don't want anything to happen until we
   * are ready.
   */

  save                = net_lock();
  memset(&state, 0, sizeof(struct send_s));
  (void)sem_init(&state.snd_sem, 0, 0);    /* Doesn't really fail */
  state.snd_sock      = psock;             /* Socket descriptor to use */
  state.snd_buflen    = len;               /* Number of bytes to send */
  state.snd_buffer    = buf;               /* Buffer to send from */

  if (len > 0)
    {
      /* Allocate resources to receive a callback */

      state.snd_cb = tcp_callback_alloc(conn);
      if (state.snd_cb)
        {
          /* Get the initial sequence number that will be used */

          state.snd_isn         = tcp_getsequence(conn->sndseq);

          /* There is no outstanding, unacknowledged data after this
           * initial sequence number.
           */

          conn->unacked         = 0;

          /* Set the initial time for calculating timeouts */

#ifdef CONFIG_NET_SOCKOPTS
          state.snd_time        = clock_systimer();
#endif
          /* Set up the callback in the connection */

          state.snd_cb->flags   = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
                                   TCP_DISCONN_EVENTS);
          state.snd_cb->priv    = (FAR void *)&state;
          state.snd_cb->event   = tcpsend_interrupt;

          /* Notify the device driver of the availability of TX data */

          send_txnotify(psock, conn);

          /* Wait for the send to complete or an error to occur:  NOTES: (1)
           * net_lockedwait will also terminate if a signal is received, (2) interrupts
           * may be disabled!  They will be re-enabled while the task sleeps and
           * automatically re-enabled when the task restarts.
           */

          ret = net_lockedwait(&state.snd_sem);

          /* Make sure that no further interrupts are processed */

          tcp_callback_free(conn, state.snd_cb);
        }
    }

  sem_destroy(&state.snd_sem);
  net_unlock(save);

  /* Set the socket state to idle */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

  /* Check for a errors.  Errors are signalled by negative errno values
   * for the send length
   */

  if (state.snd_sent < 0)
    {
      err = state.snd_sent;
      goto errout;
    }

  /* If net_lockedwait failed, then we were probably reawakened by a signal. In
   * this case, net_lockedwait will have set errno appropriately.
   */

  if (ret < 0)
    {
      err = -ret;
      goto errout;
    }

  /* Return the number of bytes actually sent */

  return state.snd_sent;

errout:
  set_errno(err);
  return ERROR;
}
コード例 #22
0
ファイル: arpspoof.c プロジェクト: 8003178550/dsploit
int main(int argc, char *argv[])
{
	extern char *optarg;
	extern int   optind;
	char			   pcap_ebuf[PCAP_ERRBUF_SIZE];
	char 				 libnet_ebuf[LIBNET_ERRBUF_SIZE];
	int 				 c,
			 	 	 	 	 netmask = 0,
			 	 	 	 	 ifaddr  = 0,
			 	 	 	 	 nhosts  = 0,
			 	 	 	 	 i			 = 0;
	network_entry_t *entry;

	iface			 = NULL;
	gateway_ip = target_ip = 0;

	printf( "dSploit ArpSpoofer.\n\n" );

	while( (c = getopt(argc, argv, "i:t:h?V")) != -1)
	{
		switch (c)
		{
		case 'i':
			iface = optarg;
			break;
		case 't':
			if ((target_ip = libnet_name2addr4(lnet, optarg, LIBNET_RESOLVE)) == -1)
				exit(1);
			break;
		default:
			return 1;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 1)
		return 1;

	if( ( gateway_ip = libnet_name2addr4( lnet, argv[0], LIBNET_RESOLVE ) ) == -1 )
	{
		printf( "[ERROR] Unable to resolve gateway ip.\n" );
		return 1;
	}

	if( iface == NULL && (iface = pcap_lookupdev(pcap_ebuf)) == NULL )
	{
		printf( "[ERROR] Unable to lookup network interface ( %s ).\n", pcap_ebuf );
		return 1;
	}

	if( ( lnet = libnet_init(LIBNET_LINK, iface, libnet_ebuf) ) == NULL )
	{
		printf( "[ERROR] Unable to initialize libnet ( %s ).\n", libnet_ebuf );
		return 1;
	}

	signal( SIGHUP, cleanup );
	signal( SIGINT, cleanup );
	signal( SIGTERM, cleanup );

	our_mac = ( struct ether_addr * )libnet_get_hwaddr( lnet );
	if( our_mac == NULL )
	{
		printf( "[ERROR] Unable to retrieve local hardware address libnet ( %s ).\n", libnet_geterror( lnet ) );
		return 1;
	}

	if( net_get_details( iface, &netmask, &ifaddr, &nhosts ) != 0 )
		exit( 1 );

	printf( "netmask = %s\n", inet_ntoa( *( struct in_addr *)&netmask ) );
	printf( "ifaddr  = %s\n", inet_ntoa( *( struct in_addr *)&ifaddr ) );
	printf( "gateway = %s\n", inet_ntoa( *( struct in_addr *)&gateway_ip ) );
	printf( "hosts   = %d\n", nhosts );

	// force the arp cache to be populated
	net_wake( iface, nhosts, ifaddr, netmask, gateway_ip );

	// if the target is the gateway itself, we switch to subnet mode,
	// otherwise if the target was set, we are in single ip spoofing mode.
	if( target_ip != 0 && target_ip != gateway_ip )
	{
		if( target_ip != 0 && arp_lookup( target_ip, &target_mac, iface ) != 0 )
		{
			printf( "[ERROR] Couldn't find a cached MAC address for %s, try to wait a little bit and then try again or restart the network discovery.\n", libnet_addr2name4(target_ip, LIBNET_DONT_RESOLVE) );
			return 1;
		}

		printf( "\nSingle target mode.\n" );

		while( killed == 0 )
		{
			arp_send( lnet, ARPOP_REPLY, (unsigned char *)our_mac, gateway_ip, (unsigned char *)&target_mac, target_ip );
			sleep(1);
		}
	}
	// whole network spoofing
	else
	{
		printf( "\nSubnet mode.\n" );

		netmap = net_get_mapping( iface, nhosts, ifaddr, netmask, gateway_ip, &i );

		if( i == 0 )
		{
			printf( "[ERROR] No alive endpoints found.\n" );
			return 1;
		}

		while( killed == 0 )
		{
			for( i = 1; i <= nhosts && killed == 0; i++ )
			{
				target_ip = ( ifaddr & netmask ) | htonl(i);

				entry = hashmapGet( netmap, (void *)target_ip );
				if( entry && killed == 0 )
				{
					arp_send( lnet, ARPOP_REPLY, (unsigned char *)our_mac, gateway_ip, (unsigned char *)&entry->mac, target_ip );
				}
			}

			sleep(1);
		}

	}

	return 0;
}
コード例 #23
0
ファイル: arp.c プロジェクト: Alex-V2/One_M8_4.4.3_kernel
static int arp_process(struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	struct in_device *in_dev = __in_dev_get_rcu(dev);
	struct arphdr *arp;
	unsigned char *arp_ptr;
	struct rtable *rt;
	unsigned char *sha;
	__be32 sip, tip;
	u16 dev_type = dev->type;
	int addr_type;
	struct neighbour *n;
	struct net *net = dev_net(dev);


	if (in_dev == NULL)
		goto out;

	arp = arp_hdr(skb);

	switch (dev_type) {
	default:
		if (arp->ar_pro != htons(ETH_P_IP) ||
		    htons(dev_type) != arp->ar_hrd)
			goto out;
		break;
	case ARPHRD_ETHER:
	case ARPHRD_IEEE802_TR:
	case ARPHRD_FDDI:
	case ARPHRD_IEEE802:
		if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
		     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
		    arp->ar_pro != htons(ETH_P_IP))
			goto out;
		break;
	case ARPHRD_AX25:
		if (arp->ar_pro != htons(AX25_P_IP) ||
		    arp->ar_hrd != htons(ARPHRD_AX25))
			goto out;
		break;
	case ARPHRD_NETROM:
		if (arp->ar_pro != htons(AX25_P_IP) ||
		    arp->ar_hrd != htons(ARPHRD_NETROM))
			goto out;
		break;
	}

	

	if (arp->ar_op != htons(ARPOP_REPLY) &&
	    arp->ar_op != htons(ARPOP_REQUEST))
		goto out;

	arp_ptr = (unsigned char *)(arp + 1);
	sha	= arp_ptr;
	arp_ptr += dev->addr_len;
	memcpy(&sip, arp_ptr, 4);
	arp_ptr += 4;
	arp_ptr += dev->addr_len;
	memcpy(&tip, arp_ptr, 4);
	if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
		goto out;

	if (dev_type == ARPHRD_DLCI)
		sha = dev->broadcast;


	
	if (sip == 0) {
		if (arp->ar_op == htons(ARPOP_REQUEST) &&
		    inet_addr_type(net, tip) == RTN_LOCAL &&
		    !arp_ignore(in_dev, sip, tip))
			arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
				 dev->dev_addr, sha);
		goto out;
	}

	if (arp->ar_op == htons(ARPOP_REQUEST) &&
	    ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {

		rt = skb_rtable(skb);
		addr_type = rt->rt_type;

		if (addr_type == RTN_LOCAL) {
			int dont_send;

			dont_send = arp_ignore(in_dev, sip, tip);
			if (!dont_send && IN_DEV_ARPFILTER(in_dev))
				dont_send = arp_filter(sip, tip, dev);
			if (!dont_send) {
				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
				if (n) {
					arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
						 dev, tip, sha, dev->dev_addr,
						 sha);
					neigh_release(n);
				}
			}
			goto out;
		} else if (IN_DEV_FORWARD(in_dev)) {
			if (addr_type == RTN_UNICAST  &&
			    (arp_fwd_proxy(in_dev, dev, rt) ||
			     arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
			     (rt->dst.dev != dev &&
			      pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
				if (n)
					neigh_release(n);

				if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
				    skb->pkt_type == PACKET_HOST ||
				    in_dev->arp_parms->proxy_delay == 0) {
					arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
						 dev, tip, sha, dev->dev_addr,
						 sha);
				} else {
					pneigh_enqueue(&arp_tbl,
						       in_dev->arp_parms, skb);
					return 0;
				}
				goto out;
			}
		}
	}

	

	n = __neigh_lookup(&arp_tbl, &sip, dev, 0);

	if (IN_DEV_ARP_ACCEPT(in_dev)) {
		if (n == NULL &&
		    (arp->ar_op == htons(ARPOP_REPLY) ||
		     (arp->ar_op == htons(ARPOP_REQUEST) && tip == sip)) &&
		    inet_addr_type(net, sip) == RTN_UNICAST)
			n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
	}

	if (n) {
		int state = NUD_REACHABLE;
		int override;

		override = time_after(jiffies, n->updated + n->parms->locktime);

		if (arp->ar_op != htons(ARPOP_REPLY) ||
		    skb->pkt_type != PACKET_HOST)
			state = NUD_STALE;
		neigh_update(n, sha, state,
			     override ? NEIGH_UPDATE_F_OVERRIDE : 0);
		neigh_release(n);
	}
コード例 #24
0
ファイル: arp.c プロジェクト: Alex-V2/One_M8_4.4.3_kernel
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
	__be32 saddr = 0;
	u8  *dst_ha = NULL;
	struct net_device *dev = neigh->dev;
	__be32 target = *(__be32 *)neigh->primary_key;
	int probes = atomic_read(&neigh->probes);
	struct in_device *in_dev;

    
    #ifdef CONFIG_HTC_NETWORK_CNE
    __be32 dev_addr = 0;
    dev_addr = inet_select_addr(dev, target, RT_SCOPE_LINK);
    #endif
    

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(dev);
	if (!in_dev) {
		rcu_read_unlock();
		return;
	}
	switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
	default:
	case 0:		
		if (skb && inet_addr_type(dev_net(dev),
					  ip_hdr(skb)->saddr) == RTN_LOCAL)
			saddr = ip_hdr(skb)->saddr;
		break;
	case 1:		
		if (!skb)
			break;
		saddr = ip_hdr(skb)->saddr;
		if (inet_addr_type(dev_net(dev), saddr) == RTN_LOCAL) {
			
			if (inet_addr_onlink(in_dev, target, saddr))
				break;
		}
		saddr = 0;
		break;
	case 2:		
		break;
	}
	rcu_read_unlock();

	if (!saddr)
		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);

	probes -= neigh->parms->ucast_probes;
	if (probes < 0) {
		if (!(neigh->nud_state & NUD_VALID))
			printk(KERN_DEBUG
			       "trying to ucast probe in NUD_INVALID\n");
		dst_ha = neigh->ha;
		read_lock_bh(&neigh->lock);
	} else {
		probes -= neigh->parms->app_probes;
		if (probes < 0) {
#ifdef CONFIG_ARPD
			neigh_app_ns(neigh);
#endif
			return;
		}
	}

    
    #ifdef CONFIG_HTC_NETWORK_CNE
    if (dev_addr != saddr)
    {
        printk(KERN_DEBUG "CnE detects wrong sender IP in ARP\n");
        saddr = dev_addr;
    }
    #endif
    

	arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
		 dst_ha, dev->dev_addr, NULL);
	if (dst_ha)
		read_unlock_bh(&neigh->lock);
}
コード例 #25
0
ファイル: sendto.c プロジェクト: KimMui/i2sTest
ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
                     size_t len, int flags, FAR const struct sockaddr *to,
                     socklen_t tolen)
{
#ifdef CONFIG_NET_UDP
  FAR struct udp_conn_s *conn;
#ifdef CONFIG_NET_IPv6
  FAR const struct sockaddr_in6 *into = (const struct sockaddr_in6 *)to;
#else
  FAR const struct sockaddr_in *into = (const struct sockaddr_in *)to;
#endif
  struct sendto_s state;
  net_lock_t save;
  int ret;
#endif
  int err;

  /* If to is NULL or tolen is zero, then this function is same as send (for
   * connected socket types)
   */

  if (!to || !tolen)
    {
#ifdef CONFIG_NET_TCP
      return psock_send(psock, buf, len, flags);
#else
      ndbg("ERROR: No to address\n");
      err = EINVAL;
      goto errout;
#endif
    }

  /* Verify that a valid address has been provided */

#ifdef CONFIG_NET_IPv6
  if (to->sa_family != AF_INET6 || tolen < sizeof(struct sockaddr_in6))
#else
  if (to->sa_family != AF_INET || tolen < sizeof(struct sockaddr_in))
#endif
  {
      ndbg("ERROR: Invalid address\n");
      err = EBADF;
      goto errout;
  }

  /* Verify that the psock corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      ndbg("ERROR: Invalid socket\n");
      err = EBADF;
      goto errout;
    }

  /* If this is a connected socket, then return EISCONN */

  if (psock->s_type != SOCK_DGRAM)
    {
      ndbg("ERROR: Connected socket\n");
      err = EISCONN;
      goto errout;
    }

  /* Make sure that the IP address mapping is in the ARP table */

#ifdef CONFIG_NET_ARP_SEND
  ret = arp_send(into->sin_addr.s_addr);
  if (ret < 0)
    {
      ndbg("ERROR: Not reachable\n");
      err = ENETUNREACH;
      goto errout;
    }
#endif

  /* Perform the UDP sendto operation */

#ifdef CONFIG_NET_UDP
  /* Set the socket state to sending */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);

  /* Initialize the state structure.  This is done with interrupts
   * disabled because we don't want anything to happen until we
   * are ready.
   */

  save = net_lock();
  memset(&state, 0, sizeof(struct sendto_s));
  sem_init(&state.st_sem, 0, 0);
  state.st_buflen = len;
  state.st_buffer = buf;

  /* Set the initial time for calculating timeouts */

#ifdef CONFIG_NET_SENDTO_TIMEOUT
  state.st_sock = psock;
  state.st_time = clock_systimer();
#endif

  /* Setup the UDP socket */

  conn = (FAR struct udp_conn_s *)psock->s_conn;
  ret = udp_connect(conn, into);
  if (ret < 0)
    {
      net_unlock(save);
      err = -ret;
      goto errout;
    }

  /* Set up the callback in the connection */

  state.st_cb = udp_callback_alloc(conn);
  if (state.st_cb)
    {
      state.st_cb->flags   = UDP_POLL;
      state.st_cb->priv    = (void*)&state;
      state.st_cb->event   = sendto_interrupt;

      /* Notify the device driver of the availabilty of TX data */

      netdev_txnotify(conn->ripaddr);

      /* Wait for either the receive to complete or for an error/timeout to occur.
       * NOTES:  (1) net_lockedwait will also terminate if a signal is received, (2)
       * interrupts may be disabled!  They will be re-enabled while the task sleeps
       * and automatically re-enabled when the task restarts.
       */

      net_lockedwait(&state.st_sem);

      /* Make sure that no further interrupts are processed */

      udp_callback_free(conn, state.st_cb);
    }

  net_unlock(save);
  sem_destroy(&state.st_sem);

  /* Set the socket state to idle */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

  /* Check for errors */

  if (state.st_sndlen < 0)
    {
      err = -state.st_sndlen;
      goto errout;
    }

  /* Success */

  return state.st_sndlen;
#else
  err = ENOSYS;
#endif

errout:
  set_errno(err);
  return ERROR;
}
コード例 #26
0
ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
                     size_t count)
{
  FAR struct socket *psock = sockfd_socket(outfd);
  FAR struct tcp_conn_s *conn;
  struct sendfile_s state;
  net_lock_t save;
  int err;

  /* Verify that the sockfd corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      ndbg("ERROR: Invalid socket\n");
      err = EBADF;
      goto errout;
    }

  /* If this is an un-connected socket, then return ENOTCONN */

  if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
    {
      ndbg("ERROR: Not connected\n");
      err = ENOTCONN;
      goto errout;
    }

  /* Make sure that we have the IP address mapping */

  conn = (FAR struct tcp_conn_s *)psock->s_conn;
  DEBUGASSERT(conn);

#if defined(CONFIG_NET_ARP_SEND) || defined(CONFIG_NET_ICMPv6_NEIGHBOR)
#ifdef CONFIG_NET_ARP_SEND
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
  if (psock->s_domain == PF_INET)
#endif
    {
      /* Make sure that the IP address mapping is in the ARP table */

      ret = arp_send(conn->u.ipv4.raddr);
    }
#endif /* CONFIG_NET_ARP_SEND */


#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
#ifdef CONFIG_NET_ARP_SEND
  else
#endif
    {
      /* Make sure that the IP address mapping is in the Neighbor Table */

      ret = icmpv6_neighbor(conn->u.ipv6.raddr);
    }
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */

  /* Did we successfully get the address mapping? */

  if (ret < 0)
    {
      ndbg("ERROR: Not reachable\n");
      err = ENETUNREACH;
      goto errout;
    }
#endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */

  /* Set the socket state to sending */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);

  /* Initialize the state structure.  This is done with interrupts
   * disabled because we don't want anything to happen until we
   * are ready.
   */

  save  = net_lock();

  memset(&state, 0, sizeof(struct sendfile_s));
  sem_init(&state. snd_sem, 0, 0);          /* Doesn't really fail */
  state.snd_sock    = psock;                /* Socket descriptor to use */
  state.snd_foffset = offset ? *offset : 0; /* Input file offset */
  state.snd_flen    = count;                /* Number of bytes to send */
  state.snd_file    = infile;               /* File to read from */

  /* Allocate resources to receive a callback */

  state.snd_datacb = tcp_callback_alloc(conn);

  if (state.snd_datacb == NULL)
    {
      nlldbg("Failed to allocate data callback\n");
      err = ENOMEM;
      goto errout_locked;
    }

  state.snd_ackcb = tcp_callback_alloc(conn);

  if (state.snd_ackcb == NULL)
    {
      nlldbg("Failed to allocate ack callback\n");
      err = ENOMEM;
      goto errout_datacb;
    }

  /* Get the initial sequence number that will be used */

  state.snd_isn          = tcp_getsequence(conn->sndseq);

  /* There is no outstanding, unacknowledged data after this
   * initial sequence number.
   */

  conn->unacked          = 0;

#ifdef CONFIG_NET_SOCKOPTS
  /* Set the initial time for calculating timeouts */

  state.snd_time         = clock_systimer();
#endif

  /* Set up the ACK callback in the connection */

  state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_DISCONN_EVENTS);
  state.snd_ackcb->priv  = (FAR void *)&state;
  state.snd_ackcb->event = ack_interrupt;

  /* Perform the TCP send operation */

  do
    {
      state.snd_datacb->flags = TCP_POLL;
      state.snd_datacb->priv  = (FAR void *)&state;
      state.snd_datacb->event = sendfile_interrupt;

      /* Notify the device driver of the availability of TX data */

      sendfile_txnotify(psock, conn);
      net_lockedwait(&state.snd_sem);
    }
  while (state.snd_sent >= 0 && state.snd_acked < state.snd_flen);

  /* Set the socket state to idle */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

  tcp_callback_free(conn, state.snd_ackcb);

errout_datacb:
  tcp_callback_free(conn, state.snd_datacb);

errout_locked:

  sem_destroy(&state. snd_sem);
  net_unlock(save);

errout:

  if (err)
    {
      set_errno(err);
      return ERROR;
    }
  else if (state.snd_sent < 0)
    {
      set_errno(-state.snd_sent);
      return ERROR;
    }
  else
    {
      return state.snd_sent;
    }
}
コード例 #27
0
ファイル: arpspoof.c プロジェクト: Affix/dsniff
int
main(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	char pcap_ebuf[PCAP_ERRBUF_SIZE];
	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
	int c;
	int n_scan_hosts = 0;
	char *scan_prefix = NULL;
	int scan_prefix_length = 32;
	char *cleanup_src = NULL;
	in_addr_t target_addr;

	intf = NULL;
	poison_reverse = 0;
	poison_mesh = 0;
	n_hosts = 0;

	/* allocate enough memory for target list */
	hosts = calloc( argc+1, sizeof(struct host) );

	while ((c = getopt(argc, argv, "vrmi:s:t:c:h?V")) != -1) {
		switch (c) {
		case 'v':
			verbose = 1;
			break;
		case 'i':
			intf = optarg;
			break;
		case 't':
			target_addr = libnet_name2addr4(l, optarg, LIBNET_RESOLVE);
			if (target_addr == -1) {
				usage();
			} else {
				host_add(target_addr, HOST_TARGET);
			}
			break;
		case 'r':
			poison_reverse = 1;
			break;
		case 'm':
			poison_mesh = 1;
			break;
		case 's':
			scan_prefix = strchr(optarg, '/');
			if (scan_prefix) {
				*scan_prefix = '\0';
				scan_prefix_length = atoi(scan_prefix+1);
				if (scan_prefix_length < 0 || scan_prefix_length > 32) {
					usage();
				}
			}
			n_scan_hosts += (1<<(32-scan_prefix_length));
			/* we need some more memory to store the target data */
			int mem = (argc+1 + n_scan_hosts) * sizeof(struct host);
			hosts = realloc( hosts, mem );
			hosts[n_hosts].ip = (uint32_t)0;
			subnet_add(inet_addr(optarg), scan_prefix_length, HOST_TARGET);
			break;
		case 'c':
			cleanup_src = optarg;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	
	if (!cleanup_src || strcmp(cleanup_src, "own")==0) { /* default! */
		/* only use our own hw address when cleaning up,
		 * not jeopardizing any bridges on the way to our
		 * target
		 */
		cleanup_src_own = 1;
		cleanup_src_host = 0;
	} else if (strcmp(cleanup_src, "host")==0) {
		/* only use the target hw address when cleaning up;
		 * this can screw up some bridges and scramble access
		 * for our own host, however it resets the arp table
		 * more reliably
		 */
		cleanup_src_own = 0;
		cleanup_src_host = 1;
	} else if (strcmp(cleanup_src, "both")==0) {
		cleanup_src_own = 1;
		cleanup_src_host = 1;
	} else {
		errx(1, "Invalid parameter to -c: use 'own' (default), 'host' or 'both'.");
		usage();
	}

	while (argc--) {
		if ((target_addr = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) {
			errx(1, "Invalid address: %s", argv[0]);
			usage();
		}
		host_add(target_addr, HOST_MODEL);
		argv++;
	}

	if (poison_mesh) {
		struct host *host = hosts;
		for(;host->ip; host++) {
			host->flags |= (HOST_TARGET|HOST_MODEL);
		}
	}

	if (poison_reverse && active_targets() <= 0) {
		errx(1, "Spoofing the reverse path (-r) is only available when specifying at least one target (-t/-s).");
		usage();
	}

	if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL)
		errx(1, "%s", pcap_ebuf);
	
	if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL)
		errx(1, "%s", libnet_ebuf);

	fprintf(stderr, "Scanning %d hw addresses...\n", n_hosts);
	struct host *target = hosts;
	for (; target->ip; target++) {
		if (verbose) {
			fprintf(stderr, "Looking up host %s...\n", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE));
		}
		int arp_status = arp_find(target->ip, &target->mac);
		if (arp_status &&
				/* just make sure we are not getting an empty or broadcast address */
				(memcmp(&target->mac, zero_ha, sizeof(struct ether_addr)) != 0) &&
				(memcmp(&target->mac, brd_ha, sizeof(struct ether_addr)) != 0)) {
			target->flags |= HOST_ACTIVE;
			if (target->flags & HOST_SUBNET) {
				fprintf(stderr, "Found host in subnet %s: %s\n", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE), ether_ntoa((struct ether_addr *)&target->mac));
			}
		} else {
			target->flags &= (~HOST_ACTIVE);
			if (! (target->flags & HOST_SUBNET)) {
				fprintf(stderr, "Unable to find specified host %s\n", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE));
			}
			if (poison_reverse && target->flags & HOST_MODEL) {
				errx(1, "couldn't arp for spoof host %s",
					libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE));
				usage();
			}
		}
	}


	if ((my_ha = (u_int8_t *)libnet_get_hwaddr(l)) == NULL) {
		errx(1, "Unable to determine own mac address");
	}

	if (active_targets() == 0) {
		errx(1, "No target hosts found.");
	}

	signal(SIGHUP, cleanup);
	signal(SIGINT, cleanup);
	signal(SIGTERM, cleanup);

	fprintf(stderr, "Starting spoofing process...\n");
	for (;;) {
		struct host *target = hosts;
		for(;target->ip; target++) {
			if (!(target->flags & HOST_TARGET)) continue;
			if (!(target->flags & HOST_ACTIVE)) continue;
			struct host *model = hosts;
			for (;model->ip; model++) {
				if (!(model->flags & HOST_ACTIVE)) continue;
				if (!(model->flags & HOST_MODEL)) continue;
				if (target->ip != model->ip) {
					arp_send(l, ARPOP_REPLY, my_ha, model->ip,
						(target->ip ? (u_int8_t *)&target->mac : brd_ha),
						target->ip,
						my_ha);
					usleep(ARP_PAUSE);
					if (poison_reverse) {
						arp_send(l, ARPOP_REPLY, my_ha, target->ip, (uint8_t *)&model->mac, model->ip, my_ha);
						usleep(ARP_PAUSE);
					}
				}
			}
		}

		sleep(2);
	}
	/* NOTREACHED */

	exit(0);
}
コード例 #28
0
ファイル: icmp_ping.c プロジェクト: JforGitHub/thingsee-sdk
int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
              int dsecs)
{
  struct icmp_ping_s state;
  net_lock_t save;
#ifdef CONFIG_NET_ARP_SEND
  int ret;

  /* Make sure that the IP address mapping is in the ARP table */

  ret = arp_send(addr);
  if (ret < 0)
    {
      ndbg("ERROR: Not reachable\n");
      return -ENETUNREACH;
    }
#endif

  /* Initialize the state structure */

  sem_init(&state.png_sem, 0, 0);
  state.png_ticks  = DSEC2TICK(dsecs); /* System ticks to wait */
  state.png_result = -ENOMEM;          /* Assume allocation failure */
  state.png_addr   = addr;             /* Address of the peer to be ping'ed */
  state.png_id     = id;               /* The ID to use in the ECHO request */
  state.png_seqno  = seqno;            /* The seqno to use in the ECHO request */
  state.png_datlen = datalen;          /* The length of data to send in the ECHO request */
  state.png_sent   = false;            /* ECHO request not yet sent */

  save             = net_lock();
  state.png_time   = clock_systimer();

  /* Set up the callback */

  state.png_cb = icmp_callback_alloc();
  if (state.png_cb)
    {
      state.png_cb->flags   = (ICMP_POLL | ICMP_ECHOREPLY);
      state.png_cb->priv    = (void*)&state;
      state.png_cb->event   = ping_interrupt;
      state.png_result      = -EINTR; /* Assume sem-wait interrupted by signal */

      /* Notify the device driver of the availability of TX data */

#ifdef CONFIG_NETDEV_MULTINIC
      netdev_ipv4_txnotify(g_ipv4_allzeroaddr, state.png_addr);
#else
      netdev_ipv4_txnotify(state.png_addr);
#endif

      /* Wait for either the full round trip transfer to complete or
       * for timeout to occur. (1) net_lockedwait will also terminate if a
       * signal is received, (2) interrupts may be disabled!  They will
       * be re-enabled while the task sleeps and automatically
       * re-enabled when the task restarts.
       */

      nllvdbg("Start time: 0x%08x seqno: %d\n", state.png_time, seqno);
      net_lockedwait(&state.png_sem);

      icmp_callback_free(state.png_cb);
    }

  net_unlock(save);

  /* Return the negated error number in the event of a failure, or the
   * sequence number of the ECHO reply on success.
   */

  if (!state.png_result)
    {
      nllvdbg("Return seqno=%d\n", state.png_seqno);
      return (int)state.png_seqno;
    }
  else
    {
      nlldbg("Return error=%d\n", -state.png_result);
      return state.png_result;
    }
}
コード例 #29
0
ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
                       size_t len)
{
    FAR struct tcp_conn_s *conn;
    net_lock_t save;
    ssize_t    result = 0;
    int        err;
    int        ret = OK;

    if (!psock || psock->s_crefs <= 0)
    {
        ndbg("ERROR: Invalid socket\n");
        err = EBADF;
        goto errout;
    }

    if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
    {
        ndbg("ERROR: Not connected\n");
        err = ENOTCONN;
        goto errout;
    }

    /* Make sure that the IP address mapping is in the ARP table */

    conn = (FAR struct tcp_conn_s *)psock->s_conn;
#ifdef CONFIG_NET_ARP_SEND
    ret = arp_send(conn->ripaddr);
    if (ret < 0)
    {
        ndbg("ERROR: Not reachable\n");
        err = ENETUNREACH;
        goto errout;
    }
#endif

    /* Dump the incoming buffer */

    BUF_DUMP("psock_tcp_send", buf, len);

    /* Set the socket state to sending */

    psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);

    save = net_lock();

    if (len > 0)
    {
        /* Allocate resources to receive a callback */

        if (!psock->s_sndcb)
        {
            psock->s_sndcb = tcp_callback_alloc(conn);
        }

        /* Test if the callback has been allocated */

        if (!psock->s_sndcb)
        {
            /* A buffer allocation error occurred */

            ndbg("ERROR: Failed to allocate callback\n");
            result = -ENOMEM;
        }
        else
        {
            FAR struct tcp_wrbuffer_s *wrb;

            /* Set up the callback in the connection */

            psock->s_sndcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
                                     TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT);
            psock->s_sndcb->priv  = (void*)psock;
            psock->s_sndcb->event = psock_send_interrupt;

            /* Allocate an write buffer */

            wrb = tcp_wrbuffer_alloc();
            if (wrb)
            {
                /* Initialize the write buffer */

                WRB_SEQNO(wrb) = (unsigned)-1;
                WRB_NRTX(wrb)  = 0;
                WRB_COPYIN(wrb, (FAR uint8_t *)buf, len);

                /* Dump I/O buffer chain */

                WRB_DUMP("I/O buffer chain", wrb, WRB_PKTLEN(wrb), 0);

                /* psock_send_interrupt() will send data in FIFO order from the
                 * conn->write_q
                 */

                sq_addlast(&wrb->wb_node, &conn->write_q);
                nvdbg("Queued WRB=%p pktlen=%u write_q(%p,%p)\n",
                      wrb, WRB_PKTLEN(wrb),
                      conn->write_q.head, conn->write_q.tail);

                /* Notify the device driver of the availability of TX data */

#ifdef CONFIG_NET_MULTILINK
                netdev_txnotify(conn->lipaddr, conn->ripaddr);
#else
                netdev_txnotify(conn->ripaddr);
#endif
                result = len;
            }

            /* A buffer allocation error occurred */

            else
            {
                ndbg("ERROR: Failed to allocate write buffer\n");
                result = -ENOMEM;
            }
        }
    }

    net_unlock(save);

    /* Set the socket state to idle */

    psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

    /* Check for a errors.  Errors are signaled by negative errno values
     * for the send length
     */

    if (result < 0)
    {
        err = result;
        goto errout;
    }

    /* If net_lockedwait failed, then we were probably reawakened by a signal.
     * In this case, net_lockedwait will have set errno appropriately.
     */

    if (ret < 0)
    {
        err = -ret;
        goto errout;
    }

    /* Return the number of bytes actually sent */

    return result;

errout:
    set_errno(err);
    return ERROR;
}
コード例 #30
0
ファイル: ARP.C プロジェクト: david6610/DDNSByMobile
//------------------------------------------------------------------------
// This handles incoming ARP messages
// See "TCP/IP Illustrated, Volume 1" Sect 4.4
// Todo:  Resolve problem of trying to add to a full cache
//------------------------------------------------------------------------
void arp_rcve(UCHAR xdata * inbuf)
{
   UCHAR idata i, cached, oldest;
   UINT idata minimum;
   ARP_HEADER xdata * arp;
      
   arp = (ARP_HEADER xdata *)(inbuf + 14);
   cached = FALSE;
   
   // Print message
   if (debug)
   {
      if (arp->message_type == ARP_REQUEST)
         serial_send("ARP: Request rcvd\r");
      else serial_send("ARP: Response rcvd\r");
   }
         
   // Validate incoming frame
   if ((arp->hardware_type != DIX_ETHERNET) ||
       (arp->protocol_type != IP_PACKET)) return;

   // Search ARP cache for senders IP address
   // If found, update entry and restart timer
   for (i=0; i < CACHESIZE; i++)
   {
      if (arp_cache[i].ipaddr == arp->source_ipaddr)
      {
         memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
         arp_cache[i].timer = CACHETIME;		
         cached = TRUE;
         if (debug) serial_send("ARP: Cache entry updated\r");
                  
         break;  
      }
   }
   
   if (arp->dest_ipaddr != my_ipaddr) return;
   
   // At this point we know the the frame is addressed to me
   // If not already in cache then add entry and start timer
   if (cached == FALSE)
   {
      // Find first blank space and add entry
		// Blank entries are indicated by ip addr = 0
      for (i=0; i < CACHESIZE; i++)
      {
         if (arp_cache[i].ipaddr == 0) 
         {
            arp_cache[i].ipaddr = arp->source_ipaddr;
            memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);   
            arp_cache[i].timer = CACHETIME;
         	if (debug) serial_send("ARP: New cache entry added\r");
         	break;
         }
      }

		// If no blank entries in arp cache	then sort cache
		// to find oldest entry and replace it
		if (i == CACHESIZE)
		{
			// Oldest entry is the one with lowest timer value			
			minimum = 0xFFFF;
			for (i=0; i < CACHESIZE; i++)
      	{
				if (arp_cache[i].timer < minimum) 
				{
					minimum = arp_cache[i].timer;
					oldest = i;
				}
			}
      	
			// "oldest" is now index of oldest entry, so replace it
			arp_cache[oldest].ipaddr = arp->source_ipaddr;
         memcpy(&arp_cache[oldest].hwaddr[0], &arp->source_hwaddr[0], 6);   
         arp_cache[oldest].timer = CACHETIME;
        if (debug) serial_send("ARP: Cache full, so replaced oldest\r");
   	}
	}

   
   // If we are waiting for an arp response and the arp response
  	// that just came in is addressed to me and is from the host
  	// we are waiting for, then send	the message-in-waiting
   if (arp->message_type == ARP_RESPONSE)
   {
   	if ((waiting_for_arp) && (wait.ipaddr == arp->source_ipaddr))
   	{
   		waiting_for_arp = FALSE;
		  	ip_send(wait.buf, wait.ipaddr, wait.proto_id, wait.len);
		}
	}
	else if (arp->message_type == ARP_REQUEST)
   {
    	// Send ARP response 
    	if (debug) serial_send("ARP: Sending response\r");
    	arp_send(arp->source_hwaddr, arp->source_ipaddr, ARP_RESPONSE);
	}
}