Beispiel #1
0
Datei: tf.c Projekt: NetSys/sts
static void
deps_diff (struct hs *hs, uint32_t port, const struct deps *deps,
           const struct tf *tf, const uint32_t *app, int napp)
{
  for (int i = 0; i < deps->n; i++) {
    const struct dep *dep = &deps->deps[i];
    if (app && !int_find (dep->rule, app, napp)) continue;
    if (dep->port > 0 && dep->port != port) continue;
    if (dep->port < 0 && !port_match (port, dep->port, tf)) continue;
    hs_diff (hs, DATA_ARR (dep->match));
  }
}
Beispiel #2
0
static void *
reach_thread (void *vdata)
{
  struct tdata *data = vdata;
  int sw = data->sw;
  struct list_res *res = &data->res;

  const uint32_t *out = g_out;
  int nout = g_nout;
  int ntfs = data_file->ntfs - 1;

  //int count = 0, loops = 0;
  while (true) {
    struct list_res queue = {0};
    pthread_mutex_lock (&wait_lock);
    //fprintf (stderr, "%d %d\n", sw, queues[sw].n);
    while (!queues[sw].head) {
      waiters |= 1 << sw;
      if (waiters + 1 == 1 << ntfs) {
        for (int i = 0; i < ntfs; i++) {
          if (i == sw) continue;
          pthread_cond_broadcast (&conds[i]);
        }
        pthread_mutex_unlock (&wait_lock);
        return NULL;
      }

      pthread_cond_wait (&conds[sw], &wait_lock);

      if (waiters + 1 == 1 << ntfs) {
        pthread_mutex_unlock (&wait_lock);
        return NULL;
      }
      assert (waiters | (1 << sw));
    }
    queue = queues[sw];
    memset (&queues[sw], 0, sizeof queues[sw]);
    pthread_mutex_unlock (&wait_lock);

    struct res *cur;
    while ((cur = queue.head)) {
      list_pop (&queue);

      bool new_res = false;
      struct list_res nextqs[ntfs];
      memset (nextqs, 0, sizeof nextqs);

      struct list_res ntf_res = ntf_apply (cur, sw);
      struct res *ntf_cur = ntf_res.head;
      while (ntf_cur) {
        struct res *ntf_next = ntf_cur->next;
        if (!out || int_find (ntf_cur->port, out, nout)) {
          list_append (res, ntf_cur);
          ref_add (ntf_cur, cur);
          if (out) {
            ntf_cur = ntf_next;
            continue;
          }
        }

        struct list_res ttf_res = tf_apply (tf_get (0), ntf_cur, true);
        struct res *ttf_cur = ttf_res.head;
        while (ttf_cur) {
          struct res *ttf_next = ttf_cur->next;
          if (is_loop (ttf_cur->port, cur)) {
            res_free (ttf_cur);
            ttf_cur = ttf_next;
            //loops++;
            continue;
          }

          ref_add (ttf_cur, cur);
          if (out && int_find (ttf_cur->port, out, nout)) list_append (res, ttf_cur);
          else {
            int new_sw = ntf_get_sw (ttf_cur->port);
            list_append (&nextqs[new_sw], ttf_cur);
            //count++;
            new_res = true;
          }
          ttf_cur = ttf_next;
        }
        if (out) res_free (ntf_cur);
        ntf_cur = ntf_next;
      }
      res_free_mt (cur, true);

      if (!new_res) continue;
      pthread_mutex_lock (&wait_lock);
      unsigned int wake = 0;
      for (int i = 0; i < ntfs; i++) {
        if (!nextqs[i].head) continue;
        list_concat (&queues[i], &nextqs[i]);
        pthread_cond_broadcast (&conds[i]);
        wake |= 1 << i;
      }
      waiters &= ~wake;
      pthread_mutex_unlock (&wait_lock);
    }
  }
}
Beispiel #3
0
/* Initiliaze interfaces */
void update_interfaces (struct intnode *intn)
{
	struct in6_addr addr;

	FILE *file;
	unsigned int prefixlen, scope, flags, ifindex;
	char devname[IFNAMSIZ];

	/* Only update every 5 seconds to avoid rerunning it every packet */
	if (g_conf->maxinterfaces)
		return;

	dbg ("Updating Interfaces\n");

	/* Get link local addresses from /proc/net/if_inet6 */
	file = fopen ("/proc/net/if_inet6", "r");

	/* We can live without it though */
	if (!file) {
		err ("Cannot open /proc/net/if_inet6\n");
		return;
	}

	char buf[255];
	/* Format "fe80000000000000029027fffe24bbab 02 0a 20 80     eth0" */
	while (fgets (buf, sizeof (buf), file)) {
		if (21 != sscanf (buf, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx %x %x %x %x %8s", &addr.s6_addr[0], &addr.s6_addr[1], &addr.s6_addr[2], &addr.s6_addr[3], &addr.s6_addr[4], &addr.s6_addr[5], &addr.s6_addr[6], &addr.s6_addr[7], &addr.s6_addr[8], &addr.s6_addr[9], &addr.s6_addr[10], &addr.s6_addr[11], &addr.s6_addr[12], &addr.s6_addr[13], &addr.s6_addr[14], &addr.s6_addr[15], &ifindex, &prefixlen, &scope, &flags, devname)) {

			warn ("/proc/net/if_inet6 in wrong format!\n");
			continue;
		}
		if (!IN6_IS_ADDR_LINKLOCAL (&addr) && (IN6_IS_ADDR_UNSPECIFIED (&addr) || IN6_IS_ADDR_LOOPBACK (&addr) || IN6_IS_ADDR_MULTICAST (&addr))) {
			continue;
		}

		if((intn=int_find(ifindex))==NULL) {
			g_conf->ints=(struct intnode*)realloc(g_conf->ints, sizeof(struct intnode)*(++g_conf->maxinterfaces));
			if (!g_conf->ints) {
				err ("Cannot get memory for interface structures.\n");
			}
			intn=g_conf->ints+g_conf->maxinterfaces-1;
			memset(intn, 0, sizeof(struct intnode));
		}
#ifdef WIN32
		// Ugly WINXP workaround
		if(scope==0x20 && flags==0x80) {
			intn->mtu=1480;
		} else {
			intn->mtu=0;
		}
#else
		intn->ifindex = ifindex;
		strcpy(intn->name, devname);

		struct ifreq ifreq;
		int sock;
		sock = socket (AF_INET6, SOCK_DGRAM, 0);
		if (sock < 0) {
			err ("Cannot get socket for setup\n");
		}

		memcpy (&ifreq.ifr_name, &intn->name, sizeof (ifreq.ifr_name));
		/* Get the MTU size of this interface */
		/* We will use that for fragmentation */
		if (ioctl (sock, SIOCGIFMTU, &ifreq) != 0) {
			warn ("Cannot get MTU size for %s index %d: %s\n", intn->name, intn->ifindex, strerror (errno));
		}
		intn->mtu = ifreq.ifr_mtu;

		/* Get hardware address + type */
		if (ioctl (sock, SIOCGIFHWADDR, &ifreq) != 0) {
			warn ("Cannot get hardware address for %s, interface index %d : %s\n", intn->name, intn->ifindex, strerror (errno));
		}
		intn->hwaddr = ifreq.ifr_hwaddr;
		close (sock);
#endif
		/* Link Local IPv6 address ? */
		if (IN6_IS_ADDR_LINKLOCAL (&addr)) {
			/* Update the linklocal address */
			intn->linklocal = addr;
		} else {
			intn->global = addr;
		}

		dbg ("Available interface %s index %u hardware %s/%u MTU %d\n", intn->name, intn->ifindex, (intn->hwaddr.sa_family == ARPHRD_ETHER ? "Ethernet" : (intn->hwaddr.sa_family == ARPHRD_SIT ? "sit" : "Unknown")), intn->hwaddr.sa_family, intn->mtu);
	}

	fclose (file);
}
Beispiel #4
0
Datei: tf.c Projekt: NetSys/sts
static bool
port_match (uint32_t port, int32_t ofs, const struct tf *tf)
{
  const struct ports *p = PORTS (tf, ofs);
  return int_find (port, p->arr, p->n);
}
Beispiel #5
0
void update_interfaces (struct intnode *intn)
{
	struct ifaddrs *myaddrs, *ifa;
	struct sockaddr_in *s4;
	struct sockaddr_in6 *s6;
	int if_index;
	/*
	 * buf must be big enough for an IPv6 address (e.g.
	 * 3ffe:2fa0:1010:ca22:020a:95ff:fe8a:1cf8)
	 */
	char buf[64];

	if (getifaddrs(&myaddrs)) {
		err ("getifaddrs");
	}
	
	for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) {
		if (ifa->ifa_addr == NULL)
			continue;
		if ((ifa->ifa_flags & IFF_UP) == 0)
			continue;

		if_index=if_nametoindex(ifa->ifa_name);
		dbg("%s(%d): ", ifa->ifa_name,if_index);
		
		if(!if_index) {
			warn("cannot get interface index for %s\n",ifa->ifa_name);
			continue;
		}

		if((intn=int_find(if_index))==NULL) {
			g_conf->ints=(struct intnode*)realloc(g_conf->ints, sizeof(struct intnode)*(++g_conf->maxinterfaces));
			if (!g_conf->ints) {
				err ("Cannot get memory for interface structures.\n");
			}
			intn=g_conf->ints+g_conf->maxinterfaces-1;
			memset(intn, 0, sizeof(struct intnode));
		}

		intn->ifindex=if_index;
		strcpy(intn->name,ifa->ifa_name);

		if(ifa->ifa_addr->sa_family == AF_LINK && ((struct if_data *)ifa->ifa_data)->ifi_type != IFT_LOOP && ifa->ifa_data) {
			dbg("MTU: %d\n", ((struct if_data *)ifa->ifa_data)->ifi_mtu);
			intn->mtu=((struct if_data *)ifa->ifa_data)->ifi_mtu;
			memcpy(&intn->hwaddr, ifa->ifa_addr, sizeof(struct sockaddr_in));
		}

		if (ifa->ifa_addr->sa_family == AF_INET) {
			s4 = (struct sockaddr_in *) (ifa->ifa_addr);
			if (inet_ntop(ifa->ifa_addr->sa_family, (void *) &(s4->sin_addr), buf, sizeof(buf)) == NULL) {
				warn("%s: inet_ntop failed!\n", ifa->ifa_name);
			} else {
				dbg("%s\n", buf);
			}
		} else if (ifa->ifa_addr->sa_family == AF_INET6) {
			s6 = (struct sockaddr_in6 *) (ifa->ifa_addr);
			/* Link Local IPv6 address ? */
			if (IN6_IS_ADDR_LINKLOCAL (&s6->sin6_addr)) {
				/* Update the linklocal address */
				intn->linklocal = s6->sin6_addr;
			} else {
				intn->global = s6->sin6_addr;
			}
			if (inet_ntop(ifa->ifa_addr->sa_family, (void *) &(s6->sin6_addr), buf, sizeof(buf)) == NULL) {
				warn("%s: inet_ntop failed!\n", ifa->ifa_name);
			} else {
				dbg("%s\n", buf);
			}
		}
	}

	freeifaddrs(myaddrs);
}