Beispiel #1
0
uint16_t dns_packet_get_field(struct dns_packet *p, unsigned idx) {
    assert(p);
    assert(idx < 2*6);
    uint16_t r;

    GET_16(p->data, idx, r);

    return ntohs(r);
}
Beispiel #2
0
int
handle_802ip_frame (struct iface_ether *iface, struct pbuf *p)
{
	if (GET_16 (p->d + 12) == ETHERNET_IPV6_TYPE && memcmp (ip_iface->hwaddr, p->d + 6, 6)) {
		dump_packet ("Got from ip", p);
		tap_iface->send_frame (tap_iface, p);
	}
	return 0;
}
Beispiel #3
0
uint8_t			query_is_compressed(char *buffer, uint16_t len)
{
  char			*name;
  struct dns_hdr	*hdr;

  hdr = (struct dns_hdr *) buffer;
  if (!(name  = jump_end_query(buffer, GET_16(&hdr->qdcount), len)))
    return (0);
  return ((*name & COMPRESS_FLAG_CHAR) == COMPRESS_FLAG_CHAR);
}
Beispiel #4
0
static uint16_t		get_type_request(void *buffer, int max_len)
{
  struct dns_hdr	*hdr;
  char 			*ptr;
  
  hdr = buffer;
  if (sizeof(struct dns_hdr) > max_len)
    return (-1);
  if (hdr->qdcount > 0)
    {
      ptr = memchr(JUMP_DNS_HDR(hdr), 0, max_len - sizeof(struct dns_hdr));
      if (ptr)
        return GET_16(&(((struct req_hdr *) (ptr+1))->qtype));
    }
  return (0);
}
Beispiel #5
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)));
}
Beispiel #6
0
static int		build_ressources_reply(t_conf *conf, void *buffer, 
					       int  max_len)
{
  struct dns_hdr	*hdr;
  t_list		*list;
  void			*where;
  char			buffer2[MAX_REQ_LEN];

  hdr = buffer;
  hdr->ra = 1;
  hdr->qr = 1;

  if (!(where = jump_end_query(buffer, GET_16(&hdr->qdcount), max_len)))
    return (-1);
  for (list = conf->ressources; list; list = list->next)
    {
      base64_encode(list->data, buffer2, (strchr(list->data, ':') - list->data));
      where = add_reply(hdr, where, TYPE_KEY, buffer2);
    }
  return (where - buffer);
}
Beispiel #7
0
/* called by tun/tap_read_callback */
static int
tuntap_do_read (int fd, struct pbuf *p)
{
	p->dlen = read (fd, p->d, p->max);
	if (p->dlen < 0) {
		perror ("read from tun");
		exit (1);
	}
	// does 0 mean the interface died?
#ifdef HAVE_LINUX_IF_TUN_H
	if (p->dlen > 4 && GET_16 (p->d + 2) == ETH_P_IPV6) {
		pbuf_drop (p, 4);
		return 0;
	}
#else
	if (p->dlen > 0) {
		return 0;
	}
#endif
	return -1;
}
Beispiel #8
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);
}
Beispiel #9
0
int			build_error_reply(t_conf *conf, void *req, int max_len, char *error)
{

  struct dns_hdr	*hdr;
  void			*where;
  t_packet		*packet;
  char			buffer[BASE64_SIZE(MAX_ERROR_SIZE) + PACKET_LEN];
  char			buffer2[BASE64_SIZE(MAX_ERROR_SIZE) + PACKET_LEN];
  int			len;

  hdr = req;
  hdr->ra = 1;
  hdr->qr = 1;
 if (!(where = jump_end_query(req, GET_16(&hdr->qdcount), max_len)))
      return (-1);
  packet = (t_packet *) memset(buffer, 0, PACKET_LEN);
  packet->type = ERR;
  len = strlen(error);
  memcpy(buffer+PACKET_LEN, error, len+1);
  base64_encode(buffer, buffer2, PACKET_LEN + len);
  where = add_reply(hdr, where, TYPE_KEY, buffer2);
  return (where - req);
}
Beispiel #10
0
static xmms_wave_format_t
read_wave_header (xmms_wave_data_t *data, guint8 *buf, gint bytes_read)
{
	gchar stmp[5];
	guint32 tmp32, data_size;
	guint16 tmp16;
	gint bytes_left = bytes_read;
	xmms_wave_format_t ret = WAVE_FORMAT_UNDEFINED;

	if (bytes_left < WAVE_HEADER_MIN_SIZE) {
		xmms_log_error ("Not enough data for wave header");
		return ret;
	}

	GET_STR (buf, stmp, 4);
	if (strcmp (stmp, "RIFF")) {
		xmms_log_error ("No RIFF data");
		return ret;
	}

	GET_32 (buf, data_size);
	data_size += 8;

	GET_STR (buf, stmp, 4);
	if (strcmp (stmp, "WAVE")) {
		xmms_log_error ("No Wave data");
		return ret;
	}

	GET_STR (buf, stmp, 4);
	if (strcmp (stmp, "fmt ")) {
		xmms_log_error ("Format chunk missing");
		return ret;
	}

	GET_32 (buf, tmp32); /* format chunk length */
	XMMS_DBG ("format chunk length: %i", tmp32);

	GET_16 (buf, tmp16); /* format tag */
	ret = tmp16;

	switch (tmp16) {
		case WAVE_FORMAT_PCM:
			if (tmp32 != 16) {
				xmms_log_error ("Format chunk length not 16.");
				return WAVE_FORMAT_UNDEFINED;
			}

			GET_16 (buf, data->channels);
			XMMS_DBG ("channels %i", data->channels);
			if (data->channels < 1 || data->channels > 2) {
				xmms_log_error ("Unhandled number of channels: %i",
				                data->channels);
				return WAVE_FORMAT_UNDEFINED;
			}

			GET_32 (buf, data->samplerate);
			XMMS_DBG ("samplerate %i", data->samplerate);
			if (data->samplerate != 8000 && data->samplerate != 11025 &&
			    data->samplerate != 22050 && data->samplerate != 44100) {
				xmms_log_error ("Invalid samplerate: %i", data->samplerate);
				return WAVE_FORMAT_UNDEFINED;
			}

			GET_32 (buf, tmp32);
			GET_16 (buf, tmp16);

			GET_16 (buf, data->bits_per_sample);
			XMMS_DBG ("bits per sample %i", data->bits_per_sample);
			if (data->bits_per_sample != 8 && data->bits_per_sample != 16) {
				xmms_log_error ("Unhandled bits per sample: %i",
				                data->bits_per_sample);
				return WAVE_FORMAT_UNDEFINED;
			}

			break;
		case WAVE_FORMAT_MP3:
			SKIP (tmp32 - sizeof (tmp16));
			/* set up so that seeking works with "bytes" as seek unit */
			data->bits_per_sample = 8;
			data->channels = 1;
			break;
		default:
			xmms_log_error ("unhandled format tag: 0x%x", tmp16);
			return WAVE_FORMAT_UNDEFINED;
	}

	GET_STR (buf, stmp, 4);

	while (strcmp (stmp, "data")) {
		GET_32 (buf, tmp32);

		if (bytes_left < (tmp32 + 8)) {
			xmms_log_error ("Data chunk missing");
			return WAVE_FORMAT_UNDEFINED;
		}

		buf += tmp32;
		bytes_left -= tmp32;

		GET_STR (buf, stmp, 4);
	}

	GET_32 (buf, data->bytes_total);

	data->header_size = bytes_read - bytes_left;

	if (data->bytes_total + data->header_size != data_size) {
		xmms_log_info ("Data chunk size doesn't match RIFF chunk size");
		/* don't return FALSE here, we try to read it anyway */
	}

	return ret;
}
Beispiel #11
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);
}