Esempio n. 1
0
/* called by tun/tap_send routines */
static int
tuntap_do_send (int fd, struct pbuf *p)
{
#ifdef HAVE_LINUX_IF_TUN_H
	pbuf_raise (p, 4);
	p->d[0] = p->d[1] = 0;
	PUT_16 (p->d + 2, ETH_P_IPV6);
#endif
	return write (fd, p->d, p->dlen) < 0 ? -1 : 0;
}
Esempio n. 2
0
int			add_query(struct dns_hdr *hdr, void *where, char *name, 
				  t_conf *conf, uint16_t type)
{
  struct req_hdr	*req;
  size_t		query_len;
  int			actual_len;

  
  query_len = strlen(name) + 1;
  actual_len = where - (void *)hdr;
  if ((query_len + actual_len + RR_HDR_SIZE) > MAX_DNS_LEN)
    return (-1);
  PUT_16(&hdr->qdcount, GET_16(&hdr->qdcount)+1);
  strcpy(where , name);
  req = (struct req_hdr *) (where + query_len);
  PUT_16(&req->qtype, type);
  PUT_16(&req->qclass, CLASS_IN);
  return ((int) (JUMP_REQ_HDR(req) - (char *)(hdr)));
}
Esempio n. 3
0
void			*add_reply(struct dns_hdr *hdr, void *where, uint16_t type, char *encoded_data)
{
  struct rr_hdr		*rr;
  uint16_t		*compress;
  int			len;

  PUT_16(&hdr->ancount, GET_16(&hdr->ancount)+1);
  hdr->arcount = 0;
  compress = where;
  PUT_16(compress, sizeof(struct dns_hdr) | COMPRESS_FLAG);
  rr = where + sizeof(uint16_t);
  PUT_16(&rr->type, type);
  PUT_16(&rr->klass, CLASS_IN);
  PUT_16(&rr->ttl, 0);
  where = JUMP_RR_HDR(rr);
  strcpy(where, encoded_data);
  if (type == TYPE_TXT)
    dns_encode(where);
  len = strlen(where);
  PUT_16(&rr->rdlength,len);
  return (where + len);
}
Esempio n. 4
0
int
main(int ac, char **av)
{
	int fd, n, i;
	unsigned long ph, ps, np;
	long nnote, nnote2, ns;

	if (ac != 2) {
		fprintf(stderr, "Usage: %s elf-file\n", av[0]);
		exit(1);
	}
	fd = open(av[1], O_RDWR);
	if (fd < 0) {
		perror(av[1]);
		exit(1);
	}

	nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr);
	nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote);

	n = read(fd, buf, sizeof(buf));
	if (n < 0) {
		perror("read");
		exit(1);
	}

	if (memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
		goto notelf;
	e_class = buf[E_IDENT+EI_CLASS];
	if (e_class != ELFCLASS32 && e_class != ELFCLASS64)
		goto notelf;
	e_data = buf[E_IDENT+EI_DATA];
	if (e_data != ELFDATA2MSB && e_data != ELFDATA2LSB)
		goto notelf;
	if (n < E_HSIZE)
		goto notelf;

	ph = (e_class == ELFCLASS32 ? GET_32(E_PHOFF) : GET_64(E_PHOFF));
	ps = GET_16(E_PHENTSIZE);
	np = GET_16(E_PHNUM);
	if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
		goto notelf;
	if (ph + (np + 2) * ps + nnote + nnote2 > n)
		goto nospace;

	for (i = 0; i < np; ++i) {
		if (GET_32(ph + PH_TYPE) == PT_NOTE) {
			fprintf(stderr, "%s already has a note entry\n",
				av[1]);
			exit(0);
		}
		ph += ps;
	}

	/* XXX check that the area we want to use is all zeroes */
	for (i = 0; i < 2 * ps + nnote + nnote2; ++i)
		if (buf[ph + i] != 0)
			goto nospace;

	/* fill in the program header entry */
	ns = ph + 2 * ps;
	PUT_32(ph + PH_TYPE, PT_NOTE);
	if (e_class == ELFCLASS32)
		PUT_32(ph + PH_OFFSET, ns);
	else
		PUT_64(ph + PH_OFFSET, ns);

	if (e_class == ELFCLASS32)
		PUT_32(ph + PH_FILESZ, nnote);
	else
		PUT_64(ph + PH_FILESZ, nnote);

	/* fill in the note area we point to */
	/* XXX we should probably make this a proper section */
	PUT_32(ns, strlen(arch) + 1);
	PUT_32(ns + 4, N_DESCR * 4);
	PUT_32(ns + 8, 0x1275);
	strcpy((char *) &buf[ns + 12], arch);
	ns += 12 + strlen(arch) + 1;
	for (i = 0; i < N_DESCR; ++i, ns += 4)
		PUT_32BE(ns, descr[i]);

	/* fill in the second program header entry and the RPA note area */
	ph += ps;
	PUT_32(ph + PH_TYPE, PT_NOTE);
	if (e_class == ELFCLASS32)
		PUT_32(ph + PH_OFFSET, ns);
	else
		PUT_64(ph + PH_OFFSET, ns);

	if (e_class == ELFCLASS32)
		PUT_32(ph + PH_FILESZ, nnote);
	else
		PUT_64(ph + PH_FILESZ, nnote2);

	/* fill in the note area we point to */
	PUT_32(ns, strlen(rpaname) + 1);
	PUT_32(ns + 4, sizeof(rpanote));
	PUT_32(ns + 8, 0x12759999);
	strcpy((char *) &buf[ns + 12], rpaname);
	ns += 12 + ROUNDUP(strlen(rpaname) + 1);
	for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
		PUT_32BE(ns, rpanote[i]);

	/* Update the number of program headers */
	PUT_16(E_PHNUM, np + 2);

	/* write back */
	lseek(fd, (long) 0, SEEK_SET);
	i = write(fd, buf, n);
	if (i < 0) {
		perror("write");
		exit(1);
	}
	if (i < n) {
		fprintf(stderr, "%s: write truncated\n", av[1]);
		exit(1);
	}

	exit(0);

 notelf:
	fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
	exit(1);

 nospace:
	fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
		av[1]);
	exit(1);
}
Esempio n. 5
0
static int mpv_send( struct rtp_endpoint *ep, void *d )
{
	struct rtp_mpv *out = (struct rtp_mpv *)d;
	int i, j, space, off, min_space;
	struct iovec v[48];
	unsigned char vhdr[4];

	/* MPEG video header always follows the RTP header */
	PUT_16( vhdr, out->temporal_reference );
	vhdr[2] = out->picture_type; /* will be different for each frame */
	vhdr[3] = out->vectors;
	v[1].iov_base = vhdr;
	v[1].iov_len = 4;

	i = 0;
	j = 2;
	space = ep->max_data_size - 4;

	/* If this is an I frame, insert the saved Video Sequence Header */
	if( out->picture_type == 1 )
	{
		vhdr[2] |= 0x20; /* Sequence-header-present bit */

		/* add the block to the frame */
		v[j].iov_base = out->vsh;
		v[j].iov_len = out->vsh_len;

		space -= v[j].iov_len;
		++j;
	}

	for( i = 0; i < out->blk_count; ++i )
	{
		/* We can fragment slices, but after the initial fragment,
		 * all the remaining fragments must be put into their own
		 * packets.  This means fragmentation only makes sense if
		 * the slice is larger than our MTU. */
		if( out->blk[i].len > ep->max_data_size - 4 ) min_space = 4;
		else min_space = out->blk[i].len;

		/* If we don't have enough space for this entire block, or if
		 * we're fragmenting and we don't have enough space for the
		 * start code, first send out the previous blocks. */
		if( space < min_space )
		{
			if( send_rtp_packet( ep, v, j, out->timestamp, 0 ) < 0 )
				return -1;
			j = 2;
			vhdr[2] = out->picture_type;
			space = ep->max_data_size - 4;
		}

		/* add the block to the frame */
		v[j].iov_base = out->blk[i].d;
		v[j].iov_len = out->blk[i].len;

		/* if this is a slice, set the Beginning-of-slice bit */
		if( out->blk[i].d[3] > 0 && out->blk[i].d[3] <= 0xAF )
			vhdr[2] |= 0x10;

		/* if the entire block fit, go on to the next block */
		if( v[j].iov_len <= space )
		{
			/* if this is a slice, set the End-of-slice bit */
			if( out->blk[i].d[3] > 0 && out->blk[i].d[3] <= 0xAF )
				vhdr[2] |= 0x08;
			space -= v[j].iov_len;
			++j;
			continue;
		}

		/* block did not fit, so send the first fragment */
		v[j].iov_len = space;
		/* the last byte of the packet is not the end of a slice, so
		 * clear the End-of-slice bit */
		vhdr[2] &= ~0x08;
		if( send_rtp_packet( ep, v, j + 1, out->timestamp, 0 ) < 0 )
			return -1;

		/* send all remaining fragments by themselves */
		for( off = space; off < out->blk[i].len;
				off += v[2].iov_len )
		{
			vhdr[2] = out->picture_type;
			v[2].iov_base = out->blk[i].d + off;
			v[2].iov_len = out->blk[i].len - off;
			if( v[2].iov_len > ep->max_data_size - 4 )
				v[2].iov_len = ep->max_data_size - 4;
			else
				vhdr[2] |= 0x08; /* End-of-slice bit */
			if( send_rtp_packet( ep, v, 3, out->timestamp,
					( vhdr[2] & 0x08 ) &&
					( ( i + 1 ) == out->blk_count ) ) < 0 )
				return -1;
		}
		j = 2;
		vhdr[2] = out->picture_type;
		space = ep->max_data_size - 4;
	}

	/* send any unsent blocks */
	if( j > 2 && send_rtp_packet( ep, v, j, out->timestamp, 1 ) < 0 )
		return -1;

	return 0;
}