Example #1
0
void *udp_packet_handler(void *arg)
{
    (void) arg;

    msg_t m_recv_ip, m_send_ip, m_recv_udp, m_send_udp;
    socket_internal_t *udp_socket = NULL;

    msg_init_queue(udp_msg_queue, UDP_PKT_RECV_BUF_SIZE);

    while (1) {
        msg_receive(&m_recv_ip);
        ipv6_hdr_t *ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
        udp_hdr_t *udp_header = ((udp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));

        uint16_t chksum = ipv6_csum(ipv6_header, (uint8_t*) udp_header, NTOHS(udp_header->length), IPPROTO_UDP);

        if (chksum == 0xffff) {
            udp_socket = get_udp_socket(udp_header);

            if (udp_socket != NULL) {
                m_send_udp.content.ptr = (char *)ipv6_header;

                msg_send_receive(&m_send_udp, &m_recv_udp, udp_socket->recv_pid);
            }
            else {
                printf("Dropped UDP Message because no thread ID was found for delivery!\n");
            }
        }
        else {
            printf("Wrong checksum (%x)!\n", chksum);
        }

        msg_reply(&m_recv_ip, &m_send_ip);
    }
}
Example #2
0
File: udp.c Project: manoja328/RIOT
void udp_packet_handler(void)
{
    msg_t m_recv_ip, m_send_ip, m_recv_udp, m_send_udp;
    ipv6_hdr_t *ipv6_header;
    udp_hdr_t *udp_header;
    uint8_t *payload;
    socket_internal_t *udp_socket = NULL;
    uint16_t chksum;

    while (1) {
        msg_receive(&m_recv_ip);
        ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
        udp_header = ((udp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));
        payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN);

        chksum = udp_csum(ipv6_header, udp_header);

        if (chksum == 0xffff) {
            udp_socket = get_udp_socket(ipv6_header, udp_header);

            if (udp_socket != NULL) {
                m_send_udp.content.ptr = (char *)ipv6_header;
                msg_send_receive(&m_send_udp, &m_recv_udp, udp_socket->recv_pid);
            }
            else {
                printf("Dropped UDP Message because no thread ID was found for delivery!\n");
            }
        }
        else {
            printf("Wrong checksum (%x)!\n", chksum);
        }

        msg_reply(&m_recv_ip, &m_send_ip);
    }
}
Example #3
0
int main(int argc, char **argv){
	int					sockfd_fp, sockfd_data, connfd, udpfd, nready, maxfdp1;
	char				mesg[MAXLINE];
	pid_t				childpid, workerpid;
	fd_set				rset;
	const int			on = 1;
	void				sig_chld(int);

	// hash worker init
	hash_init(1024);

	/* 1. Channel : fingerprint packet recv */
	sockfd_fp = get_udp_socket(SERV_PORT+1);

	/* 2. Channel : other packet */
	sockfd_data = get_udp_socket(SERV_PORT);

	Signal(SIGCHLD, sig_chld);	/* must call waitpid() */

	FD_ZERO(&rset);
	maxfdp1 = max(sockfd_fp, sockfd_data) + 1;
	for ( ; ; ) {
		FD_SET(sockfd_fp, &rset);
		FD_SET(sockfd_data, &rset);
		if ( (nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
			if (errno == EINTR)
				continue;		/* back to for() */
			else
				err_sys("select error");
		}

		if (FD_ISSET(sockfd_fp, &rset)) {
			recv_fp(sockfd_fp);
		}

		if (FD_ISSET(sockfd_data, &rset)) {
			recv_chunk(sockfd_data);
		}
	}
}
Example #4
0
int main(int argc, char **argv){
	int res = 0;
	struct timeval tv1, tv2;
	double total;
	char *directory = NULL;
	long count;

	if (argc != 3)
		err_quit("usage: client <IPaddress> <file dir>");
	serverip = argv[1];
	directory = argv[2];

	gettimeofday(&tv1, NULL);

	sockfd4pox = get_udp_socket(QUICK_PORT);// channel with POX

	bzero(&servaddrfp, sizeof(servaddrfp));
	servaddrfp.sin_family = AF_INET;
	servaddrfp.sin_port = htons(SERV_PORT+1);
	Inet_pton(AF_INET, argv[1], &servaddrfp.sin_addr);
	sockfd2serverfp = Socket(AF_INET, SOCK_DGRAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(SERV_PORT);
	Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
	sockfd2server = Socket(AF_INET, SOCK_DGRAM, 0);

	uploadDir(directory);

	gettimeofday(&tv2, NULL);
	printf("Time cost = %lfms\n",(tv2.tv_sec-tv1.tv_sec)*1000.0+(tv2.tv_usec-tv1.tv_usec)/1000.0);

	close(sockfd4pox);
	close(sockfd2server);
	close(sockfd2serverfp);
	exit(0);
}
Example #5
0
int get_multicast_socket(const char *group, unsigned short port)
{
	int fd;
	struct ip_mreq mreq;

	if ((fd = get_udp_socket(group, port)) < 0) {
		printf("Could not get UDP socket.\n");
		return (-1);
	}

	/* use setsockopt() to request that the kernel join a multicast group */
	mreq.imr_multiaddr.s_addr = inet_addr(group);
	mreq.imr_interface.s_addr = htonl(INADDR_ANY);
	if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) <
	    0) {
		printf
		    ("%s:setsockopt() failed: Join multicast group failed: %s\n",
		     progname, strerror(errno));
		return (-1);
	}

	return (fd);
}
Example #6
0
// application entry point
int main(int argc, char* argv[])
{
  int fbfd = 0;
  struct fb_var_screeninfo orig_vinfo;
  struct fb_var_screeninfo vinfo;
  struct fb_fix_screeninfo finfo;
  long int screensize = 0;
  char *fbp = 0;

  char packet[1120];
  ssize_t packet_size;

  int sock_fd = get_udp_socket(UDP_PORT);

  // Open the file for reading and writing
  fbfd = open("/dev/fb0", O_RDWR);
  if (!fbfd) {
    die("Error: cannot open framebuffer device.\n");
  }
  printf("The framebuffer device was opened successfully.\n");

  // Get variable screen information
  if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
    printf("Error reading variable information.\n");
  }
  printf("Original %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, 
         vinfo.bits_per_pixel );

  // Store for reset (copy vinfo to vinfo_orig)
  memcpy(&orig_vinfo, &vinfo, sizeof(struct fb_var_screeninfo));

  // Change variable info
  vinfo.bits_per_pixel = 24;
  if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)) {
    printf("Error setting variable information.\n");
  }
  
  // Get fixed screen information
  if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
    printf("Error reading fixed information.\n");
  }

  // map fb to user mem 
  screensize = finfo.smem_len;
  fbp = (char*)mmap(0, 
                    screensize, 
                    PROT_READ | PROT_WRITE, 
                    MAP_SHARED, 
                    fbfd, 
                    0);

  if ((long)fbp == -1) {
    die("Failed to mmap.\n");
  }
  else {
    // draw...
    int x, y, pixelcount;
    unsigned int color = 0;
    int pixeloffset = 2;
    int pixellength = 0;
    unsigned int pix_offset;
    unsigned bpp = vinfo.bits_per_pixel / 8;
    
    while( (packet_size = get_udp_packet(sock_fd, packet, sizeof(packet))) >= 0 ) {
      if((uint8_t)packet[0] == 1){
        pixellength = 8;
      } else {
        pixellength = 7;
      }

      // how many pixels
      pixelcount = (packet_size-1)/pixellength;
      //printf("%d pixels in packet of size: %d using a pixel size of: %d \n", pixelcount, packet_size, pixellength);
      // fetch a pixel from the udp socket
      int i = 0;
      for(i=pixeloffset;  // skip pixeloffset
          i<packet_size-(pixellength-1); // walk trough all bytes untill we get to the end minus one package length
          i+=pixellength){
		    x = (uint8_t)packet[i  ] + (((uint8_t)packet[i+1])<<8);
		    y = (uint8_t)packet[i+2] + (((uint8_t)packet[i+3])<<8);
        //printf("%d %d %d %d %d %d\n", x, y, packet[i  ], packet[i+1], packet[i+2], packet[i+3]);
        if(x < vinfo.xres && y < vinfo.yres){
            pix_offset = bpp * x + y * finfo.line_length;
            fbp[pix_offset++] = packet[i+6];
            fbp[pix_offset++] = packet[i+5];
            fbp[pix_offset] = packet[i+4];
        }
      }
    }
  }
  // cleanup
  munmap((void *)fbp, screensize);
  if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &orig_vinfo)) {
    printf("Error re-setting variable information.\n");
  }
  close(fbfd);
  return 0; 
}
Example #7
0
// application entry point
int main(int argc, char* argv[]) {
  uint8_t packet[ (8 * MAX_PIXELS) + 32]; // 8 bytes per pixel is the maximum size
  ssize_t packet_size;
  uint16_t x, y;
  uint8_t r, g, b, a;
  uint8_t pixellength = 0, protocol, version;
  uint16_t i;
  uint8_t offset = 2;

  int sock_fd = get_udp_socket(UDP_PORT);

  // Init screen buffer
  if (!init_frame_buffer()) {
    die("Failed to init screen buffer.\n");
  }

  // draw each udp packet
  while( (packet_size = get_udp_packet(sock_fd, (char*)&packet, sizeof(packet))) >= 0 ) {
    // Get protocol from the packet
    version = packet[1];    // the version
    protocol = packet[0];   // protocol switch
    
    //printf("V:%d, P:%d\n", version, protocol);
    
    switch (protocol) {
      // Protocol 0: xyrgb 16:16:8:8:8 specified for each pixel
      case 0:
        pixellength = 7;
        packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size);
        for (i=offset; i<packet_size; i+=pixellength) {
          x = packet[i  ] | packet[i+1]<<8;
	        y = packet[i+2] | packet[i+3]<<8;
	        r = packet[i+4];
	        g = packet[i+5];
	        b = packet[i+6];
	        a = 0xFF;
	        write_pixel_to_screen(x, y, r, g, b, a);
	      }
	      break;

	    // Protocol 1: xyrgba 16:16:8:8:8:8 specified for each pixel
      case 1:
        pixellength = 8;
        packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size);
        for (i=offset; i<packet_size; i+=pixellength) {
          x = packet[i  ] | packet[i+1]<<8;
	        y = packet[i+2] | packet[i+3]<<8;
	        r = packet[i+4];
	        g = packet[i+5];
	        b = packet[i+6];
	        a = packet[i+7];
	        write_pixel_to_screen(x, y, r, g, b, a);
	      }
	      break;

	    // Protocol 2: xyrgb 12:12:8:8:8 specified for each pixel
      case 2:
        pixellength = 6;
        packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size);
        for (i=offset; i<packet_size; i+=pixellength) {
          x = packet[i  ] | (packet[i+1]&0xF0)<<4;
	        y = (packet[i+1]&0x0F) | packet[i+2]<<4;
	        r = packet[i+3];
	        g = packet[i+4];
	        b = packet[i+5];
	        a = 0xFF;
	        write_pixel_to_screen(x, y, r, g, b, a);
	      }
	      break;

	    // Protocol 3: xyrgba 12:12:8:8:8:8 specified for each pixel
      case 3:
        pixellength = 7;
        packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size);
        for (i=offset; i<packet_size; i+=pixellength) {
          x = packet[i  ] | (packet[i+1]&0xF0)<<4;
	        y = (packet[i+1]&0x0F) | packet[i+2]<<4;
	        r = packet[i+3];
	        g = packet[i+4];
	        b = packet[i+5];
	        a = packet[i+6];
	        write_pixel_to_screen(x, y, r, g, b, a);
	      }
	      break;

	    // Protocol 4: xyrgb 12:12:3:3:2 specified for each pixel
      case 4:
        pixellength = 4;
        packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size);
        for (i=offset; i<packet_size; i+=pixellength) {
          x = packet[i  ] | (packet[i+1]&0xF0)<<4;
	        y = (packet[i+1]&0x0F) | packet[i+2]<<4;
	        r = packet[i+3] & 0xE0;
	        g = packet[i+3]<<3 & 0xE0;
	        b = packet[i+3]<<6 & 0xC0;
	        a = 0xFF;
	        write_pixel_to_screen(x, y, r, g, b, a);
	      }
	      break;

	    // Protocol 5: xyrgba 12:12:2:2:2:2 specified for each pixel
      case 5:
        pixellength = 4;
        packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size);
        for (i=offset; i<packet_size; i+=pixellength) {
          x = packet[i  ] | (packet[i+1]&0xF0)<<4;
	        y = (packet[i+1]&0x0F) | packet[i+2]<<4;
	        r = packet[i+3] & 0xC0;
	        g = packet[i+3]<<2 & 0xC0;
	        b = packet[i+3]<<4 & 0xC0;
	        a = packet[i+3]<<6 & 0xC0;
	        write_pixel_to_screen(x, y, r, g, b, a);
	      }
	      break;

	    // Error no recognied protocol defined
	    default:
	      break;
	  }
  }

  // Deinitialize screen buffer
  deinit_frame_buffer();
  return 0; 
}
Example #8
0
int main(int argc, char **argv){
	int					sockfd_fp, sockfd_data, connfd, udpfd, nready, maxfdp1, listenfd2;
	char				mesg[MAXLINE];
	pid_t				childpid, workerpid;
	struct sockaddr_in	servaddr, cliaddr;
	fd_set				rset;
	const int			on = 1;
	int client_fds[FD_SETSIZE];
	void				sig_chld(int);

	/* hash table init
	 * Contain all the fps, maybe should be a cache and read from disk
	 */
	hash_init(1024);
	/*
	 * Create a bloom filter, the size NEED TO tradeoff
	 */
	filter = bloom_filter_new(5000);

	if (!(fpfile_all = fopen("/tmp/fp.all.out", "w"))) {
        fprintf(stderr, "E: Couldn't open file for write all fp\n");
        fflush (stderr);
        return;
    }

	/* Channel : fingerprint packet recv */
	sockfd_fp = get_udp_socket(SERV_PORT+1);
	int a = 65535;
	Setsockopt(sockfd_fp, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int));
	Setsockopt(sockfd_fp, SOL_SOCKET, SO_SNDBUF, &a, sizeof(int));


	/* Channel : other packet */
	listenfd2 = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(SERV_PORT);

	Setsockopt(listenfd2, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	Bind(listenfd2, (SA *) &servaddr, sizeof(servaddr));

	Listen(listenfd2, LISTENQ);

	// Channel to POX controller
	bzero(&fakeaddr, sizeof(fakeaddr));
	fakeaddr.sin_family = AF_INET;
	fakeaddr.sin_port = htons(BLOOM_PORT);
	Inet_pton(AF_INET, "10.0.0.1", &fakeaddr.sin_addr);

	sockfdbloom = Socket(AF_INET, SOCK_DGRAM, 0);

	Signal(SIGCHLD, sig_chld);	/* must call waitpid() */

	FD_ZERO(&rset);
	maxfdp1 = max(sockfd_fp, listenfd2);
	connfd = -1;
	int i, maxi = -1;
	for(i=0; i<FD_SETSIZE; i++)
		client_fds[i] = -1;
	for ( ; ; ) {
		FD_SET(sockfd_fp, &rset);
		FD_SET(listenfd2, &rset);
		if ( (nready = select(maxfdp1 + 1, &rset, NULL, NULL, NULL)) < 0) {
			if (errno == EINTR)
				continue;		/* back to for() */
			else
				err_sys("select error");
		}

		if (FD_ISSET(sockfd_fp, &rset)) {
			recv_fp(sockfd_fp);
		}

		if (FD_ISSET(listenfd2, &rset)) {
			int len = sizeof(cliaddr);
			connfd = Accept(listenfd2, (SA *) &cliaddr, &len);
			int a = 65535;
			Setsockopt(connfd, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int));
			if ( (childpid = Fork()) == 0) {	/* child process TO recv file data */
				Close(listenfd2);	/* close listening socket */
				recv_chunk(connfd);	// LOOP 
				exit(0);
			}
			Close(connfd);			/* parent closes connected socket */
		}
		
	}
	// cannot get here 
}
Example #9
0
int main(int argc, char **argv){
	int res = 0;
	struct timeval tv1, tv2;
	char *directory = NULL;

	if (argc != 3)
		err_quit("usage: client <IPaddress> <file dir>");
	serverip = argv[1];
	directory = argv[2];

	gettimeofday(&tv1, NULL);

	sockfd4pox = get_udp_socket(QUICK_PORT);// channel with POX

	bzero(&servaddrfp, sizeof(servaddrfp));
	servaddrfp.sin_family = AF_INET;
	servaddrfp.sin_port = htons(SERV_PORT+1);
	Inet_pton(AF_INET, argv[1], &servaddrfp.sin_addr);
	sockfd2serverfp = Socket(AF_INET, SOCK_DGRAM, 0);
	// Connect(sockfd2serverfp, (SA *)&servaddrfp, sizeof(servaddrfp));

	struct timeval tv;
	tv.tv_sec = 1;
	tv.tv_usec = 0;// 
	setsockopt(sockfd2serverfp, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
	int a = 65535;
	Setsockopt(sockfd2serverfp, SOL_SOCKET, SO_SNDBUF, &a, sizeof(int));
	Setsockopt(sockfd2serverfp, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int));


#ifdef USE_UDP
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(SERV_PORT);
	Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
	sockfd2server = Socket(AF_INET, SOCK_DGRAM, 0);
#else
	sockfd2server = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(SERV_PORT); //
	Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

	Connect(sockfd2server, (SA *) &servaddr, sizeof(servaddr));
	Setsockopt(sockfd2server, SOL_SOCKET, SO_SNDBUF, &a, sizeof(int));
#endif
	// start 
	start_backup();

	uploadDir(directory);
	// uploadDir_recur(directory);

	gettimeofday(&tv2, NULL);
	printf("Time cost = %lfms\n",(tv2.tv_sec-tv1.tv_sec)*1000.0+(tv2.tv_usec-tv1.tv_usec)/1000.0);

    /* Upload complete, tell server to sync data to SDN controller
     * Need a alg(by dedu ratio) to control this sync
     */
    end_backup();


	close(sockfd4pox);
	
	// shutdown(sockfd2server, SHUT_WR);
	// shutdown(sockfd2serverfp, SHUT_WR);
	close(sockfd2serverfp);
	close(sockfd2server);
	exit(0);
}
Example #10
0
int main(int argc, char *argv[])
{
	struct sockaddr_in addr;
	socklen_t addrlen;
	mxbp_packet_t *block_packet;
	char *group = NULL;
	char *cp;
	uint16_t port = DEFAULT_PORT;
	int nbytes;
	int epollfd;
	int sock;
	int ctlsock;
	int c;
	int rv;
	int fd;
	unsigned int no_sparse = 0;
	int timeoutms = DEFAULT_TIMEOUT;
	struct epoll_event ev;
	struct epoll_event events[10];

	progname = strdup(argv[0]);

	while ((c = getopt(argc, argv, "g:p:f:s:t:o:nh")) != -1) {
		switch (c) {
		case 'g':
			if (group) {
				free(group);
			}
			group = strdup(optarg);
			break;

		case 'p':
			port = atoi(optarg);
			break;

		case 't':
			timeoutms = atoi(optarg);
			break;

		case 'f':
			from_port = atoi(optarg);
			break;

		case 's':
			if ((cp = strrchr(optarg, ':'))) {
				*cp++ = 0;
				server_port = atoi(cp);
			}
			server = strdup(optarg);
			break;

		case 'o':
			if (outputname) {
				free(outputname);
			}
			outputname = strdup(optarg);
			break;

		case 'n':
			no_sparse = 1;
			break;

		default:
			printf("Error: Unrecognized option -%c\n", c);
			/* intentional fall through */
		case 'h':
			usage();
		}
	}

	if (!group) {
		group = DEFAULT_GROUP;
	}

	if (!server) {
		server = DEFAULT_SERVER;
	}

	if (!from_port) {
		srand(time(NULL));
		from_port = (rand() % 32767) + 32767;
	}

	mapreq.magic = htobe32(MXBP_MAGIC);
	mapreq.op = htobe16(MXBP_MAPREQ);
	mapreq.size = 0;
	mapreq.blockid = 0;

	if ((ctlsock = get_udp_socket(server, from_port)) < 0) {
		printf("Error:get_udp_socket(): failed.\n");
		exit(EXIT_FAILURE);
	}

	if ((epollfd = epoll_create(10)) < 0) {
		printf("%s:epoll_create(): failed: %s\n", progname,
		       strerror(errno));
		exit(EXIT_FAILURE);
	}

	ev.events = EPOLLIN;
	ev.data.fd = ctlsock;
	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, ctlsock, &ev) == -1) {
		printf("%s:epoll_ctl(): failed: %s\n", progname,
		       strerror(errno));
		exit(EXIT_FAILURE);
	}

	for (send_mapreq(ctlsock); !mapdesc.filesize;) {
		rv = epoll_wait(epollfd, events, 10, timeoutms);
		if (rv < 0) {
			printf("%s:epoll_wait(): failed: %s\n", progname,
			       strerror(errno));
			exit(EXIT_FAILURE);
		}
		if (rv) {
			read_mapdesc(ctlsock);
		} else {
			/* Hit timeout, resend map request. */
			send_mapreq(ctlsock);
		}
	}

	close(epollfd);

	if (!(blockmap = calloc(1, mapdesc.nblocks))) {
		printf("Could not get %d bytes for block map: %s\n",
		       mapdesc.nblocks, strerror(errno));
		exit(EXIT_FAILURE);
	}

	cp = strrchr(recvfilename, '/');
	if (!cp) {
		cp = recvfilename;
	}

	printf("Received description: File %s length %ld blocks %d\n", cp,
	       mapdesc.filesize, mapdesc.nblocks);

	if (outputname) {
		cp = outputname;
		printf("Overriding output name with '%s'\n", cp);
	}

	/* There is no resume so we use O_TRUNC
	 * Note that we could periodically write out the blockmap
	 * and load that if present to be able to resume, but that's
	 * not a priority.
	 */
	if ((fd =
	     open(cp, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644)) < 0) {
		printf("Could not open %s : %s\n", cp, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (no_sparse) {
		/* Cannot use a sparse file, so now create a big zeroed file. */
		char zeros[MXBP_BLOCKSIZE];
		int bcount;

		memset(zeros, 0, sizeof(zeros));
		for (bcount = 0; bcount <= mapdesc.nblocks; ++bcount) {
			if (!write(fd, zeros, MXBP_BLOCKSIZE) != MXBP_BLOCKSIZE) {
				printf("Failed to write block %d: %s (continuing anyway)\n", bcount, strerror(errno));
			}
		}
		/* Rewind, just in case */
		lseek(fd, 0, SEEK_SET);

	}

	if ((sock = get_multicast_socket(group, port)) < 0) {
		printf("Could not get multicast socket.\n");
		exit(EXIT_FAILURE);
	}

	if ((epollfd = epoll_create(10)) < 0) {
		printf("%s:epoll_create(): failed: %s\n", progname,
		       strerror(errno));
		exit(EXIT_FAILURE);
	}
	ev.events = EPOLLIN;
	ev.data.fd = sock;
	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1) {
		printf("%s:epoll_ctl(): failed: %s\n", progname,
		       strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* now just enter a read-print loop */
	while (1) {
		addrlen = sizeof(addr);
		memset(msgbuf, 0, MAX_PACKET_SIZE);

		rv = epoll_wait(epollfd, events, 10, timeoutms);
		if (rv < 0) {
			printf("%s:epoll_wait(): failed: %s\n", progname,
			       strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (rv) {

			if ((nbytes =
			     recvfrom(sock, msgbuf,
				      sizeof(mxbp_header_t) + MXBP_BLOCKSIZE, 0,
				      (struct sockaddr *)&addr,
				      &addrlen)) < 0) {
				printf("Failed to receive: %s",
				       strerror(errno));
				exit(EXIT_FAILURE);
			}

			if (nbytes < sizeof(mxbp_header_t)) {
				printf("Got short read, ignoring.\n");
				continue;
			}
			block_packet = (mxbp_packet_t *) msgbuf;
			block_packet->header.magic =
			    be32toh(block_packet->header.magic);
			if (block_packet->header.magic != MXBP_MAGIC) {
				printf("This is not an MXBP message.\n");
				continue;
			}

			block_packet->header.op =
			    be16toh(block_packet->header.op);
			if (block_packet->header.op != MXBP_BLOCK) {
				printf("Unexpected operation %d, ignoring.\n",
				       block_packet->header.op);
				continue;
			}

			block_packet->header.size =
			    be16toh(block_packet->header.size);
			block_packet->header.blockid =
			    be32toh(block_packet->header.blockid);

			if (block_packet->header.blockid > mapdesc.nblocks) {
				printf
				    ("Got Block ID %d past end of file %d, ignoring\n",
				     block_packet->header.blockid,
				     mapdesc.nblocks);
				continue;
			}

			if (!blockmap[block_packet->header.blockid]) {
				if (lseek64
				    (fd,
				     block_packet->header.blockid *
				     MXBP_BLOCKSIZE, SEEK_SET) && errno) {
					printf
					    ("Failed to seek to offset %d: %s\n",
					     block_packet->header.blockid *
					     MXBP_BLOCKSIZE, strerror(errno));
					exit(EXIT_FAILURE);
				}

				if (write
				    (fd, block_packet->data,
				     block_packet->header.size) !=
				    block_packet->header.size) {
					printf
					    ("Failed to write to offset %d: %s\n",
					     block_packet->header.blockid *
					     MXBP_BLOCKSIZE, strerror(errno));
					exit(EXIT_FAILURE);
				}

				blockmap[block_packet->header.blockid] = 1;
				if (check_finished()) {
					close(ctlsock);
					close(sock);
					close(epollfd);
					close(fd);
					printf("All done.\n");
					exit(EXIT_SUCCESS);
				}
			}
		} else {
			/* Hit the poll timeout, so send a block request. */
			send_block_req(ctlsock);
		}
	}
	exit(EXIT_SUCCESS);
}