Exemple #1
0
static int net_get_nopacket(struct priv_net *pn, void *arg, int *len)
{
	unsigned char buf[2048];
	int l = sizeof(buf);
	int c;

	while (1) {
		l = sizeof(buf);
		c = net_get(pn->pn_s, buf, &l);
		if (c < 0)
			return c;

		if (c != NET_PACKET && c > 0)
			break;

		if(c > 0)
			net_enque(pn, buf, l);
	}

	assert(l <= *len);
	memcpy(arg, buf, l);
	*len = l;

	return c;
}
Exemple #2
0
static void
dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
{
  struct rt_dev_config *P = (void *) p->cf;

  if (!EMPTY_LIST(P->iface_list) &&
      !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
    /* Empty list is automagically treated as "*" */
    return;

  if (ad->flags & IA_SECONDARY)
    return;

  if (ad->scope <= SCOPE_LINK)
    return;

  if (c & IF_CHANGE_DOWN)
    {
      net *n;

      DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
      n = net_find(p->table, ad->prefix, ad->pxlen);
      if (!n)
	{
	  DBG("dev_if_notify: device shutdown: prefix not found\n");
	  return;
	}

      /* Use iface ID as local source ID */
      struct rte_src *src = rt_get_source(p, ad->iface->index);
      rte_update2(p->main_ahook, n, NULL, src);
    }
  else if (c & IF_CHANGE_UP)
    {
      rta *a;
      net *n;
      rte *e;

      DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);

      /* Use iface ID as local source ID */
      struct rte_src *src = rt_get_source(p, ad->iface->index);

      rta a0 = {
	.src = src,
	.source = RTS_DEVICE,
	.scope = SCOPE_UNIVERSE,
	.cast = RTC_UNICAST,
	.dest = RTD_DEVICE,
	.iface = ad->iface
      };

      a = rta_lookup(&a0);
      n = net_get(p->table, ad->prefix, ad->pxlen);
      e = rte_get_temp(a);
      e->net = n;
      e->pflags = 0;
      rte_update2(p->main_ahook, n, e, src);
    }
}
static void handle_client(struct sstate *ss, struct client *c)
{
	unsigned char buf[2048];
	int len = sizeof(buf);
	int cmd;

	cmd = net_get(c->c_s, buf, &len);
	if (cmd == -1) {
		debug(ss, c, 2, "handle_client: net_get()\n");
		client_kill(c);
		return;
	}

	/* figure out command */
	switch (cmd) {
	case NET_SET_CHAN:
		handle_set_chan(ss, c, buf, len);
		break;

	case NET_SET_RATE:
		handle_set_rate(ss, c, buf, len);
		break;

	case NET_GET_MAC:
		handle_get_mac(ss, c);
		break;

	case NET_GET_CHAN:
		handle_get_chan(ss, c);
		break;

	case NET_GET_RATE:
		handle_get_rate(ss, c);
		break;

	case NET_GET_MONITOR:
		handle_get_monitor(ss, c);
		break;

	case NET_WRITE:
		handle_write(ss, c, buf, len);
		break;

	default:
		printf("Unknown request %d\n", cmd);
		client_kill(c);
		break;
	}
}
Exemple #4
0
static int net_read(struct wif *wi, unsigned char *h80211, int len,
		    struct rx_info *ri)
{
	struct priv_net *pn = wi_priv(wi);
	uint32_t buf[512]; // 512 * 4 = 2048
	unsigned char *bufc = (unsigned char*)buf;
	int cmd;
	int sz = sizeof(*ri);
	int l;
	int ret;

	/* try queue */
	l = queue_get(pn, buf, sizeof(buf));
	if (!l) {
		/* try reading form net */
		l = sizeof(buf);
		cmd = net_get(pn->pn_s, buf, &l);

		if (cmd == -1)
			return -1;
		if (cmd == NET_RC)
		{
			ret = ntohl((buf[0]));
			return ret;
		}
		assert(cmd == NET_PACKET);
	}

	/* XXX */
	if (ri) {
		// re-assemble 64-bit integer
		ri->ri_mactime = __be64_to_cpu(((uint64_t)buf[0] << 32 || buf[1] ));
		ri->ri_power = __be32_to_cpu(buf[2]);
		ri->ri_noise = __be32_to_cpu(buf[3]);
		ri->ri_channel = __be32_to_cpu(buf[4]);
		ri->ri_freq = __be32_to_cpu(buf[5]);
		ri->ri_rate = __be32_to_cpu(buf[6]);
		ri->ri_antenna = __be32_to_cpu(buf[7]);
	}
	l -= sz;
	assert(l > 0);
	if (l > len)
		l = len;
	memcpy(h80211, &bufc[sz], l);

	return l;
}
Exemple #5
0
static void
krt_parse_entry(byte *ent, struct krt_proto *p)
{
  u32 dest0, gw0, mask0;
  ip_addr dest, gw, mask;
  unsigned int flags;
  int masklen;
  net *net;
  byte *iface = ent;
  rte *e;

  if (sscanf(ent, "%*s\t%x\t%x\t%x\t%*d\t%*d\t%*d\t%x\t", &dest0, &gw0, &flags, &mask0) != 4)
    {
      log(L_ERR "krt read: unable to parse `%s'", ent);
      return;
    }
  while (*ent != '\t')
    ent++;
  *ent = 0;

  dest = ipa_from_u32(dest0);
  ipa_ntoh(dest);
  gw = ipa_from_u32(gw0);
  ipa_ntoh(gw);
  mask = ipa_from_u32(mask0);
  ipa_ntoh(mask);
  if ((masklen = ipa_mklen(mask)) < 0)
    {
      log(L_ERR "krt read: invalid netmask %08x", mask0);
      return;
    }
  DBG("Got %I/%d via %I flags %x\n", dest, masklen, gw, flags);

  if (!(flags & RTF_UP))
    {
      DBG("Down.\n");
      return;
    }
  if (flags & RTF_HOST)
    masklen = 32;
  if (flags & (RTF_DYNAMIC | RTF_MODIFIED)) /* Redirect route */
    {
      log(L_WARN "krt: Ignoring redirect to %I/%d via %I", dest, masklen, gw);
      return;
    }

  net = net_get(p->p.table, dest, masklen);

  rta a = {
    .proto = &p->p,
    .source = RTS_INHERIT,
    .scope = SCOPE_UNIVERSE,
    .cast = RTC_UNICAST
  };

  if (flags & RTF_GATEWAY)
    {
      neighbor *ng = neigh_find(&p->p, &gw, 0);
      if (ng && ng->scope)
	a.iface = ng->iface;
      else
	{
	  log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", gw, net->n.prefix, net->n.pxlen);
	  return;
	}
      a.dest = RTD_ROUTER;
      a.gw = gw;
    }
  else if (flags & RTF_REJECT)
    {
      a.dest = RTD_UNREACHABLE;
      a.gw = IPA_NONE;
    }
  else if (isalpha(iface[0]))
    {
      a.dest = RTD_DEVICE;
      a.gw = IPA_NONE;
      a.iface = krt_temp_iface(p, iface);
    }
  else
    {
      log(L_WARN "Kernel reporting unknown route type to %I/%d", net->n.prefix, net->n.pxlen);
      return;
    }

  e = rte_get_temp(&a);
  e->net = net;
  e->u.krt.src = KRT_SRC_UNKNOWN;
  krt_got_route(p, e);
}

void
krt_scan_fire(struct krt_proto *p)
{
  byte buf[32768];
  int l, seen_hdr;

  if (krt_scan_fd < 0)
    {
      krt_scan_fd = open("/proc/net/route", O_RDONLY);
      if (krt_scan_fd < 0)
	die("/proc/net/route: %m");
    }
  else if (lseek(krt_scan_fd, 0, SEEK_SET) < 0)
    {
      log(L_ERR "krt seek: %m");
      return;
    }
  seen_hdr = 0;
  while ((l = read(krt_scan_fd, buf, sizeof(buf))) > 0)
    {
      byte *z = buf;
      if (l & 127)
	{
	  log(L_ERR "krt read: misaligned entry: l=%d", l);
	  return;
	}
      while (l >= 128)
	{
	  if (seen_hdr++)
	    krt_parse_entry(z, p);
	  z += 128;
	  l -= 128;
	}
    }
  if (l < 0)
    {
      log(L_ERR "krt read: %m");
      return;
    }
  DBG("KRT scan done, seen %d lines\n", seen_hdr);
}