int main() {
  const char * old_domain_name = get_domain_name();
  const char * old_host_name = get_host_name();

  step("parent: old domainname: %s", old_domain_name);
  step("parent: old hostname: %s", old_host_name);

  step("parent: fork");
  if (fork()) {
    step("parent: wait for child to exit");
    int status = 0;
    do wait(&status); while (!WIFEXITED(status));

    assertStrEquals("parent: domain name", old_domain_name, get_domain_name());
    assertStrEquals("parent: host name", old_host_name, get_host_name());
  } else {
    step("child: create container with separate uts namespace");
    struct slc_create_container_parameters params;
    initialize_default_fs_root(&params.fs_root);
    slc_create_container(&params, 0);

    const char * new_domain_name = "new_domain_name";
    const char * new_host_name = "new_host_name";
    
    step("child: set domain name to '%s'", new_domain_name);
    setdomainname(new_domain_name, strlen(new_domain_name));
    assertStrEquals("child: domain name", new_domain_name, get_domain_name());
    
    step("child: set host name to '%s'", new_host_name);
    sethostname(new_host_name, strlen(new_host_name));
    assertStrEquals("child: host name", new_host_name, get_host_name());
  }

  return 0;
}
Esempio n. 2
0
static gchar *generate_password(void)
{
	SMD5 *md5;
	time_t t;
	gchar date_str[15];
	const gchar *hostname;
	guint32 salt;
	gchar *b64;

	time(&t);
	strftime(date_str, sizeof(date_str), "%Y%m%d%H%M%S", localtime(&t));

	hostname = get_domain_name();

	salt = g_random_int();

	md5 = s_gnet_md5_new_incremental();
	s_gnet_md5_update(md5, (guchar *)date_str, strlen(date_str));
	s_gnet_md5_update(md5, (const guchar *)hostname, strlen(hostname));
	s_gnet_md5_update(md5, (guchar *)&salt, sizeof(salt));
	s_gnet_md5_final(md5);

	b64 = g_malloc(S_GNET_MD5_HASH_LENGTH * 2);
	base64_encode(b64, (guchar *)s_gnet_md5_get_digest(md5), S_GNET_MD5_HASH_LENGTH);
	debug_print("generate_password: b64(%s %s %u) = %s\n", date_str, hostname, salt, b64);
	b64[12] = '\0';
	debug_print("generate_password: password = %s\n", b64);

	s_gnet_md5_delete(md5);

	return b64;
}
Esempio n. 3
0
int process_answer(char *dns_response, int offset) {
   unsigned char data[200];

   int numBytes = 2; // skip initial 2 bytes

   int type = get_short(dns_response, offset + numBytes);
   numBytes += 2;    // count the type
   numBytes += 2;    // skip the address class (should be 0x0001, IPv4)
   numBytes += 4;    // skip the TTL (recommended cache time)

   int data_length1 = get_short(dns_response, offset + numBytes);
   numBytes += 2;

   if (type == 1) {
      // this is a normal query response (i.e. name -> address)
      get_ip_address(dns_response, offset + numBytes, data);
      numBytes += 4;
      printf("Response:  %u.%u.%u.%u\n", data[0],data[1],data[2],data[3]);
   } else if (type == 5) {
      // this is a CNAME query response (i.e. an alias)
      int data_length = get_domain_name(dns_response, offset + numBytes, data);
      numBytes += data_length;
      printf("Alias:  %s\n", data);
   }

   return numBytes;
}
Esempio n. 4
0
static gint smtp_helo(SMTPSession *session)
{
	gchar buf[MSGBUFSIZE];

	session->state = SMTP_HELO;

	g_snprintf(buf, sizeof(buf), "HELO %s",
		   session->hostname ? session->hostname : get_domain_name());
	session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
	log_print("SMTP> %s\n", buf);

	return SM_OK;
}
Esempio n. 5
0
static gint smtp_ehlo(SMTPSession *session)
{
	gchar buf[MESSAGEBUFSIZE];

	session->state = SMTP_EHLO;

	session->avail_auth_type = 0;

	g_snprintf(buf, sizeof(buf), "EHLO %s",
		   session->hostname ? session->hostname : get_domain_name());
	if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf) < 0)
		return SM_ERROR;
	log_print(LOG_PROTOCOL, "ESMTP> %s\n", buf);

	return SM_OK;
}
Esempio n. 6
0
static int open_socket(unsigned int domain, unsigned int type, unsigned int protocol)
{
	int fd;
	struct sockaddr *sa = NULL;
	socklen_t salen;
	struct sockopt so = { 0, 0, 0, 0 };

	fd = socket(domain, type, protocol);
	if (fd == -1)
		return fd;

	shm->sockets[nr_sockets].fd = fd;
	shm->sockets[nr_sockets].triplet.family = domain;
	shm->sockets[nr_sockets].triplet.type = type;
	shm->sockets[nr_sockets].triplet.protocol = protocol;

	output(2, "fd[%i] = domain:%i (%s) type:0x%x protocol:%i\n",
		fd, domain, get_domain_name(domain), type, protocol);

	/* Set some random socket options. */
	sso_socket(&shm->sockets[nr_sockets].triplet, &so, fd);

	nr_sockets++;

	/* Sometimes, listen on created sockets. */
	if (RAND_BOOL()) {
		int ret;

		/* fake a sockaddr. */
		generate_sockaddr((struct sockaddr **) &sa, (socklen_t *) &salen, domain);

		ret = bind(fd, sa, salen);
		if (ret != -1) {
			(void) listen(fd, RAND_RANGE(1, 128));
		}
	}

	if (sa != NULL)
		free(sa);

	return fd;
}
Esempio n. 7
0
static void lock_cachefile(int cachefile, int type)
{
	struct flock fl = {
		.l_len = 0,
		.l_start = 0,
		.l_whence = SEEK_SET,
	};

	fl.l_pid = getpid();
	fl.l_type = type;

	if (verbose)
		output(2, "waiting on lock for cachefile\n");

	if (fcntl(cachefile, F_SETLKW, &fl) == -1) {
		perror("fcntl F_SETLKW");
		exit_main_fail();
	}

	if (verbose)
		output(2, "took lock for cachefile\n");
}

static void unlock_cachefile(int cachefile)
{
	struct flock fl = {
		.l_len = 0,
		.l_start = 0,
		.l_whence = SEEK_SET,
	};

	fl.l_pid = getpid();
	fl.l_type = F_UNLCK;

	if (fcntl(cachefile, F_SETLK, &fl) == -1) {
		perror("fcntl F_UNLCK F_SETLK ");
		exit_main_fail();
	}

	if (verbose)
		output(2, "dropped lock for cachefile\n");
}

static unsigned int valid_proto(unsigned int family)
{
	const char *famstr;

	famstr = get_domain_name(family);

	/* Not used for creating sockets. */
	if (strncmp(famstr, "PF_UNSPEC", 9) == 0)
		return FALSE;
	if (strncmp(famstr, "PF_BRIDGE", 9) == 0)
		return FALSE;
	if (strncmp(famstr, "PF_SECURITY", 11) == 0)
		return FALSE;

	/* Not actually implemented (or now removed). */
	if (strncmp(famstr, "PF_NETBEUI", 10) == 0)
		return FALSE;
	if (strncmp(famstr, "PF_ASH", 6) == 0)
		return FALSE;
	if (strncmp(famstr, "PF_ECONET", 9) == 0)
		return FALSE;
	if (strncmp(famstr, "PF_SNA", 6) == 0)
		return FALSE;
	if (strncmp(famstr, "PF_WANPIPE", 10) == 0)
		return FALSE;

	/* Needs root. */
	if (orig_uid != 0) {
		if (strncmp(famstr, "PF_KEY", 6) == 0)
			return FALSE;
		if (strncmp(famstr, "PF_PACKET", 9) == 0)
			return FALSE;
		if (strncmp(famstr, "PF_LLC", 6) == 0)
			return FALSE;
	}

	return TRUE;
}

static int generate_sockets(void)
{
	int fd, n, ret = FALSE;
	int cachefile;
	unsigned int nr_to_create = NR_SOCKET_FDS;
	unsigned int buffer[3];

	cachefile = creat(cachefilename, S_IWUSR|S_IRUSR);
	if (cachefile == -1)
		outputerr("Couldn't open cachefile for writing! (%s)\n", strerror(errno));
	else
		lock_cachefile(cachefile, F_WRLCK);

	/*
	 * Don't loop forever if all domains all are disabled.
	 */
	if (!do_specific_domain) {
		for (n = 0; n < (int)ARRAY_SIZE(no_domains); n++) {
			if (!no_domains[n])
				break;
		}

		if (n >= (int)ARRAY_SIZE(no_domains))
			nr_to_create = 0;
	}

	while (nr_to_create > 0) {

		struct socket_triplet st;

		for (st.family = 0; st.family < TRINITY_PF_MAX; st.family++) {

			/* check for ctrl-c again. */
			if (shm->exit_reason != STILL_RUNNING)
				goto out_unlock;

			if (do_specific_domain == TRUE) {
				st.family = specific_domain;
				//FIXME: If we've passed -P and we're spinning here without making progress
				// then we should abort after a few hundred loops.
			}

			if (get_domain_name(st.family) == NULL)
				continue;

			if (valid_proto(st.family) == FALSE) {
				if (do_specific_domain == TRUE) {
					outputerr("Can't do protocol %s\n", get_domain_name(st.family));
					goto out_unlock;
				} else {
					continue;
				}
			}

			BUG_ON(st.family >= ARRAY_SIZE(no_domains));
			if (no_domains[st.family])
				continue;

			if (sanitise_socket_triplet(&st) == -1)
				rand_proto_type(&st);

			fd = open_socket(st.family, st.type, st.protocol);
			if (fd > -1) {
				nr_to_create--;

				if (cachefile != -1) {
					buffer[0] = st.family;
					buffer[1] = st.type;
					buffer[2] = st.protocol;
					n = write(cachefile, &buffer, sizeof(int) * 3);
					if (n == -1) {
						outputerr("something went wrong writing the cachefile!\n");
						goto out_unlock;
					}
				}

				if (nr_to_create == 0)
					goto done;
			} else {
				//outputerr("Couldn't open family:%d (%s)\n", st.family, get_domain_name(st.family));
			}
		}
	}

done:
	ret = TRUE;

	output(1, "created %d sockets\n", nr_sockets);

out_unlock:
	if (cachefile != -1) {
		unlock_cachefile(cachefile);
		close(cachefile);
	}

	return ret;
}


void close_sockets(void)
{
	unsigned int i;
	int fd;
	struct linger ling = { .l_onoff = FALSE, .l_linger = 0 };

	for (i = 0; i < nr_sockets; i++) {

		//FIXME: This is a workaround for a weird bug where we hang forevre
		// waiting for bluetooth sockets when we setsockopt.
		// Hopefully at some point we can remove this when someone figures out what's going on.
		if (shm->sockets[i].triplet.family == PF_BLUETOOTH)
			continue;

		/* Grab an fd, and nuke it before someone else uses it. */
		fd = shm->sockets[i].fd;
		shm->sockets[i].fd = 0;

		/* disable linger */
		(void) setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger));

		(void) shutdown(fd, SHUT_RDWR);

		if (close(fd) != 0)
			output(1, "failed to close socket [%d:%d:%d].(%s)\n",
				shm->sockets[i].triplet.family,
				shm->sockets[i].triplet.type,
				shm->sockets[i].triplet.protocol,
				strerror(errno));
	}

	nr_sockets = 0;
}

static int open_sockets(void)
{
	int cachefile;
	unsigned int domain, type, protocol;
	unsigned int buffer[3];
	int bytesread = -1;
	int fd;
	int ret;

	/* If we're doing victim files we probably don't care about sockets. */
	//FIXME: Is this really true ? We might want to sendfile for eg
	if (victim_path != NULL)
		return TRUE;

	cachefile = open(cachefilename, O_RDONLY);
	if (cachefile < 0) {
		output(1, "Couldn't find socket cachefile. Regenerating.\n");
		ret = generate_sockets();
		return ret;
	}

	lock_cachefile(cachefile, F_RDLCK);

	while (bytesread != 0) {
		bytesread = read(cachefile, buffer, sizeof(int) * 3);
		if (bytesread == 0)
			break;

		domain = buffer[0];
		type = buffer[1];
		protocol = buffer[2];

		if ((do_specific_domain == TRUE && domain != specific_domain) ||
		    (domain < ARRAY_SIZE(no_domains) && no_domains[domain] == TRUE)) {
			output(1, "ignoring socket cachefile due to specific "
			       "protocol request (or protocol disabled), "
			       "and stale data in cachefile.\n");
regenerate:
				unlock_cachefile(cachefile);	/* drop the reader lock. */
				close(cachefile);
				unlink(cachefilename);

				close_sockets();
				ret = generate_sockets();
				return ret;
		}

		fd = open_socket(domain, type, protocol);
		if (fd < 0) {
			output(1, "Cachefile is stale. Need to regenerate.\n");
			goto regenerate;
		}

		/* check for ctrl-c */
		if (shm->exit_reason != STILL_RUNNING) {
			close(cachefile);
			return FALSE;
		}
	}

	if (nr_sockets < NR_SOCKET_FDS) {
		output(1, "Insufficient sockets in cachefile (%d). Regenerating.\n", nr_sockets);
		goto regenerate;
	}

	output(1, "%d sockets created based on info from socket cachefile.\n", nr_sockets);

	unlock_cachefile(cachefile);
	close(cachefile);

	return TRUE;
}
void HttpServer(){
	 _u8   SecType = 0;
	    _i32   retVal = -1;
	    _i32   mode = ROLE_STA;
	   /*
	     * Following function configures the device to default state by cleaning
	     * the persistent settings stored in NVMEM (viz. connection profiles &
	     * policies, power policy etc)
	     *
	     * Applications may choose to skip this step if the developer is sure
	     * that the device is in its default state at start of application
	     *
	     * Note that all profiles and persistent settings that were done on the
	     * device will be lost
	     */
	    retVal = configureSimpleLinkToDefaultState();
	    if(retVal < 0)
	    {
	        if (DEVICE_NOT_IN_STATION_MODE == retVal)
	            CLI_Write(" Failed to configure the device in its default state \n\r");

	        LOOP_FOREVER();
	    }

	    CLI_Write(" Device is configured in default state \n\r");

	    /*
	     * Assumption is that the device is configured in station mode already
	     * and it is in its default state
	     */
	    mode = sl_Start(0, 0, 0);
	    if(mode < 0)
	    {
	        LOOP_FOREVER();
	    }
	    else
	    {
	        if (ROLE_AP == mode)
	        {
	            /* If the device is in AP mode, we need to wait for this
	             * event before doing anything */
	            while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
	        }
	        else
	        {
	            /* Configure CC3100 to start in AP mode */
	            retVal = sl_WlanSetMode(ROLE_AP);
	            if(retVal < 0)
	                LOOP_FOREVER();
	        }
	    }

	    /* Configure AP mode without security */
	    retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID,
	               pal_Strlen(SSID_AP_MODE), (_u8 *)SSID_AP_MODE);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    SecType = SEC_TYPE_AP_MODE;
	    /* Configure the Security parameter in the AP mode */
	    retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1,
	            (_u8 *)&SecType);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, pal_Strlen(PASSWORD_AP_MODE),
	            (_u8 *)PASSWORD_AP_MODE);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    /* Restart the CC3100 */
	    retVal = sl_Stop(SL_STOP_TIMEOUT);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    g_Status = 0;

	    mode = sl_Start(0, 0, 0);
	    if (ROLE_AP == mode)
	    {
	        /* If the device is in AP mode, we need to wait for this event before doing anything */
	        while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
	    }
	    else
	    {
	        CLI_Write(" Device couldn't come in AP mode \n\r");
	        LOOP_FOREVER();
	    }

	    CLI_Write(" \r\n Device is configured in AP mode \n\r");

	    CLI_Write(" Waiting for client to connect\n\r");
	    /* wait for client to connect */
	    while((!IS_IP_LEASED(g_Status)) || (!IS_STA_CONNECTED(g_Status))) { _SlNonOsMainLoopTask(); }

	    CLI_Write(" Client connected\n\r");

	    /* Enable the HTTP Authentication */
	    retVal = set_authentication_check(TRUE);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    /* Get authentication parameters */
	    retVal = get_auth_name(g_auth_name);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    retVal = get_auth_password(g_auth_password);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    retVal = get_auth_realm(g_auth_realm);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    CLI_Write((_u8 *)"\r\n Authentication parameters: ");
	    CLI_Write((_u8 *)"\r\n Name = ");
	    CLI_Write(g_auth_name);
	    CLI_Write((_u8 *)"\r\n Password = "******"\r\n Realm = ");
	    CLI_Write(g_auth_realm);

	    /* Get the domain name */
	    retVal = get_domain_name(g_domain_name);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    CLI_Write((_u8 *)"\r\n\r\n Domain name = ");
	    CLI_Write(g_domain_name);

	    /* Get URN */
	    retVal = get_device_urn(g_device_urn);
	    if(retVal < 0)
	        LOOP_FOREVER();

	    CLI_Write((_u8 *)"\r\n Device URN = ");
	    CLI_Write(g_device_urn);
	    CLI_Write((_u8 *)"\r\n");

	    /* Process the async events from the NWP */
	    while(1)
	    {
	        Semaphore_pend(Semaphore_CC3100_Req, BIOS_WAIT_FOREVER);
	        _SlNonOsMainLoopTask();
	    }

}
Esempio n. 9
0
static void socket_destructor(struct object *obj)
{
	struct socketinfo *si = &obj->sockinfo;
	struct linger ling = { .l_onoff = FALSE, .l_linger = 0 };
	int fd;

	//FIXME: This is a workaround for a weird bug where we hang forevre
	// waiting for bluetooth sockets when we setsockopt.
	// Hopefully at some point we can remove this when someone figures out what's going on.
	if (si->triplet.family == PF_BLUETOOTH)
		return;

	/* Grab an fd, and nuke it before someone else uses it. */
	fd = si->fd;
	si->fd = 0;

	/* disable linger */
	(void) setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger));

	(void) shutdown(fd, SHUT_RDWR);

	if (close(fd) != 0)
		output(1, "failed to close socket [%d:%d:%d].(%s)\n",
			si->triplet.family,
			si->triplet.type,
			si->triplet.protocol,
			strerror(errno));
}

static void socket_dump(struct object *obj, bool global)
{
	struct socketinfo *si = &obj->sockinfo;
	struct msg_objcreatedsocket objmsg;

	output(2, "socket fd:%d domain:%u (%s) type:0x%u protocol:%u\n",
		si->fd, si->triplet.family, get_domain_name(si->triplet.family),
		si->triplet.type, si->triplet.protocol);

	init_msgobjhdr(&objmsg.hdr, OBJ_CREATED_SOCKET, global, obj);
	objmsg.si.fd = si->fd;
	objmsg.si.triplet.family = si->triplet.family;
	objmsg.si.triplet.type = si->triplet.type;
	objmsg.si.triplet.protocol = si->triplet.protocol;
	sendudp((char *) &objmsg, sizeof(objmsg));
}

static int open_sockets(void)
{
	struct objhead *head;
	int bytesread = -1;
	int ret;

	head = get_objhead(OBJ_GLOBAL, OBJ_FD_SOCKET);
	head->destroy = &socket_destructor;
	head->dump = &socket_dump;

	cachefile = open(cachefilename, O_RDONLY);
	if (cachefile < 0) {
		output(1, "Couldn't find socket cachefile. Regenerating.\n");
		ret = generate_sockets();
		output(1, "created %d sockets\n", nr_sockets);
		return ret;
	}

	lock_cachefile(F_RDLCK);

	while (bytesread != 0) {
		unsigned int domain, type, protocol;
		unsigned int buffer[3];
		int fd;

		bytesread = read(cachefile, buffer, sizeof(int) * 3);
		if (bytesread == 0) {
			if (nr_sockets == 0)
				goto regenerate;
			break;
		}

		domain = buffer[0];
		type = buffer[1];
		protocol = buffer[2];

		if (domain >= TRINITY_PF_MAX) {
			output(1, "cachefile contained invalid domain %u\n", domain);
			goto regenerate;
		}

		if ((do_specific_domain == TRUE && domain != specific_domain) ||
		    (no_domains[domain] == TRUE)) {
			output(1, "ignoring socket cachefile due to specific "
			       "protocol request (or protocol disabled), "
			       "and stale data in cachefile.\n");
regenerate:
				unlock_cachefile();	/* drop the reader lock. */
				close(cachefile);
				unlink(cachefilename);

				ret = generate_sockets();
				return ret;
		}

		fd = open_socket(domain, type, protocol);
		if (fd < 0) {
			output(1, "Cachefile is stale. Need to regenerate.\n");
			goto regenerate;
		}

		/* check for ctrl-c */
		if (shm->exit_reason != STILL_RUNNING) {
			close(cachefile);
			return FALSE;
		}
	}

	output(1, "%d sockets created based on info from socket cachefile.\n", nr_sockets);

	unlock_cachefile();
	close(cachefile);

	return TRUE;
}

struct socketinfo * get_rand_socketinfo(void)
{
	struct object *obj;

	/* When using victim files, sockets can be 0. */
	if (objects_empty(OBJ_FD_SOCKET) == TRUE)
		return NULL;

	obj = get_random_object(OBJ_FD_SOCKET, OBJ_GLOBAL);
	return &obj->sockinfo;
}

static int get_rand_socket_fd(void)
{
	struct socketinfo *sockinfo;

	sockinfo = get_rand_socketinfo();
	if (sockinfo == NULL)
		return -1;

	return sockinfo->fd;
}

int fd_from_socketinfo(struct socketinfo *si)
{
	if (si != NULL) {
		if (!(ONE_IN(1000)))
			return si->fd;
	}
	return get_random_fd();
}

static const struct fd_provider socket_fd_provider = {
	.name = "sockets",
	.enabled = TRUE,
	.open = &open_sockets,
	.get = &get_rand_socket_fd,
};

REG_FD_PROV(socket_fd_provider);
Esempio n. 10
0
static void lock_cachefile(int type)
{
	struct flock fl = {
		.l_len = 0,
		.l_start = 0,
		.l_whence = SEEK_SET,
	};

	fl.l_pid = getpid();
	fl.l_type = type;

	if (verbose)
		output(2, "waiting on lock for cachefile\n");

	if (fcntl(cachefile, F_SETLKW, &fl) == -1) {
		perror("fcntl F_SETLKW");
		return;
	}

	if (verbose)
		output(2, "took lock for cachefile\n");
}

static void unlock_cachefile(void)
{
	struct flock fl = {
		.l_len = 0,
		.l_start = 0,
		.l_whence = SEEK_SET,
	};

	fl.l_pid = getpid();
	fl.l_type = F_UNLCK;

	if (fcntl(cachefile, F_SETLK, &fl) == -1) {
		perror("fcntl F_UNLCK F_SETLK ");
		return;
	}

	if (verbose)
		output(2, "dropped lock for cachefile\n");
}

static unsigned int valid_proto(unsigned int family)
{
	const char *famstr;

	famstr = get_domain_name(family);

	/* Not used for creating sockets. */
	if (strncmp(famstr, "UNSPEC", 9) == 0)
		return FALSE;
	if (strncmp(famstr, "BRIDGE", 9) == 0)
		return FALSE;
	if (strncmp(famstr, "SECURITY", 11) == 0)
		return FALSE;

	/* Not actually implemented (or now removed). */
	if (strncmp(famstr, "NETBEUI", 10) == 0)
		return FALSE;
	if (strncmp(famstr, "ASH", 6) == 0)
		return FALSE;
	if (strncmp(famstr, "ECONET", 9) == 0)
		return FALSE;
	if (strncmp(famstr, "SNA", 6) == 0)
		return FALSE;
	if (strncmp(famstr, "WANPIPE", 10) == 0)
		return FALSE;

	/* Needs root. */
	if (orig_uid != 0) {
		if (strncmp(famstr, "KEY", 6) == 0)
			return FALSE;
		if (strncmp(famstr, "PACKET", 9) == 0)
			return FALSE;
		if (strncmp(famstr, "LLC", 6) == 0)
			return FALSE;
	}

	return TRUE;
}

static bool write_socket_to_cache(struct socket_triplet *st)
{
	unsigned int buffer[3];
	int n;

	if (cachefile == -1)
		return FALSE;

	buffer[0] = st->family;
	buffer[1] = st->type;
	buffer[2] = st->protocol;
	n = write(cachefile, &buffer, sizeof(int) * 3);
	if (n == -1) {
		outputerr("something went wrong writing the cachefile! : %s\n", strerror(errno));
		return FALSE;
	}
	return TRUE;
}

static bool generate_socket(unsigned int family, unsigned int protocol, unsigned int type)
{
	struct socket_triplet st;
	int fd;

	st.family = family;
	st.type = type;
	st.protocol = protocol;

	fd = open_socket(st.family, st.type, st.protocol);
	if (fd > -1) {
		write_socket_to_cache(&st);
		return TRUE;
	}
	output(2, "Couldn't open socket %d:%d:%d. %s\n", family, type, protocol, strerror(errno));
	return FALSE;
}

static bool generate_specific_socket(int family)
{
	struct socket_triplet st;
	int fd;

	st.family = family;

	BUG_ON(st.family >= ARRAY_SIZE(no_domains));
	if (no_domains[st.family])
		return FALSE;

	if (get_domain_name(st.family) == NULL)
		return FALSE;

	if (valid_proto(st.family) == FALSE) {
		outputerr("Can't do protocol %s\n", get_domain_name(st.family));
		return FALSE;
	}

	st.protocol = rnd() % 256;

	if (sanitise_socket_triplet(&st) == -1)
		rand_proto_type(&st);

	fd = open_socket(st.family, st.type, st.protocol);
	if (fd == -1) {
		output(0, "Couldn't open socket (%d:%d:%d). %s\n",
				st.family, st.type, st.protocol,
				strerror(errno));
		return FALSE;
	}

	return write_socket_to_cache(&st);
}

#define NR_SOCKET_FDS 50

static bool generate_sockets(void)
{
	int i, r, ret = FALSE;
	bool domains_disabled = FALSE;

	cachefile = creat(cachefilename, S_IWUSR|S_IRUSR);
	if (cachefile == -1) {
		outputerr("Couldn't open cachefile for writing! (%s)\n", strerror(errno));
		return FALSE;
	}
	lock_cachefile(F_WRLCK);

	if (do_specific_domain == TRUE) {
		while (nr_sockets < NR_SOCKET_FDS) {
			ret = generate_specific_socket(specific_domain);

			if (ret == FALSE)
				return FALSE;
		}
		goto out_unlock;
	}

	/*
	 * check if all domains are disabled.
	 */
	for (i = 0; i < (int)ARRAY_SIZE(no_domains); i++) {
		if (no_domains[i] == FALSE) {
			domains_disabled = FALSE;
			break;
		} else {
			domains_disabled = TRUE;
		}
	}

	if (domains_disabled == TRUE) {
		output(0, "All domains disabled!\n");
		goto out_unlock;
	}

	for (i = 0; i < TRINITY_PF_MAX; i++) {
		const struct netproto *proto = net_protocols[i].proto;
		struct socket_triplet *triplets;
		unsigned int j;

		if (no_domains[i] == TRUE)
			continue;

		/* check for ctrl-c again. */
		if (shm->exit_reason != STILL_RUNNING)
			goto out_unlock;

		if (proto == NULL)
			continue;
		if (proto->nr_triplets == 0)
			continue;

		triplets = proto->valid_triplets;
		for (j = 0; j < proto->nr_triplets; j++)
			ret |= generate_socket(triplets[j].family, triplets[j].protocol, triplets[j].type);

		if (proto->nr_privileged_triplets == 0)
			continue;

		if (orig_uid != 0)
			continue;

		triplets = proto->valid_privileged_triplets;
		for (j = 0; j < proto->nr_privileged_triplets; j++)
			ret |= generate_socket(triplets[j].family, triplets[j].protocol, triplets[j].type);
	}

	/* This is here temporarily until we have sufficient ->valid_proto's */
	while (nr_sockets < NR_SOCKET_FDS) {
		r = rnd() % TRINITY_PF_MAX;
		for (i = 0; i < 10; i++)
			generate_specific_socket(r);
	}

out_unlock:
	if (cachefile != -1) {
		unlock_cachefile();
		close(cachefile);
	}

	return ret;
}