Пример #1
0
struct udpiphdr *udp_read(void)
{
    int                  len;
    char                *ptr;
    struct ether_header *eptr;

    for ( ; ; ) {
        // 从分组捕获设备获取下一个分组
        ptr = next_pcap(&len);

        switch (datalink) {
            case DLT_NULL:  // loopback header = 4 bytes
                return(udp_check(ptr + 4, len - 4));

            case DLT_EN10MB:
                eptr = (struct ether_header *) ptr;
                if (ntohs(eptr->ether_type) != ETHERTYPE_IP) {
                    err_quit("Ethernet type %x not IP", ntohs(eptr->ether_type));
                }
                return(udp_check(ptr + 14, len - 14));

            case DLT_SLIP:  // SLIP header = 24 bytes
                return(udp_check(ptr + 24, len - 24));

            case DLT_PPP:   // PPP header = 24 bytes
                return(udp_check(ptr + 24, len - 24));

            default:
                err_quit("unsupported datalink (%d)", datalink);
        }
    }
}
Пример #2
0
// This is a very weird function, look at udpCheckReceiveFork() in matlab.c for the "why"
int udpmsg_receive(udpmsg *packet)
 {
	 char recv_buf[MAXMSGLENGTH+10];
	 char senderIP[16]; // "xxx.xxx.xxx.xxx\0"
	 int ret = 0;

	 if(udp_check(0)) {

		 udp_read(recv_buf, sizeof(recv_buf), senderIP);
		 //	printf("%s\n", senderIP);
		 // First if clause determines whether message is from Psychtoolbox
		 if (!strcmp(senderIP, macIP)) {
			 if(strlen(recv_buf)>10 && recv_buf[9]==' ' && strcmp(recv_buf,last_recv)!=0) {
				 strcpy(last_recv, recv_buf);
				 strncpy(packet->id, recv_buf, 9);
				 packet->id[9] = 0;
				 strcpy(packet->msg, recv_buf+10);
				 if (strcmp(packet->msg,"RECEIVED")==0)
				   packet->received = 1;
				 else if (strcmp(packet->msg,"EXECUTED")==0)
				   packet->executed = 1;
				 else {
					 /* if it is a new message confirm its receipt */
					 strcpy(recv_buf+10, "RECEIVED");
					 udp_send(recv_buf, macIP);
				 }
				 
				 ret = 1;
			 }       
		 }
	 }
	 return ret;
 }
Пример #3
0
int udp_send(struct netdev *nd, struct sin *from, struct sin *to, struct buflist *data)
{
	struct buflist bl, *blp;
	struct udphdr udp;
	int size = 0;

	bl.data = &udp;
	bl.size = sizeof(udp);
	bl.next = data;

	for (blp = &bl; blp; blp = blp->next)
		size += blp->size;

	udp.udp_source = from->sin_port;
	udp.udp_dest   = to->sin_port;
	udp.udp_length = htons(size);
	udp.udp_check  = 0;
	udp.udp_check  = udp_check(&udp, from, to, &bl, size);

	return ip_send(nd, 0x11, from->sin_addr, to->sin_addr, &bl);
}
Пример #4
0
int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
	__u32 daddr, unsigned short len,
	__u32 saddr, int redo, struct inet_protocol *protocol)
{
  	struct sock *sk;
  	struct udphdr *uh;
	unsigned short ulen;
	int addr_type;

	/*
	 * If we're doing a "redo" (the socket was busy last time
	 * around), we can just queue the packet now..
	 */
	if (redo) {
		udp_queue_rcv_skb(skb->sk, skb);
		return 0;
	}

	/*
	 * First time through the loop.. Do all the setup stuff
	 * (including finding out the socket we go to etc)
	 */

	addr_type = IS_MYADDR;
	if(!dev || dev->pa_addr!=daddr)
		addr_type=ip_chk_addr(daddr);
		
	/*
	 *	Get the header.
	 */
	 
  	uh = (struct udphdr *) skb->h.uh;
  	
  	ip_statistics.IpInDelivers++;

	/*
	 *	Validate the packet and the UDP length.
	 */
	 
	ulen = ntohs(uh->len);
	
	if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) 
	{
		NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
		udp_statistics.UdpInErrors++;
		kfree_skb(skb, FREE_WRITE);
		return(0);
	}

	/* RFC1122 warning: According to 4.1.3.6, we MUST discard any */
	/* datagram which has an invalid source address, either here or */
	/* in IP. */
	/* Right now, IP isn't doing it, and neither is UDP. It's on the */
	/* FIXME list for IP, though, so I wouldn't worry about it. */
	/* (That's the Right Place to do it, IMHO.) -- MS */

	if (uh->check && (
		( (skb->ip_summed == CHECKSUM_HW) && udp_check(uh, len, saddr, daddr, skb->csum ) ) ||
		( (skb->ip_summed == CHECKSUM_NONE) && udp_check(uh, len, saddr, daddr,csum_partial((char*)uh, len, 0)))
			  /* skip if CHECKSUM_UNNECESSARY */
		         )
	   )
	{
		/* <*****@*****.**> wants to know, who sent it, to
		   go and stomp on the garbage sender... */

	  /* RFC1122: OK.  Discards the bad packet silently (as far as */
	  /* the network is concerned, anyway) as per 4.1.3.4 (MUST). */

		NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
		       ntohl(saddr),ntohs(uh->source),
		       ntohl(daddr),ntohs(uh->dest),
		       ulen));
		udp_statistics.UdpInErrors++;
		kfree_skb(skb, FREE_WRITE);
		return(0);
	}

	/*
	 *	These are supposed to be switched. 
	 */
	 
	skb->daddr = saddr;
	skb->saddr = daddr;

	len=ulen;

	skb->dev = dev;
	skb_trim(skb,len);

#ifdef CONFIG_IP_MULTICAST
	if (addr_type==IS_BROADCAST || addr_type==IS_MULTICAST)
		return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
#endif
#ifdef CONFIG_IP_TRANSPARENT_PROXY
	if(skb->redirport)
		sk = udp_v4_proxy_lookup(saddr, uh->source, daddr, uh->dest,
					 dev->pa_addr, skb->redirport, dev);
	else
#endif
	sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, dev);
	
	if (sk == NULL) 
  	{
  		udp_statistics.UdpNoPorts++;
		if (addr_type != IS_BROADCAST && addr_type != IS_MULTICAST) 
		{
			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
		}
		/*
		 * Hmm.  We got an UDP broadcast to a port to which we
		 * don't wanna listen.  Ignore it.
		 */
		skb->sk = NULL;
		kfree_skb(skb, FREE_WRITE);
		return(0);
  	}
	udp_deliver(sk, skb);
	return 0;
}