Exemple #1
0
int ArduinoCOIL::readRawSensor (seeyou_sensor packet, byte* buffer, int size)
{
    int numread = 0;
    byte cmd[3];
    cmd[0] = packet;
    cmd[1] = TRAILER;
    cmd[2] = CARRIAGE_RETURN;

    if (cwrite (port, cmd, 3) < 0)
    {
        Debug::error ("[COIL] Could not request sensor");
        return -1;
    }

    SleeperThread::msleep(40); // BUG: Why must we sleep? RTFM...

    numread = cread (port, buffer, size, packet);
    if (numread < 0)
    {
        Debug::error ("[COIL] Could not read sensor");
        return -1;
    }

    return numread;
}
Exemple #2
0
int get_ip_from_server(int net_fd, char *devname)
{
	char *buffer;

	// Get IP Address from server
	buffer = malloc(100) ;
	struct ip_header *iphdr = (struct ip_header*)buffer ;
	memset(buffer,0,100) ;
	iphdr->vers = 0x45 ;
	iphdr->ip_header_len = 20 ;
	iphdr->ttl = 64;
	if(cwrite(net_fd, buffer, 20) <= 0)
	{
		printf("error: write failed while getting IP address from server\n");
		exit(1);
	}

	cread(net_fd, buffer, 100) ;
	printf("Got IP response: %08x\n", ntohl(iphdr->dest_ip)) ;

	set_ip(devname, ntohl(iphdr->dest_ip), 0xffff0000);

	// Set the interface address.
	free(buffer) ;

	return 0;
}
Exemple #3
0
static inline COUNT
cread_32 (DECODE_REF fh, DWORD *v)
{
	DWORD t;
	if (!v) /* read value ignored */
		v = &t;
	return cread (v, 4, 1, fh);
}
Exemple #4
0
static inline COUNT
cread_16 (DECODE_REF fh, UWORD *v)
{
	UWORD t;
	if (!v) /* read value ignored */
		v = &t;
	return cread (v, 2, 1, fh);
}
Exemple #5
0
// XXX: these should handle endian conversions later
static inline COUNT
cread_8 (DECODE_REF fh, BYTE *v)
{
	BYTE t;
	if (!v) /* read value ignored */
		v = &t;
	return cread (v, 1, 1, fh);
}
Exemple #6
0
void
bread(daddr_t blkno, char *buf, int size)
{
	int cnt, i;

loop:
	cnt = cread(diskfd, buf, size, ((off_t)blkno << dev_bshift));
	if (cnt == size)
		return;
	if (blkno + (size / dev_bsize) > fsbtodb(sblock, sblock->fs_size)) {
		/*
		 * Trying to read the final fragment.
		 *
		 * NB - dump only works in TP_BSIZE blocks, hence
		 * rounds `dev_bsize' fragments up to TP_BSIZE pieces.
		 * It should be smarter about not actually trying to
		 * read more than it can get, but for the time being
		 * we punt and scale back the read only when it gets
		 * us into trouble. (mkm 9/25/83)
		 */
		size -= dev_bsize;
		goto loop;
	}
	if (cnt == -1)
		msg("read error from %s: %s: [block %d]: count=%d\n",
			disk, strerror(errno), blkno, size);
	else
		msg("short read error from %s: [block %d]: count=%d, got=%d\n",
			disk, blkno, size, cnt);
	if (++breaderrors > BREADEMAX) {
		msg("More than %d block read errors from %s\n",
			BREADEMAX, disk);
		broadcast("DUMP IS AILING!\n");
		msg("This is an unrecoverable error.\n");
		if (!query("Do you want to attempt to continue?")){
			dumpabort(0);
			/*NOTREACHED*/
		} else
			breaderrors = 0;
	}
	/*
	 * Zero buffer, then try to read each sector of buffer separately,
	 * and bypass the cache.
	 */
	memset(buf, 0, size);
	for (i = 0; i < size; i += dev_bsize, buf += dev_bsize, blkno++) {
		if ((cnt = pread(diskfd, buf, (int)dev_bsize,
		    ((off_t)blkno << dev_bshift))) == dev_bsize)
			continue;
		if (cnt == -1) {
			msg("read error from %s: %s: [sector %d]: count=%ld\n",
				disk, strerror(errno), blkno, dev_bsize);
			continue;
		}
		msg("short read error from %s: [sector %d]: count=%ld, got=%d\n",
			disk, blkno, dev_bsize, cnt);
	}
}
Exemple #7
0
/* server_loop: continously receive and process data */
void TwitchBot::server_loop()
{
	char buf[BUFFER_SIZE];
	char *pos, *s;
	int bytes, shift;
	size_t len;

	pos = buf;
	len = 0;
	/* continuously receive data from server */
	while (1) {
		shift = 0;
		if ((bytes = cread(&client, pos, BUFFER_SIZE - len)) < 0) {
			perror("read");
			fprintf(stderr, "LynxBot exiting.\n");
			disconnect();
			break;
		} else if (bytes == 0) {
			continue;
		}
		pos += bytes;
		len += bytes;
		if (len < BUFFER_SIZE - 1) {
			/* keep reading until full message has been received */
			if (*(pos - 1) != '\n' && *(pos - 2) != '\r')
				continue;
		} else {
			/* end string at last newline, shift rest to front */
			s = pos;
			while (*--s != '\n' && len)
				--len;
			*s = '\0';
			shift = 1;
		}

		printf("[RECV] %s\n", buf);
		process_data(buf);
		if (shift) {
			len = BUFFER_SIZE - 1 - len;
			pos = buf + len;
			memmove(buf, s + 1, len + 1);
		} else {
			pos = buf;
			len = 0;
		}

		if (!bot_connected)
			break;
	}
}
Exemple #8
0
int read_n(int fd, char *buf, int n) {

    int nread, left = n;

    while(left > 0) {
        if ((nread = cread(fd, buf, left)) == 0){
            return 0 ;
        }else {
            left -= nread;
            buf += nread;
        }
    }
    return n;
}
Exemple #9
0
unsigned long inline 
readXDInt(cfile *patchf, unsigned char *buff)
{
	unsigned long num=0;
	signed int count=-1;
	do {
		count++;
		cread(patchf, buff + count, 1);
	} while(buff[count] & 0x80);
	for(; count >= 0; count--) {
		num <<= 7;
		num |= (buff[count] & 0x7f); 
	}
	return num;
}
INPUT_STATE
demo_input (INPUT_REF InputRef, INPUT_STATE InputState)
{
    if (InputState || AnyButtonPress () || cread (
                (PBYTE)&InputState, sizeof (InputState), 1, journal_fh
            ) == 0)
    {
        cclose (journal_fh);
        journal_fh = 0;

        StopMusic ();
        StopSound ();

        FreeKernel ();
        exit (1);
    }

    return (InputState);
}
static int
get_byte(struct sd *s)
{
	if (s->z_eof)
		return (EOF);

	if (s->stream.avail_in == 0) {
		int got;

		errno = 0;
		got = cread(s->fd, s->inbuf, Z_BUFSIZE);
		if (got <= 0) {
			s->z_eof = 1;
			if (errno) s->z_err = Z_ERRNO;
			return EOF;
		}
		s->stream.avail_in = got;
		s->stream.next_in = s->inbuf;
	}
	s->stream.avail_in--;
	return *(s->stream.next_in)++;
}
void
OpenJournal (void)
{
    DWORD start_seed;

#if CREATE_JOURNAL
    if (create_journal)
    {
        if (journal_fh = copen (journal_buf, MEMORY_STREAM, STREAM_WRITE))
        {
            start_seed = SeedRandomNumbers ();
            cwrite ((PBYTE)&start_seed, sizeof (start_seed), 1, journal_fh);
        }
    }
    else
#endif /* CREATE_JOURNAL */
    {
        uio_Stream *fp;

        if (fp = res_OpenResFile ("starcon.jnl", "rb"))
        {
            ReadResFile (journal_buf, 1, sizeof (journal_buf), fp);
            res_CloseResFile (fp);

            if (journal_fh = copen (journal_buf, MEMORY_STREAM, STREAM_READ))
            {
                OldArrowInput = ArrowInput;
                ArrowInput = DemoInput;
                PlayerInput[0] = PlayerInput[1] = DemoInput;

                FlushInput ();

                cread ((PBYTE)&start_seed, sizeof (start_seed), 1, journal_fh);
                TFB_SeedRandom (start_seed);
            }
        }
    }
}
Exemple #13
0
unsigned int
check_xdelta1_magic(cfile *patchf)
{
	unsigned char buff[XDELTA_MAGIC_LEN];
	cseek(patchf, 0, CSEEK_FSTART);
	if(XDELTA_MAGIC_LEN != cread(patchf, buff, XDELTA_MAGIC_LEN)) {
		return 0;
	}
	if(memcmp(buff, XDELTA_110_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 2;
	} else if (memcmp(buff, XDELTA_104_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_100_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_020_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_018_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_014_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	}
	return 0;
}
Exemple #14
0
void* mon_tap2net (void* fd) 
{

	uint16_t nread, nwrite;
	char buffer[BUFSIZE]; 
	unsigned long int tap2net = 0;
	struct fd *fds = fd;

	while(1) {
		
		/* data from tun/tap: just read it and write it to the network */
    		nread = cread(fds->tap_fd, buffer, BUFSIZE);

		tap2net++;
    		do_debug("TAP2NET %lu: Read %d bytes from the tap interface\n", tap2net, nread);

		/* write length + packet */
		nwrite = sendto(fds->remote_net_fd, buffer, nread, 0, 
				(struct sockaddr *)&fds->remote, sizeof(fds->remote));

		do_debug("TAP2NET %lu: Written %d bytes to the network\n", tap2net, nwrite);
	}
}
Exemple #15
0
int register_static_ip(int net_fd, int ip, char *devname)
{
	char *buffer;
	int nread;

	// Static IP
	buffer = malloc(100);
	struct ip_header *iphdr = (struct ip_header*)buffer;
	memset(buffer,0,100);
	iphdr->vers = 0x45;
	iphdr->ip_header_len = 20;
	iphdr->ttl = 64;
	iphdr->source_ip = ip;
	if(cwrite(net_fd, buffer, 20) <= 0)
	{
		printf("error: write failed while requesting static IP address from server.\n");
		exit(1);
	}

	nread = cread(net_fd, buffer, 100) ;

	if(nread == 0)
	{
		// Connection closed while trying to assign a statick IP. This means that someone else already has that address.
		fprintf(stderr, "ERROR: Requested static IP address already in use.\n");
		exit(0);
	}

	set_ip(devname, ntohl(iphdr->dest_ip), 0xffff0000);
	if(add_host_route(devname, (in_addr_t)ntohl(iphdr->dest_ip)) < 0)
		printf("add_host_route returned\n");

	// Set the interface address.
	free(buffer) ;

	return 0;
}
// load into memory and return a pointer to the section of type 'type',
// or NULL if the file doesn't have a section of that type.
uint8_t *SIFLoader::FindSection(int type, int *length_out)
{
	// try and find the section in the index
	for(int i=0;;i++)
	{
		SIFIndexEntry *entry = (SIFIndexEntry *)fIndex.ItemAt(i);
		if (!entry) break;
		
		if (entry->type == type)
		{	// got it!
			
			// haven't loaded it yet? need to fetch it from file?
			if (!entry->data)
			{
				if (!fFP)
				{
					NX_ERR("SIFLoader::FindSection: entry found and need to load it, but file handle closed\n");
					if (length_out) *length_out = 0;
					return NULL;
				}
				
				NX_LOG("Loading SIF section %d from address %04x\n", type, entry->foffset);
				
				entry->data = (uint8_t *)malloc(entry->length);
				cseek(fFP, entry->foffset, SEEK_SET);
				cread(entry->data, entry->length, 1, fFP);
			}
			
			if (length_out) *length_out = entry->length;
			return entry->data;
		}
	}
	
	if (length_out) *length_out = 0;
	return NULL;
}
Exemple #17
0
int
read_entry(cfile *src_cfh, off_u64 start, tar_entry *entry)
{
	unsigned char block[512];
	unsigned int read_bytes;
	unsigned int name_len, prefix_len;

	if(start != cseek(src_cfh, start, CSEEK_FSTART)) {
			return IO_ERROR;
	}
	if((read_bytes=cread(src_cfh, block, 512))!=512) {
			return IO_ERROR;
	}
	entry->start = start;
	entry->end = 512 + start;
	if(strnlen((const char *)block, 512)==0)  {
		return TAR_EMPTY_ENTRY;
	}
	if (! check_str_chksum(block)) {
		v0printf("checksum failed on a tarfile, bailing\n");
		return IO_ERROR;
	}
	if('L'==block[TAR_TYPEFLAG_LOC]) {
		v2printf("handling longlink at %llu eg(%llu)\n", (act_off_u64)start, (act_off_u64)(start * 512));
		name_len = octal_str2long(block + TAR_SIZE_LOC, TAR_SIZE_LEN);
		if((read_bytes=cread(src_cfh, block, 512))!=512) {
			v0printf("unexpected EOF on tarfile, bailing\n");
			return EOF_ERROR;
		}
		if((entry->fullname = 
			(unsigned char *)malloc(name_len + 1))==NULL){
			v0printf("unable to allocate memory for name_len, bailing\n");
			return EOF_ERROR;
		}
		memcpy(entry->fullname, block, name_len);
		if((read_bytes=cread(src_cfh, block, 512))!=512){
			v0printf("unable to allocate memory for fullname, bailing\n");
			return EOF_ERROR;
		}
		if(! check_str_chksum(block)) {
			v0printf("tar checksum failed for tar entry at %llu, bailing\n", (act_off_u64)start);
			// IO_ERROR? please.  add data_error.
			return IO_ERROR;
		}
		entry->fullname[name_len] = '\0';
		entry->end += octal_str2long(block + TAR_SIZE_LOC, TAR_SIZE_LEN) + 1024;
	} else {
		name_len = strnlen((char *)block + TAR_NAME_LOC, TAR_NAME_LEN);
		prefix_len = strnlen((char *)block + TAR_PREFIX_LOC, TAR_PREFIX_LEN);

		// check if space will be needed for the slash
		prefix_len += (prefix_len==0 ? 0 : 1);
		if((entry->fullname = 
			(unsigned char *)malloc(name_len + prefix_len + 1))==NULL){
			v0printf("unable to allocate needed memory, bailing\n");
			return MEM_ERROR;
		}
		if(prefix_len) {
			memcpy(entry->fullname, block + TAR_PREFIX_LOC, prefix_len -1);
			entry->fullname[prefix_len] = '/';
			memcpy(entry->fullname + prefix_len, block + TAR_NAME_LOC, name_len);
			entry->fullname[prefix_len + name_len ] = '\0';
		} else {
			memcpy(entry->fullname, block + TAR_NAME_LOC, name_len);
			entry->fullname[name_len] = '\0';
		}
		entry->end += octal_str2long(block + TAR_SIZE_LOC, TAR_SIZE_LEN);
	}
	if(entry->end % 512)
		entry->end += 512 - (entry->end % 512);
	return 0;
}
Exemple #18
0
int main(int argc, char *argv[]) {
#ifdef DEBUG
  signal(SIGSEGV,debug_backtrace);
#endif
  printf("begin!\n");
  int tap_fd, tap_fd1, option;
  int dummy = 0;
  int flags = IFF_TUN;
  char if_name0[IFNAMSIZ] = "tap0";
  char if_name1[IFNAMSIZ] = "tap1";
  int maxfd;
  uint16_t nread, nwrite, plength;
  char buffer[BUFSIZE];
  struct sockaddr_in local, remote;
  char remote_ip[16] = "";            /* dotted quad IP string */
  unsigned short int port = PORT;
  int sock_fd, net_fd, optval = 1;
  socklen_t remotelen;
  int cliserv = -1;    /* must be specified on cmd line */
  unsigned long int tap2net = 0, net2tap = 0;

  struct in_addr addr;
  struct host twohopneis[10];
  inet_aton(twohopnei_ip_addr,&addr);
  twohopneis[0].ip_addr = addr.s_addr;
  memcpy(twohopneis[0].mac_addr,gate_mac_addr, ETHER_ADDR_LEN); 

  struct host localhost;
  inet_aton(local_ip_addr,&addr);
  localhost.ip_addr = addr.s_addr;
  memcpy(localhost.mac_addr, local_mac_addr, ETHER_ADDR_LEN);

  progname = argv[0];
  
  /* Check command line options */
  while((option = getopt(argc, argv, "i:sc:p:uahd")) > 0) {
    switch(option) {
      case 'd':
	printf("Enter dummy mode\n");
        dummy = 1;
        break;
      case 'h':
        usage();
        break;
      case 'i':
        strncpy(if_name0,optarg, IFNAMSIZ-1);
        break;
      case 's':
        cliserv = SERVER;
        break;
      case 'c':
        cliserv = CLIENT;
        strncpy(remote_ip,optarg,15);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'u':
        flags = IFF_TUN;
        break;
      case 'a':
        flags = IFF_TAP;
        break;
      default:
        my_err("Unknown option %c\n", option);
        usage();
    }
  }

  argv += optind;
  argc -= optind;

  if(argc > 0) {
    my_err("Too many options!\n");
    usage();
  }

  if(*if_name0 == '\0') {
    my_err("Must specify interface name!\n");
    usage();
  } else if(cliserv < 0) {
    my_err("Must specify client or server mode!\n");
    usage();
  } else if((cliserv == CLIENT)&&(*remote_ip == '\0')) {
    my_err("Must specify server address!\n");
    usage();
  }
	printf("allocate tap device!\n");
  /* initialize tun/tap interface */
  if ( (tap_fd = tun_alloc(if_name0, flags | IFF_NO_PI)) < 0 ) {
    my_err("Error connecting to tun/tap interface %s!\n", if_name0);
    exit(1);
  }
  
   if ( (tap_fd1 = tun_alloc(if_name1, flags | IFF_NO_PI)) < 0 ) {
    my_err("Error connecting to tun1/tap1 interface %s!\n", if_name1);
    exit(1);
  }
  printf("allocate tap device success!\n");

  //do_debug("Successfully connected to interface %s\n", if_name0);
  
  /* use select() to handle two descriptors at once */
  maxfd = (tap_fd > tap_fd1)?tap_fd:tap_fd1;
  while(1) {
    int ret;
    fd_set rd_set;

    FD_ZERO(&rd_set);
    FD_SET(tap_fd, &rd_set); FD_SET(tap_fd1, &rd_set);
    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);
    if (ret < 0 && errno == EINTR){
	  do_debug("ret error");
      continue;
    }

    if (ret < 0) {
      perror("select()");
      exit(1);
    }
    if(FD_ISSET(tap_fd, &rd_set)) {
      /* data from tun/tap: just read it and write it to the network */
      
      DEBUGMSG(2,"\n--Send a packet--\n");
      nread = cread(tap_fd, buffer, BUFSIZE);

      //append the trailer
      if(!dummy){
        if(isIP((unsigned char*)buffer) && isTCP((unsigned char*)buffer)){
          ++send_counter;
          if(send_counter >= UP_LIMIT){
            const int len = 14 + sizeof(struct ip) + 4;
	    unsigned char signal[14 + sizeof(struct ip) + 4] = {0};
	    ConstructSignal(signal, &(twohopneis[0]), &localhost);	
            DEBUGMSG(1,"Epoch end and send a signal\n");
            nwrite = write(tap_fd1, signal, len);
            send_counter = 0;
	  }
          int newLen = extendPacket(TCP, (unsigned char*)buffer);
          nread = newLen;
        }
      }

      //DEBUGMSG(2,"route a packet(len: %i) to tap1\n", nread);
      nwrite = write(tap_fd1, buffer, nread);
      //DEBUGMSG(2,"Written %d bytes to the network\n", nwrite);
    }
	
    if(FD_ISSET(tap_fd1, &rd_set)) {
      /* data from tun/tap: just read it and write it to the network */

      nread = cread(tap_fd1, buffer, BUFSIZE);

 
      /* write length + packet */
      plength = htons(nread);

        if(!dummy){
	    if(isEpochEnd((unsigned char*)buffer)){
		DEBUGMSG(1,"Receive a Epoch end signal\n");
		const int len = 14 + sizeof(struct ip) + 40;
	    unsigned char echobuffer [14 + sizeof(struct ip) + 4] = {0};
		ConstructSignal(echobuffer, (unsigned char*)buffer);	
		nwrite = write(tap_fd1, echobuffer, len);
	    continue;
	  }
	  if(isIP((unsigned char*)buffer) && isTCP((unsigned char*)buffer)){
       	    int newLen = 0;
            verifyPacket(TCP, (unsigned char*)buffer, &newLen);
            nread = newLen;
	  }
	  DEBUGMSG(2,"packet len: %i\n", nread);
       }
      nwrite = write(tap_fd, buffer, nread);
      
      do_debug("TAP2NET %lu: Written %d bytes to the network\n", tap2net, nwrite);
    }

    //if(FD_ISSET(net_fd, &rd_set)) {
	if(0) {
      /* data from the network: read it, and write it to the tun/tap interface. 
       * We need to read the length first, and then the packet */

      /* Read length */      
      nread = read_n(net_fd, (char *)&plength, sizeof(plength));
      if(nread == 0) {
        /* ctrl-c at the other end */
        break;
      }

      net2tap++;

      /* read packet */
      nread = read_n(net_fd, buffer, ntohs(plength));
      do_debug("NET2TAP %lu: Read %d bytes from the network\n", net2tap, nread);

      /* now buffer[] contains a full packet or frame, write it into the tun/tap interface */ 
      nwrite = cwrite(tap_fd, buffer, nread);
      do_debug("NET2TAP %lu: Written %d bytes to the tap interface\n", net2tap, nwrite);
    }
  }
  
  return(0);
}
void tap_side()
{
    int tap0_fd, tap1_fd;
    int maxfd;
    /* initialize tun/tap interface */
    if ((tap0_fd = tun_alloc(diface, IFF_TAP | IFF_NO_PI)) < 0) {
        fprintf(stderr, "Error connecting to tun/tap interface %s!\n",
            diface);
        return;
    }
    if ((tap1_fd = tun_alloc(iface, IFF_TAP | IFF_NO_PI)) < 0) {
        fprintf(stderr, "Error connecting to tun/tap interface %s!\n",
            iface);
        return;
    }
    printf("tap0_fd = %d tap2_fd = %d\n", tap0_fd, tap1_fd);

    maxfd = (tap0_fd > tap1_fd) ? tap0_fd : tap1_fd;
    while (1) {
        int ret;
        fd_set rd_set;
        char buf[128];

        FD_ZERO(&rd_set);
        FD_SET(tap0_fd, &rd_set);
        FD_SET(tap1_fd, &rd_set);

        ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

        if (ret < 0 && errno == EINTR) {
            continue;
        }

        if (ret < 0) {
            perror("select()");
        }

        if (FD_ISSET(tap0_fd, &rd_set)) {
            printf("*GOT tap0 fd set\n");

            /*  
               The TX that got started from parent thread 
               sendto() fn eventually calls ->dev_hard_start_xmit()
               which will not complete unless we read from tap0 fd.
               Reading from tap0 FD causes call tun_aio_read()->
               tun_put_user() which increments the tx pkt stat of tap0
             */
            memset(buf, 0, 128);
            int bytes = cread(tap0_fd, buf, 1024);
            printf("READ %d bytes (from tap0) data: \"%s\"\n",
                   bytes, buf + ETH_HLEN);

            /*      
               The recvfrom() socket call on the tap1 will not complete
               unless a ethernet frame ends up in RX of tap1. This can
               be achieved strangely by 'write' syscall on the tap1.
               The act of write will increment the rx pkt stat on tap1
               (and recvfrom will merely give it to user)
             */

            /* Lets write() slightly modifed string into tap1 fd */
            char *ptr = buf + ETH_HLEN;
            strncpy(ptr, "Bharath", 7);
            ret = write(tap1_fd, buf, bytes);
            printf
                ("written %d bytes (modified from tap0) into tap1\n",
                 ret);
            break;
        }
        if (FD_ISSET(tap1_fd, &rd_set)) {
            printf("*GOT tap0 fd set\n");
        }
    }
}
Exemple #20
0
static inline COUNT
cread_a8 (DECODE_REF fh, BYTE *ar, COUNT count)
{
	assert (ar != NULL);
	return cread (ar, 1, count, fh) == count;
}
Exemple #21
0
/*
 * Read a character from the keyboard.
 * Handle special characters too!
 */
int wxgetch(void)
{
  int f, g;
  int match = 1;
  int len;
  char c;
  static unsigned char mem[8];
  static int leftmem = 0;
  static int init = 0;
  int nfound = 0;
  int start_match;
#if VT_KLUDGE
  char temp[8];
#endif
  struct timeval timeout;
  fd_set readfds;

  if (init == 0) {
    _initkeys();
    init++;
    erasechar = setcbreak(3);
  }

  /* Some sequence still in memory ? */
  if (leftmem > 0) {
    leftmem--;
    if (leftmem == 0)
      pendingkeys = 0;
    if (pendingkeys == 0 && keys_in_buf == 0)
      io_pending = 0;
    return mem[leftmem];
  }
  gotalrm = 0;
  pendingkeys = 0;

  for (len = 1; len < 8 && match; len++) {
#if KEY_KLUDGE
    if (len > 1 && keys_in_buf == 0)
#else
    if (len > 1)
#endif
    {
      timeout.tv_sec = 0;
      timeout.tv_usec = 400000; /* 400 ms */
      FD_ZERO(&readfds);
      FD_SET(0, &readfds);
      if (!(nfound = select(1, &readfds, NULL, NULL, &timeout)))
        break;
    }

#if KEY_KLUDGE
    while ((nfound = cread(&c)) < 0 && (errno == EINTR && !gotalrm))
      ;
#else
    while ((nfound = read(0, &c, 1)) < 0 && (errno == EINTR && !gotalrm))
      ;
#endif

    if (nfound < 1)
      return EOF;

    if (len == 1) {
      /* Enter and erase have precedence over anything else */
      if (c == '\n')
        return c;
      if (c == erasechar)
        return K_ERA;
    }
#if KEY_KLUDGE
    /* Return single characters immideately */
    if (isconsole && nfound == 1 && len == 1)
      return c;

    /* Another hack - detect the Meta Key. */
    if (isconsole && nfound == 2 && len == 1 && c == 27 && escape == 27) {
      cread(&c);
      return c + K_META;
    }
#endif
    mem[len - 1] = c;
    match = 0;
#if VT_KLUDGE
    /* Oh boy. Stupid vt100 2 mode keyboard. */
    strncpy(temp, mem, len);
    if (len > 1 && temp[0] == 27) {
      if (temp[1] == '[')
        temp[1] = 'O';
      else if (temp[1] == 'O')
        temp[1] = '[';
    }
    /* We now have an alternate string to check. */
#endif
    start_match = 0;
    for (f = 0; f < NUM_KEYS; f++) {
#if VT_KLUDGE
      if (_keys[f].len >= len &&
          (strncmp(_keys[f].cap, (char *)mem,  len) == 0 ||
           strncmp(_keys[f].cap, (char *)temp, len) == 0))
#else
        if (_keys[f].len >= len &&
            strncmp(_keys[f].cap, (char *)mem, len) == 0)
#endif
        {
          match++;
          if (_keys[f].len == len) {
            return f + KEY_OFFS;
          }
        }
      /* Does it match on first two chars? */
      if (_keys[f].len > 1 && len == 2 &&
          strncmp(_keys[f].cap, (char *)mem, 2) == 0)
        start_match++;
    }
#if KEY_KLUDGE
    if (!isconsole)
#endif
#ifndef _MINIX /* Minix doesn't have ESC-c meta mode */
      /* See if this _might_ be a meta-key. */
      if (escape == 27 && !start_match && len == 2 && mem[0] == 27)
        return c + K_META;
#endif
  }
  /* No match. in len we have the number of characters + 1 */
  len--; /* for convenience */
  if (len == 1)
    return mem[0];
  /* Remember there are more keys waiting in the buffer */
  pendingkeys++;
  io_pending++;

  /* Reverse the "mem" array */
  for (f = 0; f < len / 2; f++) {
    g = mem[f];
    mem[f] = mem[len - f - 1];
    mem[len - f - 1] = g;
  }
  leftmem = len - 1;
  return mem[leftmem];
}
Exemple #22
0
int main(int argc, char *argv[]) {
  
  int tap_fd, option;
  int flags = IFF_TUN;
  char if_name[IFNAMSIZ] = "";
  int header_len = IP_HDR_LEN;
  int maxfd;
  uint16_t nread, nwrite, plength;
//  uint16_t total_len, ethertype;
  char buffer[BUFSIZE];
  struct sockaddr_in local, remote;
  char remote_ip[16] = "";
  unsigned short int port = PORT;
  int sock_fd, net_fd, optval = 1;
  socklen_t remotelen;
  int cliserv = -1;    /* must be specified on cmd line */
  unsigned long int tap2net = 0, net2tap = 0;

  progname = argv[0];
  
  /* Check command line options */
  while((option = getopt(argc, argv, "i:sc:p:uahd")) > 0){
    switch(option) {
      case 'd':
        debug = 1;
        break;
      case 'h':
        usage();
        break;
      case 'i':
        strncpy(if_name,optarg,IFNAMSIZ-1);
        break;
      case 's':
        cliserv = SERVER;
        break;
      case 'c':
        cliserv = CLIENT;
        strncpy(remote_ip,optarg,15);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'u':
        flags = IFF_TUN;
        break;
      case 'a':
        flags = IFF_TAP;
        header_len = ETH_HDR_LEN;
        break;
      default:
        my_err("Unknown option %c\n", option);
        usage();
    }
  }

  argv += optind;
  argc -= optind;


  if (argc == 2) {
	  strncpy(if_name,argv[0],IFNAMSIZ-1);
	  port = atoi(argv[1]);
      cliserv = SERVER;
      flags = IFF_TAP;
      header_len = ETH_HDR_LEN;
  } else
  if(argc > 0){
    my_err("Too many options!\n");
    usage();
  }

  if(*if_name == '\0'){
    my_err("Must specify interface name!\n");
    usage();
  }else if(cliserv < 0){
    my_err("Must specify client or server mode!\n");
    usage();
  }else if((cliserv == CLIENT)&&(*remote_ip == '\0')){
    my_err("Must specify server address!\n");
    usage();
  }

  /* initialize tun/tap interface */
  if ( (tap_fd = tun_alloc(if_name, flags | IFF_NO_PI)) < 0 ) {
    my_err("Error connecting to tun/tap interface %s!\n", if_name);
    exit(1);
  }

  do_debug("Successfully connected to interface %s\n", if_name);

  if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("socket()");
    exit(1);
  }

  if(cliserv==CLIENT){
    /* Client, try to connect to server */

    /* assign the destination address */
    memset(&remote, 0, sizeof(remote));
    remote.sin_family = AF_INET;
    remote.sin_addr.s_addr = inet_addr(remote_ip);
    remote.sin_port = htons(port);

    /* connection request */
    if (connect(sock_fd, (struct sockaddr*) &remote, sizeof(remote)) < 0){
      perror("connect()");
      exit(1);
    }

    net_fd = sock_fd;
    do_debug("CLIENT: Connected to server %s\n", inet_ntoa(remote.sin_addr));
    
  } else {
    /* Server, wait for connections */

    /* avoid EADDRINUSE error on bind() */
    if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) < 0){
      perror("setsockopt()");
      exit(1);
    }
    
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_port = htons(port);
    if (bind(sock_fd, (struct sockaddr*) &local, sizeof(local)) < 0){
      perror("bind()");
      exit(1);
    }
    
    if (listen(sock_fd, 5) < 0){
      perror("listen()");
      exit(1);
    }
    
    /* wait for connection request */
    remotelen = sizeof(remote);
    memset(&remote, 0, remotelen);
    if ((net_fd = accept(sock_fd, (struct sockaddr*)&remote, &remotelen)) < 0){
      perror("accept()");
      exit(1);
    }

    do_debug("SERVER: Client connected from %s\n", inet_ntoa(remote.sin_addr));
  }
  
  /* use select() to handle two descriptors at once */
  maxfd = (tap_fd > net_fd)?tap_fd:net_fd;

  while(1) {
    int ret;
    fd_set rd_set;

    FD_ZERO(&rd_set);
    FD_SET(tap_fd, &rd_set); FD_SET(net_fd, &rd_set);

    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

    if (ret < 0 && errno == EINTR){
      continue;
    }

    if (ret < 0) {
      perror("select()");
      exit(1);
    }

    if(FD_ISSET(tap_fd, &rd_set)){
      /* data from tun/tap: just read it and write it to the network */
      
      nread = cread(tap_fd, buffer, BUFSIZE);

      tap2net++;
      do_debug("TAP2NET %lu: Read %d bytes from the tap interface\n", tap2net, nread);

      /* write length + packet */
      plength = htons(nread);
      nwrite = cwrite(net_fd, (char *)&plength, sizeof(plength));
      nwrite = cwrite(net_fd, buffer, nread);
      
      do_debug("TAP2NET %lu: Written %d bytes to the network\n", tap2net, nwrite);
    }

    if(FD_ISSET(net_fd, &rd_set)){
      /* data from the network: read it, and write it to the tun/tap interface. 
       * We need to read the length first, and then the packet */

      /* Read length */      
      nread = read_n(net_fd, (char *)&plength, sizeof(plength));
      if(nread == 0) {
        /* ctrl-c at the other end */
        break;
      }

      net2tap++;

      /* read packet */
      nread = read_n(net_fd, buffer, ntohs(plength));
      do_debug("NET2TAP %lu: Read %d bytes from the network\n", net2tap, nread);

      /* now buffer[] contains a full packet or frame, write it into the tun/tap interface */ 
      nwrite = cwrite(tap_fd, buffer, nread);
      do_debug("NET2TAP %lu: Written %d bytes to the tap interface\n", net2tap, nwrite);
    }
  }
  
  return(0);
}
int main(int argc, char *argv[]) {
  
	int tap_fd, option;
	int flags = IFF_TUN;
	char if_name[IFNAMSIZ] = "";
	int header_len = IP_HDR_LEN;
	int maxfd;
	uint16_t nread, nwrite, plength;
	char buffer[BUFSIZE];
	struct sockaddr_in local, remote;
	char remote_ip[16] = "";
	unsigned short int port = PORT;
	int sock_fd, net_fd, optval = 1;
	socklen_t remotelen;
	int cliserv = -1;    /* must be specified on cmd line */
	unsigned long int tap2net = 0, net2tap = 0;

	int listen_sd;
  	int sd;
  	struct sockaddr_in sa_serv;
	struct sockaddr_in sa_cli;
	size_t client_len;
	int err;
	int yes = 1;

	struct ip *ip_header;            //ip header struct
	struct VPNDataHdr* vpn_header;

	int ptc[2];         //pipe from control process to tunnel process

	progname = argv[0];
  
  /* Check command line options */
  while((option = getopt(argc, argv, "i:sc:p:uahd")) > 0){
    switch(option) {
      case 'd':
        debug = 1;
        break;
      case 'h':
        usage();
        break;
      case 'i':
        strncpy(if_name,optarg,IFNAMSIZ-1);
        break;
      case 's':
        cliserv = SERVER;
        break;
      case 'c':
        cliserv = CLIENT;
        strncpy(remote_ip,optarg,15);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'u':
        flags = IFF_TUN;
        break;
      case 'a':
        flags = IFF_TAP;
        header_len = ETH_HDR_LEN;
        break;
      default:
        my_err("Unknown option %c\n", option);
        usage();
    }
  }

  argv += optind;
  argc -= optind;

  if(argc > 0){
    my_err("Too many options!\n");
    usage();
  }

  if(*if_name == '\0'){
    my_err("Must specify interface name!\n");
    usage();
  }else if(cliserv < 0){
    my_err("Must specify client or server mode!\n");
    usage();
  }else if((cliserv == CLIENT)&&(*remote_ip == '\0')){
    my_err("Must specify server address!\n");
    usage();
  }

  /* initialize tun/tap interface */
  if ( (tap_fd = tun_alloc(if_name, flags | IFF_NO_PI)) < 0 ) {
    my_err("Error connecting to tun/tap interface %s!\n", if_name);
    exit(1);
  }

  do_debug("Successfully connected to interface %s\n", if_name);
  




 
  	if ( (sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    	 perror("socket()");
   	 exit(1);
 	 }

	/////////////////////////////////////////////////////////


    	memset(&local, 0, sizeof(local));
    	local.sin_family = AF_INET;
    	local.sin_addr.s_addr = htonl(INADDR_ANY);
    	local.sin_port = htons(port);
    	if (bind(sock_fd, (struct sockaddr*) &local, sizeof(local)) < 0){
      	perror("bind()");
      	exit(1);
    	}

	//init remote
	memset(&remote, 0, sizeof(remote));
	remote.sin_family = AF_INET;
	//remote.sin_addr.s_addr = inet_addr(remote_ip);
  	remote.sin_port = htons(port);	



	net_fd = sock_fd;

    	do_debug("SERVER: UDP built\n");
	//////////////////////////////////////////////////////////////////////

///////////ssl tcp control connection////////////////
	loadcert();
	listen_sd = socket (AF_INET, SOCK_STREAM, 0);   
	if(err < 0){
		printf("err tcp listening sock!\n");
		return 0;
	}
   
	if(setsockopt(listen_sd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1){
		perror("Server-socket() error lol!");
		exit(1);
	}  


	memset (&sa_serv, '\0', sizeof(sa_serv));
	sa_serv.sin_family      = AF_INET;
	sa_serv.sin_addr.s_addr = INADDR_ANY;
	sa_serv.sin_port        = htons (TCP_LISTEN_PORT);          /* Server Port number */
  
	err = bind(listen_sd, (struct sockaddr*) &sa_serv,
	sizeof (sa_serv));
	if(err < 0){
		printf("err tcp bind!\n");
		return 0;
	}
	     
  /* Receive a TCP connection. */
	     
	err = listen (listen_sd, 5);
	do_debug("Server start Listen OK\n");                    


	if(err < 0){
		printf("err tcp listening!\n");
		return 0;
	}
  /////

////////////////////////////////////////////////////

  
  /* use select() to handle two descriptors at once */
  maxfd = (tap_fd > net_fd)?tap_fd:net_fd;
  maxfd = (maxfd > listen_sd)?maxfd:listen_sd;

  while(1) {
    int ret;
    fd_set rd_set;

	struct Session *cursess;
	cursess= slisthead;

    FD_ZERO(&rd_set);
    FD_SET(tap_fd, &rd_set); FD_SET(net_fd, &rd_set);
	FD_SET(0, &rd_set);
	FD_SET(listen_sd,&rd_set);

	while(cursess != 0){
		FD_SET(cursess->sd,&rd_set);
		maxfd = (maxfd > cursess->sd)?maxfd:cursess->sd;
		cursess = cursess->next;
	}

	cursess = slisthead;

    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

    if (ret < 0 && errno == EINTR){
      continue;
    }

    if (ret < 0) {
      perror("select()");
      exit(1);
    }




	if(FD_ISSET(0, &rd_set)){
		memset(buffer,0,BUFSIZE);
		nread = read(0, buffer, BUFSIZE);
		if(0 == strncmp(buffer,"quit",strlen("quit")))
			break;

	}

	if(FD_ISSET(listen_sd, &rd_set)){
		client_len = sizeof(sa_cli);
		sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
		if(err < 0){
			printf("err accept!\n");
			return 0;
		}
		err = sslinit(sd, &slisthead, &sa_cli, "vpnauth");
		if(err)
			do_debug("Client from %s is connected\n", inet_ntoa(sa_cli.sin_addr));
		//continue;

	}


	if(FD_ISSET(tap_fd, &rd_set)){
      /* data from tun/tap: just read it and write it to the network */
		unsigned char outbuffer[VPN_BUFSIZE];
		struct VPNDataHdr *pvpnh = (struct VPNDataHdr*) outbuffer;
		unsigned long curip;
		cursess = 0;
		nread = cread(tap_fd, buffer, BUFSIZE);
		if(nread <= 0)
			continue;
		
		tap2net++;
		do_debug("TAP2NET %lu: Read %d bytes from the tap interface\n", tap2net, nread);

		ip_header = (struct ip*) buffer;
		memcpy(&curip,&(ip_header->ip_dst),sizeof(long));
		cursess = findsessByDstIP(slisthead,curip);
		//memcpy(&tpaddr,&(destsess->ip),sizeof(unsigned long));
		if(cursess == 0)
			continue;
		remote.sin_addr.s_addr = cursess->ip;
		

      /* write length + packet */

		if(32 != getHMACSHA256(buffer, pvpnh->hmac, nread,cursess->s_key,KEY_LENGTH))
			continue;
		nwrite = crypt(buffer,nread,outbuffer + sizeof(struct VPNDataHdr),cursess->s_key,cursess->iv,1);
		if(0 == nwrite)
			continue;
		pvpnh->plen = htons(nwrite);
		sendto(net_fd,outbuffer, nwrite + sizeof(struct VPNDataHdr),0,(struct sockaddr*) &remote, sizeof(remote));
	
		do_debug("TAP2NET %lu: Written %d bytes to the network %s\n", tap2net,nwrite,inet_ntoa(remote.sin_addr));
		//continue;
    }

    if(FD_ISSET(net_fd, &rd_set)){
      /* data from the network: read it, and write it to the tun/tap interface. 
       * We need to read the length first, and then the packet */
		unsigned char inbuffer[VPN_BUFSIZE];
		unsigned char hmac[32];
		int nwrite;
		struct VPNDataHdr *pvpnh = (struct VPNDataHdr*) inbuffer;
		struct sockaddr_in sa;
		socklen_t fromlen;
		fromlen =sizeof(sa);

		nread = recvfrom(net_fd,inbuffer,VPN_BUFSIZE,0,(struct sockaddr*)&sa,&fromlen);

		if(nread <= 0) {
	        continue;
	      }

		cursess = findsessByVPNHeader(slisthead,pvpnh,sa.sin_addr.s_addr);
		if(cursess == 0)
			continue;
			
		nwrite = crypt(inbuffer + sizeof(struct VPNDataHdr),htons(pvpnh->plen),buffer,cursess->s_key,cursess->iv,0);
		if(0 == nwrite)
			continue;
	
		if(32 != getHMACSHA256(buffer, hmac, nwrite,cursess->s_key,KEY_LENGTH) 
		|| !isequal(hmac,pvpnh->hmac,HMAC_LENGTH))
			continue;
		net2tap++;
		/* read packet */
		do_debug("NET2TAP %lu: Read %d bytes from the network\n", net2tap, nread);
		
		/* now buffer[] contains a full packet or frame, write it into the tun/tap interface */ 
		nwrite = cwrite(tap_fd, buffer, nwrite);
		do_debug("NET2TAP %lu: Written %d bytes to the tap interface\n", net2tap, nwrite);
		//continue;
    }

	cursess = slisthead;
	while(cursess != 0){
		if(FD_ISSET(cursess->sd, &rd_set)){
			struct CliRequest* rst;
			memset(buffer,0,BUFSIZE);
			nread = ssl_read(cursess->ssl,buffer,BUFSIZE);
			rst = (struct CliRequest*)buffer;
			if(nread != sizeof(struct CliRequest)){
				break;
			}
			if(nread == 0 || rst->act == QUIT_REQUEST){
				struct in_addr temp;
				temp.s_addr = cursess->ip;
				do_debug("Client from %s break the connection\n", inet_ntoa(temp));
				cleanupSSL(cursess);
				deletesess(&slisthead,cursess);
				//slisthead = 0;
			}

			if(rst->act == IV_REFRESH_REQUEST){
				RefreshIV(cursess);
				do_debug("IV is refreshed:");
				debugSession(cursess);
			}
			if(rst->act == IV_REFRESH_SET){
				struct ServResponse rsp;
				rsp.act = ACT_ACK;
				if(-1 != ssl_write(cursess->ssl,(char*)&rsp, sizeof(struct ServResponse))){
					memcpy(cursess->iv, rst->iv,KEY_LENGTH);
					do_debug("IV is updated:");
					debugSession(cursess);
				}
			}
			if(rst->act == KEY_REFRESH_REQUEST){
				RefreshKEY(cursess);
				do_debug("Key is refreshed:");
				debugSession(cursess);
			}
			if(rst->act == KEY_REFRESH_SET){
				struct ServResponse rsp;
				rsp.act = ACT_ACK;
				if(-1 != ssl_write(cursess->ssl,(char*)&rsp, sizeof(struct ServResponse))){
					memcpy(cursess->s_key, rst->s_key,KEY_LENGTH);
					do_debug("Key is updated:");
					debugSession(cursess);
				}
			}
			
		}
		cursess = cursess->next;
	}


	
  }

	if(slisthead != 0){
		struct Session* tsess = slisthead;
		while(tsess != 0){
			cleanupSSL(tsess);
			tsess = tsess->next;
		}
	}
	freesess(slisthead);
	close(listen_sd);
	close(net_fd);
	close(tap_fd);
	cleanupCTX();
  	
  return(0);
}
Exemple #24
0
signed int 
xdelta1ReconstructDCBuff(DCB_SRC_ID src_id, cfile *patchf, CommandBuffer *dcbuff, 
	unsigned int version)
{
	cfile *add_cfh, *ctrl_cfh;
	unsigned long control_offset, control_end, flags;
	unsigned long len, offset, x, count, proc_count;
	unsigned long add_start, add_pos;
	unsigned char buff[32];
	EDCB_SRC_ID ref_id, add_id;
	unsigned char add_is_sequential, copy_is_sequential;
	cseek(patchf, XDELTA_MAGIC_LEN, CSEEK_FSTART);
	cread(patchf, buff, 4);
	flags = readUBytesBE(buff, 4);
	cread(patchf, buff, 4);

	dcbuff->ver_size = 0;
	
	// the header is 32 bytes, then 2 word's, each the length of the 
	// src/trg file name.
	add_start = 32 + readUBytesBE(buff, 2) + readUBytesBE(buff + 2, 2);
	cseek(patchf, -12, CSEEK_END);
	control_end = ctell(patchf, CSEEK_FSTART);
	cread(patchf, buff, 4);
	control_offset = readUBytesBE(buff,4);

	cseek(patchf, control_offset, CSEEK_FSTART);

	if(flags & XD_COMPRESSED_FLAG) {
		v2printf("compressed segments detected\n");
		if((ctrl_cfh = (cfile *)malloc(sizeof(cfile)))==NULL) {
			return MEM_ERROR;
		}
		copen_child_cfh(ctrl_cfh, patchf, control_offset, control_end, 
			GZIP_COMPRESSOR, CFILE_RONLY);
	} else {
		ctrl_cfh = patchf;
	}

	/* kludge. skipping 8 byte unknown, and to_file md5.*/
	cseek(ctrl_cfh, 24, CSEEK_CUR);

	/* read the frigging to length, since it's variable */
	x = readXDInt(ctrl_cfh, buff);
		v2printf("to_len(%lu)\n", x);

	/* two bytes here I don't know about... */
	cseek(ctrl_cfh, 2, CSEEK_CUR);
	/* get and skip the segment name's len and md5 */
	x = readXDInt(ctrl_cfh, buff);

	cseek(ctrl_cfh, x + 16, CSEEK_CUR);

	/* read the damned segment patch len. */
	x = readXDInt(ctrl_cfh, buff);

	/* skip the seq/has data bytes */
	/* handle sequential/has_data info */
	cread(ctrl_cfh, buff, 2);
	add_is_sequential = buff[1];

	v2printf("patch sequential? (%u)\n", add_is_sequential);

	/* get and skip the next segment name len and md5. */
	x = readXDInt(ctrl_cfh, buff);
	cseek(ctrl_cfh, x + 16, CSEEK_CUR);

	/* read the damned segment patch len. */
	x = readXDInt(ctrl_cfh, buff);
	v2printf("seg2_len(%lu)\n", x);

	/* handle sequential/has_data */
	cread(ctrl_cfh, buff, 2);
	copy_is_sequential = buff[1];
	v2printf("copy is sequential? (%u)\n", copy_is_sequential);
	/* next get the number of instructions (eg copy | adds) */
	count = readXDInt(ctrl_cfh, buff);
	proc_count=0;
	/* so starts the commands... */
	v2printf("supposedly %lu commands...\nstarting command processing at %zi\n",
		count, ctell(ctrl_cfh, CSEEK_FSTART));
	if(flags & XD_COMPRESSED_FLAG) {
		add_pos = 0;
		if((add_cfh = (cfile *)malloc(sizeof(cfile)))==NULL) {
			return MEM_ERROR;
		}
		copen_child_cfh(add_cfh, patchf, add_start, control_offset, 
			GZIP_COMPRESSOR, CFILE_RONLY);
		add_id = DCB_REGISTER_ADD_SRC(dcbuff, add_cfh, NULL, 1);
	} else {
		add_pos = add_start;
		add_id = DCB_REGISTER_VOLATILE_ADD_SRC(dcbuff, patchf, NULL, 0);
	}
	ref_id = src_id;
	while(proc_count++ != count) {
		x = readXDInt(ctrl_cfh, buff);
		offset = readXDInt(ctrl_cfh, buff);
		len = readXDInt(ctrl_cfh, buff);
		if(x==XD_INDEX_COPY) {
			DCB_add_copy(dcbuff, offset, 0, len, ref_id);
		} else {
			if(add_is_sequential != 0) {
				offset += add_pos; 
				add_pos += len;
			} else {
				offset += add_pos;
			}
			DCB_add_add(dcbuff, offset, len, add_id);
		}
	}
	v2printf("finishing position was %zi\n", ctell(ctrl_cfh, CSEEK_FSTART));
	v2printf("processed %lu of %lu commands\n", proc_count, count);
	dcbuff->ver_size = dcbuff->reconstruct_pos;
	if(flags & XD_COMPRESSED_FLAG) {
		cclose(ctrl_cfh);
		free(ctrl_cfh);
	}
	return 0;
}
Exemple #25
0
BOOLEAN
LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr)
{
	uio_Stream *in_fp;
	char file[PATH_MAX];
	char buf[256];
	SUMMARY_DESC loc_sd;
	GAME_STATE_FILE *fp;
	DECODE_REF fh;
	COUNT num_links;
	STAR_DESC SD;
	ACTIVITY Activity;

	sprintf (file, "starcon2.%02u", which_game);
	in_fp = res_OpenResFile (saveDir, file, "rb");
	if (!in_fp)
		return FALSE;

	if (!LoadSummary (&loc_sd, in_fp))
	{
		log_add (log_Error, "Warning: Savegame is corrupt");
		res_CloseResFile (in_fp);
		return FALSE;
	}

	if (!SummPtr)
	{
		SummPtr = &loc_sd;
	}
	else
	{	// only need summary for displaying to user
		memcpy (SummPtr, &loc_sd, sizeof (*SummPtr));
		res_CloseResFile (in_fp);
		return TRUE;
	}

	// Crude check for big-endian/little-endian incompatibilities.
	// year_index is suitable as it's a multi-byte value within
	// a specific recognisable range.
	if (SummPtr->year_index < START_YEAR ||
			SummPtr->year_index >= START_YEAR +
			YEARS_TO_KOHRAH_VICTORY + 1 /* Utwig intervention */ +
			1 /* time to destroy all races, plenty */ +
			25 /* for cheaters */)
	{
		log_add (log_Error, "Warning: Savegame corrupt or from "
				"an incompatible platform.");
		res_CloseResFile (in_fp);
		return FALSE;
	}

	GlobData.SIS_state = SummPtr->SS;

	if ((fh = copen (in_fp, FILE_STREAM, STREAM_READ)) == 0)
	{
		res_CloseResFile (in_fp);
		return FALSE;
	}

	ReinitQueue (&GLOBAL (GameClock.event_q));
	ReinitQueue (&GLOBAL (encounter_q));
	ReinitQueue (&GLOBAL (ip_group_q));
	ReinitQueue (&GLOBAL (npc_built_ship_q));
	ReinitQueue (&GLOBAL (built_ship_q));

	memset (&GLOBAL (GameState[0]), 0, sizeof (GLOBAL (GameState)));
	Activity = GLOBAL (CurrentActivity);
	LoadGameState (&GlobData.Game_state, fh);
	NextActivity = GLOBAL (CurrentActivity);
	GLOBAL (CurrentActivity) = Activity;

	LoadRaceQueue (fh, &GLOBAL (avail_race_q));
	// START_INTERPLANETARY is only set when saving from Homeworld
	//   encounter screen. When the game is loaded, the
	//   GenerateOrbitalFunction for the current star system will
	//   create the encounter anew and populate the npc queue.
	if (!(NextActivity & START_INTERPLANETARY))
	{
		if (NextActivity & START_ENCOUNTER)
			LoadShipQueue (fh, &GLOBAL (npc_built_ship_q));
		else if (LOBYTE (NextActivity) == IN_INTERPLANETARY)
			// XXX: Technically, this queue does not need to be
			//   saved/loaded at all. IP groups will be reloaded
			//   from group state files. But the original code did,
			//   and so will we until we can prove we do not need to.
			LoadGroupQueue (fh, &GLOBAL (ip_group_q));
		else
			// XXX: The empty queue read is only needed to maintain
			//   the savegame compatibility
			LoadEmptyQueue (fh);
	}
	LoadShipQueue (fh, &GLOBAL (built_ship_q));

	// Load the game events (compressed)
	cread_16 (fh, &num_links);
	{
#ifdef DEBUG_LOAD
		log_add (log_Debug, "EVENTS:");
#endif /* DEBUG_LOAD */
		while (num_links--)
		{
			HEVENT hEvent;
			EVENT *EventPtr;

			hEvent = AllocEvent ();
			LockEvent (hEvent, &EventPtr);

			LoadEvent (EventPtr, fh);

#ifdef DEBUG_LOAD
		log_add (log_Debug, "\t%u/%u/%u -- %u",
				EventPtr->month_index,
				EventPtr->day_index,
				EventPtr->year_index,
				EventPtr->func_index);
#endif /* DEBUG_LOAD */
			UnlockEvent (hEvent);
			PutEvent (hEvent);
		}
	}

	// Load the encounters (black globes in HS/QS (compressed))
	cread_16 (fh, &num_links);
	{
		while (num_links--)
		{
			HENCOUNTER hEncounter;
			ENCOUNTER *EncounterPtr;

			hEncounter = AllocEncounter ();
			LockEncounter (hEncounter, &EncounterPtr);

			LoadEncounter (EncounterPtr, fh);

			UnlockEncounter (hEncounter);
			PutEncounter (hEncounter);
		}
	}

	// Copy the star info file from the compressed stream
	fp = OpenStateFile (STARINFO_FILE, "wb");
	if (fp)
	{
		DWORD flen;

		cread_32 (fh, &flen);
		while (flen)
		{
			COUNT num_bytes;

			num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
			cread (buf, num_bytes, 1, fh);
			WriteStateFile (buf, num_bytes, 1, fp);

			flen -= num_bytes;
		}
		CloseStateFile (fp);
	}

	// Copy the defined groupinfo file from the compressed stream
	fp = OpenStateFile (DEFGRPINFO_FILE, "wb");
	if (fp)
	{
		DWORD flen;

		cread_32 (fh, &flen);
		while (flen)
		{
			COUNT num_bytes;

			num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
			cread (buf, num_bytes, 1, fh);
			WriteStateFile (buf, num_bytes, 1, fp);

			flen -= num_bytes;
		}
		CloseStateFile (fp);
	}

	// Copy the random groupinfo file from the compressed stream
	fp = OpenStateFile (RANDGRPINFO_FILE, "wb");
	if (fp)
	{
		DWORD flen;

		cread_32 (fh, &flen);
		while (flen)
		{
			COUNT num_bytes;

			num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
			cread (buf, num_bytes, 1, fh);
			WriteStateFile (buf, num_bytes, 1, fp);

			flen -= num_bytes;
		}
		CloseStateFile (fp);
	}

	LoadStarDesc (&SD, fh);

	cclose (fh);
	res_CloseResFile (in_fp);

	EncounterGroup = 0;
	EncounterRace = -1;

	ReinitQueue (&race_q[0]);
	ReinitQueue (&race_q[1]);
	CurStarDescPtr = FindStar (NULL, &SD.star_pt, 0, 0);
	if (!(NextActivity & START_ENCOUNTER)
			&& LOBYTE (NextActivity) == IN_INTERPLANETARY)
		NextActivity |= START_INTERPLANETARY;

	return TRUE;
}
Exemple #26
0
void
bread(ufs2_daddr_t blkno, char *buf, int size)
{
	int secsize, bytes, resid, xfer, base, cnt, i;
	static char *tmpbuf;
	off_t offset;

loop:
	offset = blkno << dev_bshift;
	secsize = sblock->fs_fsize;
	base = offset % secsize;
	resid = size % secsize;
	/*
	 * If the transfer request starts or ends on a non-sector
	 * boundary, we must read the entire sector and copy out
	 * just the part that we need.
	 */
	if (base == 0 && resid == 0) {
		cnt = cread(diskfd, buf, size, offset);
		if (cnt == size)
			return;
	} else {
		if (tmpbuf == NULL && (tmpbuf = malloc(secsize)) == 0)
			quit("buffer malloc failed\n");
		xfer = 0;
		bytes = size;
		if (base != 0) {
			cnt = cread(diskfd, tmpbuf, secsize, offset - base);
			if (cnt != secsize)
				goto bad;
			xfer = MIN(secsize - base, size);
			offset += xfer;
			bytes -= xfer;
			resid = bytes % secsize;
			memcpy(buf, &tmpbuf[base], xfer);
		}
		if (bytes >= secsize) {
			cnt = cread(diskfd, &buf[xfer], bytes - resid, offset);
			if (cnt != bytes - resid)
				goto bad;
			xfer += cnt;
			offset += cnt;
		}
		if (resid == 0)
			return;
		cnt = cread(diskfd, tmpbuf, secsize, offset);
		if (cnt == secsize) {
			memcpy(&buf[xfer], tmpbuf, resid);
			return;
		}
	}
bad:
	if (blkno + (size / dev_bsize) > fsbtodb(sblock, sblock->fs_size)) {
		/*
		 * Trying to read the final fragment.
		 *
		 * NB - dump only works in TP_BSIZE blocks, hence
		 * rounds `dev_bsize' fragments up to TP_BSIZE pieces.
		 * It should be smarter about not actually trying to
		 * read more than it can get, but for the time being
		 * we punt and scale back the read only when it gets
		 * us into trouble. (mkm 9/25/83)
		 */
		size -= dev_bsize;
		goto loop;
	}
	if (cnt == -1)
		msg("read error from %s: %s: [block %jd]: count=%d\n",
			disk, strerror(errno), (intmax_t)blkno, size);
	else
		msg("short read error from %s: [block %jd]: count=%d, got=%d\n",
			disk, (intmax_t)blkno, size, cnt);
	if (++breaderrors > BREADEMAX) {
		msg("More than %d block read errors from %s\n",
			BREADEMAX, disk);
		broadcast("DUMP IS AILING!\n");
		msg("This is an unrecoverable error.\n");
		if (!query("Do you want to attempt to continue?")){
			dumpabort(0);
			/*NOTREACHED*/
		} else
			breaderrors = 0;
	}
	/*
	 * Zero buffer, then try to read each sector of buffer separately,
	 * and bypass the cache.
	 */
	memset(buf, 0, size);
	for (i = 0; i < size; i += dev_bsize, buf += dev_bsize, blkno++) {
		if ((cnt = pread(diskfd, buf, (int)dev_bsize,
		    ((off_t)blkno << dev_bshift))) == dev_bsize)
			continue;
		if (cnt == -1) {
			msg("read error from %s: %s: [sector %jd]: count=%ld\n",
			    disk, strerror(errno), (intmax_t)blkno, dev_bsize);
			continue;
		}
		msg("short read from %s: [sector %jd]: count=%ld, got=%d\n",
		    disk, (intmax_t)blkno, dev_bsize, cnt);
	}
}
off_t
clseek(int fd, off_t offset, int where)
{
	struct sd *s;

	s = ss[fd];

	if(s->compressed == 0) {
		off_t res = lseek(fd, offset, where);
		if (res != (off_t)-1) {
			/* make sure the lookahead buffer is invalid */
			s->stream.avail_in = 0;
		}
		return (res);
	}

	switch(where) {
	case SEEK_CUR:
		    offset += s->stream.total_out;
	case SEEK_SET:
		/* if seek backwards, simply start from the beginning */
		if (offset < s->stream.total_out) {
			off_t res;
			void *sav_inbuf;

			res = lseek(fd, 0, SEEK_SET);
			if(res == (off_t)-1)
			    return(res);
			/* ??? perhaps fallback to close / open */

			inflateEnd(&(s->stream));

			sav_inbuf = s->inbuf; /* don't allocate again */
			memset(s, 0, sizeof(struct sd)); /* this resets total_out to 0! */

			inflateInit2(&(s->stream), -15);
			s->stream.next_in = s->inbuf = sav_inbuf;

			s->fd = fd;
			check_header(s); /* skip the .gz header */
		}

		    /* to seek forwards, throw away data */
		if (offset > s->stream.total_out) {
			off_t toskip = offset - s->stream.total_out;

			while (toskip > 0) {
#define DUMMYBUFSIZE 256
				char dummybuf[DUMMYBUFSIZE];
				off_t len = toskip;
				if (len > DUMMYBUFSIZE) len = DUMMYBUFSIZE;
				if (cread(fd, dummybuf, len) != len) {
					errno = EINVAL;
					return ((off_t)-1);
				}
				toskip -= len;
			}
		}
#ifdef DEBUG
		if (offset != s->stream.total_out)
			panic("lseek compressed");
#endif
		return (offset);
	case SEEK_END:
		errno = EINVAL;
		break;
	default:
		errno = EINVAL;
	}

	return((off_t)-1);
}
Exemple #28
0
int main(int argc, char **argv)
{
	char *devname = malloc(IFNAMSIZ+1) ;
	char *str = malloc(50) ;
	char *buffer ;
	char *port_str = NULL;
	int tun_fd = tun_alloc(devname) ;
	int net_fd = 0, sock_fd = 0;
	unsigned int ip = 0;
	struct sockaddr_in remote;
	unsigned short port = 2002;
	char *server_domain = NULL;
	unsigned short nread;
	int n;
	int socktype = SOCK_STREAM;
	int c ;
	struct addrinfo *hints = malloc(sizeof(struct addrinfo));
	struct addrinfo *result = malloc(sizeof(struct addrinfo));

	while ((c = getopt (argc, argv, "us:a:p:")) != -1)
	{
		switch (c)
		{
		case 'a':
			ip = inet_addr(optarg) ;
			break ;
		case 's':
			server_domain = malloc(strlen(optarg)+2);
			strcpy(server_domain, optarg);
			break ;
		case 'u':
			socktype = SOCK_DGRAM;
			break;
		case 'p':
			port = atoi(optarg);
			break;
		default:
			usage(argv[0]);
			printf("Unrecognized option %c\n", c);
			return -1;
		}
	}


	if(server_domain == NULL)
	{
		usage(argv[0]);
		printf("Please specify a server using the -s argument\n");
		return -1 ;
	}

	if(tun_fd <= 0)
	{
		printf("Could not create tun device.\nPlease make sure you are running as root and that the tun kernel module is loaded.\n") ;
		return -1;
	}

//	printf("New tun device = %s\n", devname) ;

	if ( (sock_fd = socket(AF_INET, socktype, 0)) < 0) {
		perror("socket()");
		exit(1);
	}

	// Look up the IP address associated with the user-supplied domain
	memset(hints, 0, sizeof(struct addrinfo));
	hints->ai_family = AF_UNSPEC;
	hints->ai_socktype = SOCK_DGRAM;
	hints->ai_flags = AI_PASSIVE;
	hints->ai_protocol = 0;
	hints->ai_canonname = NULL;
	hints->ai_addr = NULL;
	hints->ai_next = NULL;
	port_str = malloc(20);
	sprintf(port_str, "%d", (int)(port & 0xffff));
	getaddrinfo(server_domain, port_str, hints, &result);
	memcpy(&remote, result->ai_addr, sizeof(struct sockaddr_in));
//	printf("domain = %s\nIP = %08x\n", server_domain, ((struct sockaddr_in*)result->ai_addr)->sin_addr.s_addr);


	/* connection request */
	if (connect(sock_fd, (struct sockaddr*) &remote, sizeof(remote)) < 0)
	{
		perror("connect()");
		exit(1);
	}

	net_fd = sock_fd;
	printf("CLIENT: Connected to server %s\n", inet_ntoa(remote.sin_addr));

	if(ip == 0)
	{
		get_ip_from_server(net_fd, devname);
	}
	else
	{
		register_static_ip(net_fd, ip, devname);
	}
	int maxfd = (tun_fd > net_fd)?tun_fd:net_fd;
	
	while(1)
	{
		fd_set rd_set ;
		struct timeval timeout;

		// If we come close to timing out, we will send a keep-alive packet.
		timeout.tv_sec = SOCK_TIMEOUT / 4;
		timeout.tv_usec = 0;

		FD_ZERO(&rd_set) ;
		FD_SET(tun_fd,&rd_set) ;
		FD_SET(net_fd,&rd_set);

		int ret = select(maxfd + 1, &rd_set, NULL, NULL, &timeout);

		if (ret < 0 && errno == EINTR)
			continue;

		if (ret < 0)
		{
			perror("select()");
			exit(1);
		}

		if(ret == 0)
		{
			// Timeout
			buffer = malloc(100) ;
			struct ip_header *iphdr = (struct ip_header*)buffer ;
			memset(buffer,0,100) ;
			iphdr->vers = 0x45 ;
			iphdr->ip_header_len = 20 ;
			iphdr->ttl = 64;
			iphdr->dest_ip = -1 ;
			iphdr->source_ip = -1;
			
			do
			{
				// Send keepalive
				if(cwrite(net_fd, buffer, 20) <= 0)
				{
					printf("error: cwrite failed while sending keepalive\n");
					exit(1);
				}
				
				timeout.tv_sec = 1;
				timeout.tv_usec = 0;

				FD_ZERO(&rd_set) ;
				FD_SET(net_fd,&rd_set);
			}while(select(maxfd + 1, &rd_set, NULL, NULL, &timeout) == 0);

			// Set the interface address.
			free(buffer) ;
			continue;
		}

		if(FD_ISSET(tun_fd, &rd_set))
		{
			buffer = malloc(2000);
			*(int*)buffer = 0 ;
			/* data from tun/tap: just read it and write it to the network */

			nread = cread(tun_fd, buffer, 2000);

			/* write length + packet */
			if(cwrite(net_fd, buffer, nread) <= 0)
			{
				printf("error: writing to net_fd\n");
				exit(1) ;
			}
			free(buffer);
		}

		if(FD_ISSET(net_fd, &rd_set))
		{
			ioctl(net_fd, FIONREAD,&n);

			buffer = malloc(n);
			*(int*) buffer = 0 ;

			if(n == 0)
			{
				printf("Connection closed by remote host.\n");
	close(sock_fd) ;

	while ( (sock_fd = socket(AF_INET, socktype, 0)) < 0) {
		perror("socket()");
		sleep(1) ;
	}

	// Look up the IP address associated with the user-supplied domain
	memset(hints, 0, sizeof(struct addrinfo));
	hints->ai_family = AF_UNSPEC;
	hints->ai_socktype = SOCK_DGRAM;
	hints->ai_flags = AI_PASSIVE;
	hints->ai_protocol = 0;
	hints->ai_canonname = NULL;
	hints->ai_addr = NULL;
	hints->ai_next = NULL;
	getaddrinfo(server_domain, "2002", hints, &result);
	memcpy(&remote, result->ai_addr, sizeof(struct sockaddr_in));

	// Attempt to reconnect.
	while (connect(sock_fd, (struct sockaddr*) &remote, sizeof(remote)) < 0)
	{
		perror("connect()");
		sleep(1) ;
	}

	net_fd = sock_fd;
	printf("CLIENT: Connected to server %s\n", inet_ntoa(remote.sin_addr));

	// Re-register the IP address with the server after we have reconnected.
	register_static_ip(net_fd, ip, devname);
				sleep(2) ;
				continue ;
			}

			// read packet
			nread = read(net_fd, buffer, n);

			// now buffer[] contains a full packet or frame, write it into the tun/tap interface
			if(write(tun_fd, buffer, nread) <= 0)
			{
				printf("tun_fd = %08x buffer = %p nread = %d\n", tun_fd, buffer, nread) ;
				perror("write to tun_fd") ;
			}
			free(buffer);
		}
	}

	// Clean up
	free(devname) ;
	free(str);
	close(sock_fd);
	return 0 ;
}