void resolve_hostname(std::string hostname, Callback<ResolveHostnameResult> cb,
                      Settings settings, SharedPtr<Reactor> reactor,
                      SharedPtr<Logger> logger) {

    logger->debug("resolve_hostname: %s", hostname.c_str());

    sockaddr_storage storage;
    SharedPtr<ResolveHostnameResult> result{
            std::make_shared<ResolveHostnameResult>()};

    // If address is a valid IPv4 address, connect directly
    memset(&storage, 0, sizeof storage);
    if (inet_pton(PF_INET, hostname.c_str(), &storage) == 1) {
        logger->debug("resolve_hostname: is valid ipv4");
        result->addresses.push_back(hostname);
        result->inet_pton_ipv4 = true;
        cb(*result);
        return;
    }

    // If address is a valid IPv6 address, connect directly
    memset(&storage, 0, sizeof storage);
    if (inet_pton(PF_INET6, hostname.c_str(), &storage) == 1) {
        logger->debug("resolve_hostname: is valid ipv6");
        result->addresses.push_back(hostname);
        result->inet_pton_ipv6 = true;
        cb(*result);
        return;
    }

    logger->debug("resolve_hostname: ipv4...");

    dns::query("IN", "A", hostname,
               [=](Error err, SharedPtr<dns::Message> resp) {
                   logger->debug("resolve_hostname: ipv4... done");
                   result->ipv4_err = err;
                   if (!err) {
                       result->ipv4_reply = *resp;
                       for (dns::Answer answer : resp->answers) {
                           // Don't connect using pure CNAME answers.
                           if (answer.ipv4 != "") {
                              result->addresses.push_back(answer.ipv4);
                           }
                       }
                   }
                   logger->debug("resolve_hostname: ipv6...");
                   dns::query(
                       "IN", "AAAA", hostname,
                       [=](Error err, SharedPtr<dns::Message> resp) {
                           logger->debug("resolve_hostname: ipv6... done");
                           result->ipv6_err = err;
                           if (!err) {
                               result->ipv6_reply = *resp;
                               for (dns::Answer answer : resp->answers) {
                                   // Don't connect using pure CNAME answers.
                                   if (answer.ipv6 != "") {
                                       result->addresses.push_back(answer.ipv6);
                                   }
                               }
                           }
                           cb(*result);
                       },
                       settings, reactor, logger);
               },
               settings, reactor, logger);
}
Exemple #2
0
/****************************************************************************
 * Name: ConnectReceive
 *
 * Description:
 *   Blocking connect and receive
 *
 * Input Parameters:
 *   dconf - socket daemon configuration
 *
 * Returned Value:
 *   None
 *
 * Assumptions/Limitations:
 *   None
 *
 ****************************************************************************/
static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf)
{
  ssize_t ret;
  size_t datalen;
  void *data;
  struct sockaddr_in addr;
  char databuf[5];

  /* Start test daemon. */

  dconf->endpoint_addr = "127.0.0.1";
  dconf->endpoint_port = 255;
  dconf->endpoint_block_connect = true;
  dconf->endpoint_block_send = true;
  dconf->endpoint_recv_avail_from_start = false;
  dconf->endpoint_recv_avail = 7;
  TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
  started = true;
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());

  /* Open socket */

  sd = socket(AF_INET, SOCK_STREAM, 0);
  TEST_ASSERT_TRUE(sd >= 0);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Do connect, should succeed (after connect block released). */

  inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
  addr.sin_family = AF_INET;
  addr.sin_port = htons(255);
  TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
  ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
  TEST_ASSERT_EQUAL(0, ret);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Receive data from remote */

  data = databuf;
  datalen = sizeof(databuf);
  TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
  ret = recvfrom(sd, data, datalen, 0, NULL, 0);
  TEST_ASSERT_EQUAL(datalen, ret);
  TEST_ASSERT_EQUAL(5, ret);
  TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Receive data from remote */

  data = databuf;
  datalen = sizeof(databuf);
  ret = recvfrom(sd, data, datalen, 0, NULL, 0);
  TEST_ASSERT_EQUAL(2, ret);
  TEST_ASSERT_EQUAL_UINT8_ARRAY("ab", data, 2);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Close socket */

  TEST_ASSERT_TRUE(close(sd) >= 0);
  sd = -1;
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());

  /* Stopping daemon should succeed. */

  TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
  started = false;
  TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
  TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
Exemple #3
0
int main(int argc, char **argv)
{
	WSADATA wsaData;

	char *sendbuf = "this is a test";
	char recvbuf[DEFAULT_BUFLEN];
	int iResult;
	int recvbuflen = DEFAULT_BUFLEN;
	char IP[15] = "127.0.0.1";
	char input[128];
	int port = -1;
	struct sockaddr_in addr;
	u_short len;
	char lenMsg[3] = "12\n";

	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed with error: %d\n", iResult);
		return 1;
	}

	printf("Started client process\n");
	printf("Please enter IP for client process(localhost by default): ");
	gets(IP);
	if (!strcmp(IP, ""))
		strncpy_s(IP, 10, "127.0.0.1", 9);
	printf("Please enter port number: ");
	gets(input);
	port = atoi(input);
	if (port <= 0)
	{
		printf("Invalid port number entered, leaving process\n");
		return 1;
	}

	printf("client process using address: tcp://%s:%d\n", IP, port);

	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	if (inet_pton(AF_INET, &IP, &addr.sin_addr) != 1)
		printf("Error in code\n");

	// Create a SOCKET for connecting to server
	ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (ConnectSocket == INVALID_SOCKET) {
		printf("socket failed with error: %ld\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}
	printf("client: connecting to socket...");
	// Connect to server.
	iResult = connect(ConnectSocket, (struct sockaddr *)&addr, sizeof(addr));
	if (iResult == SOCKET_ERROR) {
		closesocket(ConnectSocket);
		ConnectSocket = INVALID_SOCKET;
	}

	if (ConnectSocket == INVALID_SOCKET) {
		printf("Unable to connect to server!\n");
		WSACleanup();
		return 1;
	}

	printf("Connected.\nClient: waiting for welcome message.\n");
	if (s_recv() < 0)
	{	
		printf("Client: error recieving message. Closing. \n");
		shut();
		return 0;
	}
	printf("Recieved: %s.\n", filteredMsg);
	if (strcmp(filteredMsg, "welcome") != 0)
	{
		printf("Recieved unknown message, Closing\n.");
		shut();
		return 0;
	}

	printf("Client, please enter ID number:");
	gets(input);

	if (s_send(input))
	{
		shut();
		return 0;
	}

	printf("please enter name: ");
	gets(input);
	if (s_send(input))
	{
		shut();
		return 0;
	}
	if (s_recv() < 0)
	{
		printf("Client: error recieving message. Closing. \n");
		shut();
		return 0;
	}
	if (!strcmp(filteredMsg, "failure"))
	{
		printf("Incorrect ID/name combination. Closing");
		shut();
		return 0;
	}
	else if (strcmp(filteredMsg, "success") != 0)
	{
		printf("Recieved unknown message, Closing\n.");
		shut();
		return 0;
	}

	printf("Client: found pair in server.\n");
	printf("Please enter password: "******"send failed with error: %d\n", WSAGetLastError());
		closesocket(ConnectSocket);
		WSACleanup();
		gets(input);
		return 1;
	}

	input[strlen(input)] = '\n';
	if (s_send(input))
	{
		shut();
		gets(input);
		return 0;
	}
	if (s_recv() < 0)
	{
		printf("Client: error recieving message. Closing. \n");
		shut();
		gets(input);
		return 0;
	}

	printf("%s\n", filteredMsg);
	shut();
	//if (s_recv() < 0)
	//{
	//	printf("Client: error recieving message. Closing. \n");
	//	shut();
	//	return 0;
	//}
	//// cleanup
	gets(input);
	return 0;
}
Exemple #4
0
void
read_pharos_stats(struct module *mod, char *parameter)
{
    int                 write_flag = 0, addr_len, domain;
    int                 m, sockfd, send, pos;
    void               *addr;
    char                buf[LEN_4096], request[LEN_4096], line[LEN_4096];
    FILE               *stream = NULL;

    struct sockaddr_in  servaddr;
    struct sockaddr_un  servaddr_un;
    struct hostinfo     hinfo;

    init_pharos_host_info(&hinfo);
    if (atoi(parameter) != 0) {
       hinfo.port = atoi(parameter);
    }
    struct stats_pharos st_pharos;
    memset(&st_pharos, 0, sizeof(struct stats_pharos));

    if (*hinfo.host == '/') {
        addr = &servaddr_un;
        addr_len = sizeof(servaddr_un);
        bzero(addr, addr_len);
        domain = AF_LOCAL;
        servaddr_un.sun_family = AF_LOCAL;
        strncpy(servaddr_un.sun_path, hinfo.host, sizeof(servaddr_un.sun_path) - 1);

    } else {
        addr = &servaddr;
        addr_len = sizeof(servaddr);
        bzero(addr, addr_len);
        domain = AF_INET;
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(hinfo.port);
        inet_pton(AF_INET, hinfo.host, &servaddr.sin_addr);
    }


    if ((sockfd = socket(domain, SOCK_STREAM, 0)) == -1) {
        goto writebuf;
    }

    sprintf(request,
            "GET %s HTTP/1.0\r\n"
            "User-Agent: taobot\r\n"
            "Host: %s\r\n"
            "Accept:*/*\r\n"
            "Connection: Close\r\n\r\n",
            hinfo.uri, hinfo.server_name);

    if ((m = connect(sockfd, (struct sockaddr *) addr, addr_len)) == -1 ) {
        goto writebuf;
    }

    if ((send = write(sockfd, request, strlen(request))) == -1) {
        goto writebuf;
    }

    if ((stream = fdopen(sockfd, "r")) == NULL) {
        goto writebuf;
    }

    while (fgets(line, LEN_4096, stream) != NULL) {
        if (!strncmp(line, "request_status:", sizeof("request_status:") - 1)) {
            sscanf(line, "request_status:requests=%llu,tcp_reqs=%llu,udp_reqs=%llu,tcp_accepts=%llu,rt=%llu",
                    &st_pharos.requests, &st_pharos.tcp_reqs, &st_pharos.udp_reqs,
                    &st_pharos.tcp_accepts, &st_pharos.rt);
            write_flag = 1;
        }
    }

writebuf:
    if (stream) {
        fclose(stream);
    }

    if (sockfd != -1) {
        close(sockfd);
    }

    if (write_flag) {
        pos = sprintf(buf, "%lld,%lld,%lld,%lld,",
                st_pharos.requests,
                st_pharos.tcp_reqs,
                st_pharos.udp_reqs,
                st_pharos.rt);

        buf[pos] = '\0';
        set_mod_record(mod, buf);
    }
}
Exemple #5
0
void
read_nginx_live_stats(struct module *mod, char *parameter)
{
    int                 addr_len, domain, m, sockfd, send, pos = 0;
    char                buf[LEN_1M], request[LEN_4096], line[LEN_4096];
    unsigned long long online = 0, online_history = 0, up_flow = 0;
    unsigned long long down_flow = 0, fmtime = 0, drop_frame = 0;
    char               *p;
    void               *addr;
    FILE               *stream = NULL;
    struct sockaddr_in  servaddr;
    struct sockaddr_un  servaddr_un;
    struct hostinfo     hinfo;
    struct stats_nginx_live  stat;

    /* get peer info */
    init_nginx_host_info(&hinfo);

    if (*hinfo.host == '/') {
        addr = &servaddr_un;
        addr_len = sizeof(servaddr_un);
        bzero(addr, addr_len);
        domain = AF_LOCAL;
        servaddr_un.sun_family = AF_LOCAL;
        strncpy(servaddr_un.sun_path, hinfo.host, sizeof(servaddr_un.sun_path) - 1);

    } else {
        addr = &servaddr;
        addr_len = sizeof(servaddr);
        bzero(addr, addr_len);
        domain = AF_INET;
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(hinfo.port);
        inet_pton(AF_INET, hinfo.host, &servaddr.sin_addr);
    }

    /* send request */
    if ((sockfd = socket(domain, SOCK_STREAM, 0)) == -1) {
        return;
    }

    sprintf(request,
            "GET %s HTTP/1.0\r\n"
            "User-Agent: taobot\r\n"
            "Host: %s\r\n"
            "Accept:*/*\r\n"
            "Connection: Close\r\n\r\n",
            hinfo.uri, hinfo.server_name);

    if ((m = connect(sockfd, (struct sockaddr *) addr, addr_len)) == -1 ) {
        close(sockfd);
        return;
    }

    if ((send = write(sockfd, request, strlen(request))) == -1) {
        close(sockfd);
        return;
    }

    /* read & parse request */
    if ((stream = fdopen(sockfd, "r")) == NULL) {
        close(sockfd);
        return;
    }

    memset(&stat, 0, sizeof(struct stats_nginx_live));
    while (fgets(line, LEN_4096, stream) != NULL) {
        if ((p = strstr(line, "fm_time")) == NULL) {
            continue;
        }

        if (sscanf(p, "fm_time:%llu drop_frame:%llu online:%llu online_history:%llu down_flow:%llu up_flow:%llu",
                   &fmtime, &drop_frame, &online, &online_history, &down_flow, &up_flow) != 6) {
            continue;
        }
        stat.online += online;
        stat.fmdata += fmtime;
        stat.dropfr += drop_frame;
        stat.olhstr += online_history;
        stat.downfl += down_flow;
        stat.upflow += up_flow;
    }
    pos += snprintf(buf + pos, LEN_1M - pos, "%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld", stat.online, stat.olhstr, stat.olvary, stat.upflow, stat.uspeed, stat.downfl, stat.dspeed, stat.fmtime, stat.fmdata, stat.dropfr);
    if (strlen(buf) >= LEN_1M - 1) {
        fclose(stream);
        close(sockfd);
        return;
    }

    set_mod_record(mod, buf);
    fclose(stream);
    close(sockfd);
}
/*
 * _gai_numerichost
 * Determines whether the given host name is a numeric IPv4 or IPv6 address,
 * based on the address family input value.  If the input addres family is
 * unspecified, a more specific value will be provided on output if possible.
 * Returns 1 if host name is numeric or 0 if not, or -1 on error.
 */
static int
_gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_addr *a4, struct in6_addr *a6, int *scope)
{
	int numerichost, passive;

	numerichost = 0;

	if (nodename == NULL)
	{
		/* return loopback or passive addresses */
		passive = (flags & AI_PASSIVE);

		if (((*family == AF_UNSPEC) || (*family == AF_INET)) || ((*family == AF_INET6) && (flags & AI_V4MAPPED) && (flags & AI_ALL)))
		{
			if (passive) a4->s_addr = 0;
			else a4->s_addr = htonl(INADDR_LOOPBACK);
		}

		if ((*family == AF_UNSPEC) || (*family == AF_INET6))
		{
			memset(a6, 0, sizeof(*a6));
			if (!passive) a6->__u6_addr.__u6_addr32[3] = htonl(1);
		}

		numerichost = 1;
	}
	else
	{
		/*
		 * numeric IPv4 host valid for AF_UNSPEC and AF_INET
		 * also valid for AF_INET6 with AI_V4MAPPED
		 */
		numerichost = inet_pton(AF_INET, nodename, a4);
		if (numerichost == 0)
		{
			/* inet_pton doesn't allow "a", "a.b", or "a.b.c" forms, so we re-check */
			numerichost = _inet_aton_check(nodename, a4, 1);
		}

		if (numerichost == 1)
		{
			if (*family == AF_UNSPEC)
			{
				*family = AF_INET;
			}
			else if (*family == AF_INET6)
			{
				if (flags & AI_V4MAPPED)
				{
					memset(a6, 0, sizeof(struct in6_addr));
					memset(&(a6->__u6_addr.__u6_addr8[10]), 0xff, 2);
					memcpy(&(a6->__u6_addr.__u6_addr8[12]), a4, sizeof(struct in_addr));
				}
				else
				{
					numerichost = -1;
				}
			}

			return numerichost;
		}

		/* numeric IPv6 host valid for AF_UNSPEC and AF_INET6 */
		numerichost = inet_pton(AF_INET6, nodename, a6);
		if (numerichost == 1)
		{
			/* check for scope/zone id */
			char *p = strrchr(nodename, SCOPE_DELIMITER);
			if (p != NULL)
			{
				int i, d;
				char *x;
				
				p++;
				d = 1;
				for (x = p; (*x != '\0') && (d == 1); x++)
				{
					i = *x;
					d = isdigit(i);
				}
				
				if (d == 1) *scope = atoi(p);
				else *scope = if_nametoindex(p);
			}

			if (*family == AF_UNSPEC) *family = AF_INET6;
			else if (*family == AF_INET) numerichost = -1;

			return numerichost;
		}
	}

	return numerichost;
}
Exemple #7
0
VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
{
	char		*p, *s=0;
	const char	*cp, *cs;
	int		x;
	size_t		length;
	DICT_VALUE	*dval;

	if (!value) return NULL;

	/*
	 *	Even for integers, dates and ip addresses we
	 *	keep the original string in vp->vp_strvalue.
	 */
	if (vp->type != PW_TYPE_TLV) {
		strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
		vp->length = strlen(vp->vp_strvalue);
	}

	switch(vp->type) {
		case PW_TYPE_STRING:
			/*
			 *	Do escaping here
			 */
			p = vp->vp_strvalue;
			cp = value;
			length = 0;

			while (*cp && (length < (sizeof(vp->vp_strvalue) - 1))) {
				char c = *cp++;

				if (c == '\\') {
					switch (*cp) {
					case 'r':
						c = '\r';
						cp++;
						break;
					case 'n':
						c = '\n';
						cp++;
						break;
					case 't':
						c = '\t';
						cp++;
						break;
					case '"':
						c = '"';
						cp++;
						break;
					case '\'':
						c = '\'';
						cp++;
						break;
					case '\\':
						c = '\\';
						cp++;
						break;
					case '`':
						c = '`';
						cp++;
						break;
					case '\0':
						c = '\\'; /* no cp++ */
						break;
					default:
						if ((cp[0] >= '0') &&
						    (cp[0] <= '9') &&
						    (cp[1] >= '0') &&
						    (cp[1] <= '9') &&
						    (cp[2] >= '0') &&
						    (cp[2] <= '9') &&
						    (sscanf(cp, "%3o", &x) == 1)) {
							c = x;
							cp += 3;
						} /* else just do '\\' */
					}
				}
				*p++ = c;
				length++;
			}
			vp->vp_strvalue[length] = '\0';
			vp->length = length;
			break;

		case PW_TYPE_IPADDR:
			/*
			 *	It's a comparison, not a real IP.
			 */
			if ((vp->operator == T_OP_REG_EQ) ||
			    (vp->operator == T_OP_REG_NE)) {
				break;
			}

			/*
			 *	FIXME: complain if hostname
			 *	cannot be resolved, or resolve later!
			 */
			s = NULL;
			if ((p = strrchr(value, '+')) != NULL && !p[1]) {
				cs = s = strdup(value);
				if (!s) return NULL;
				p = strrchr(s, '+');
				*p = 0;
				vp->flags.addport = 1;
			} else {
				p = NULL;
				cs = value;
			}

			{
				fr_ipaddr_t ipaddr;

				if (ip_hton(cs, AF_INET, &ipaddr) < 0) {
					free(s);
					fr_strerror_printf("Failed to find IP address for %s", cs);
					return NULL;
				}

				vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
			}
			free(s);
			vp->length = 4;
			break;

		case PW_TYPE_BYTE:
			vp->length = 1;

			/*
			 *	Note that ALL integers are unsigned!
			 */
			vp->vp_integer = getint(value, &p);
			if (!*p) {
				if (vp->vp_integer > 255) {
					fr_strerror_printf("Byte value \"%s\" is larger than 255", value);
					return NULL;
				}
				break;
			}
			if (check_for_whitespace(p)) break;
			goto check_for_value;

		case PW_TYPE_SHORT:
			/*
			 *	Note that ALL integers are unsigned!
			 */
			vp->vp_integer = getint(value, &p);
			vp->length = 2;
			if (!*p) {
				if (vp->vp_integer > 65535) {
					fr_strerror_printf("Byte value \"%s\" is larger than 65535", value);
					return NULL;
				}
				break;
			}
			if (check_for_whitespace(p)) break;
			goto check_for_value;

		case PW_TYPE_INTEGER:
			/*
			 *	Note that ALL integers are unsigned!
			 */
			vp->vp_integer = getint(value, &p);
			vp->length = 4;
			if (!*p) break;
			if (check_for_whitespace(p)) break;

	check_for_value:
			/*
			 *	Look for the named value for the given
			 *	attribute.
			 */
			if ((dval = dict_valbyname(vp->attribute, vp->vendor, value)) == NULL) {
				fr_strerror_printf("Unknown value %s for attribute %s",
					   value, vp->name);
				return NULL;
			}
			vp->vp_integer = dval->value;
			break;

		case PW_TYPE_DATE:
		  	{
				/*
				 *	time_t may be 64 bits, whule vp_date
				 *	MUST be 32-bits.  We need an
				 *	intermediary variable to handle
				 *	the conversions.
				 */
				time_t date;

				if (gettime(value, &date) < 0) {
					fr_strerror_printf("failed to parse time string "
						   "\"%s\"", value);
					return NULL;
				}

				vp->vp_date = date;
			}
			vp->length = 4;
			break;

		case PW_TYPE_ABINARY:
#ifdef ASCEND_BINARY
			if (strncasecmp(value, "0x", 2) == 0) {
				vp->type = PW_TYPE_OCTETS;
				goto do_octets;
			}

		  	if (ascend_parse_filter(vp) < 0 ) {
				char buffer[256];

				snprintf(buffer, sizeof(buffer), "failed to parse Ascend binary attribute: %s", fr_strerror());
				fr_strerror_printf("%s", buffer);
				return NULL;
			}
			break;

			/*
			 *	If Ascend binary is NOT defined,
			 *	then fall through to raw octets, so that
			 *	the user can at least make them by hand...
			 */
	do_octets:
#endif
			/* raw octets: 0x01020304... */
		case PW_TYPE_OCTETS:
			if (strncasecmp(value, "0x", 2) == 0) {
				size_t size;
				uint8_t *us;

				cp = value + 2;
				us = vp->vp_octets;
				vp->length = 0;

				/*
				 *	Invalid.
				 */
				size = strlen(cp);
				if ((size  & 0x01) != 0) {
					fr_strerror_printf("Hex string is not an even length string.");
					return NULL;
				}

				vp->length = size >> 1;
				if (size > 2*sizeof(vp->vp_octets)) {
					vp->type |= PW_FLAG_LONG;
					us = vp->vp_tlv = malloc(vp->length);
					if (!us) {
						fr_strerror_printf("Out of memory.");
						return NULL;
					}
				}

				if (fr_hex2bin(cp, us,
					       vp->length) != vp->length) {
					fr_strerror_printf("Invalid hex data");
					return NULL;
				}
			}
			break;

		case PW_TYPE_IFID:
			if (ifid_aton(value, (void *) &vp->vp_ifid) == NULL) {
				fr_strerror_printf("failed to parse interface-id "
					   "string \"%s\"", value);
				return NULL;
			}
			vp->length = 8;
			break;

		case PW_TYPE_IPV6ADDR:
			{
				fr_ipaddr_t ipaddr;

				if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
					char buffer[1024];

					strlcpy(buffer, fr_strerror(), sizeof(buffer));

					fr_strerror_printf("failed to parse IPv6 address "
                                                           "string \"%s\": %s", value, buffer);
					return NULL;
				}
				vp->vp_ipv6addr = ipaddr.ipaddr.ip6addr;
				vp->length = 16; /* length of IPv6 address */
			}
			break;

		case PW_TYPE_IPV6PREFIX:
			p = strchr(value, '/');
			if (!p || ((p - value) >= 256)) {
				fr_strerror_printf("invalid IPv6 prefix "
					   "string \"%s\"", value);
				return NULL;
			} else {
				unsigned int prefix;
				char buffer[256], *eptr;

				memcpy(buffer, value, p - value);
				buffer[p - value] = '\0';

				if (inet_pton(AF_INET6, buffer, vp->vp_octets + 2) <= 0) {
					fr_strerror_printf("failed to parse IPv6 address "
						   "string \"%s\"", value);
					return NULL;
				}

				prefix = strtoul(p + 1, &eptr, 10);
				if ((prefix > 128) || *eptr) {
					fr_strerror_printf("failed to parse IPv6 address "
						   "string \"%s\"", value);
					return NULL;
				}
				vp->vp_octets[1] = prefix;
			}
			vp->vp_octets[0] = '\0';
			vp->length = 16 + 2;
			break;

		case PW_TYPE_ETHERNET:
			{
				const char *c1, *c2;

				length = 0;
				cp = value;
				while (*cp) {
					if (cp[1] == ':') {
						c1 = hextab;
						c2 = memchr(hextab, tolower((int) cp[0]), 16);
						cp += 2;
					} else if ((cp[1] != '\0') &&
						   ((cp[2] == ':') ||
						    (cp[2] == '\0'))) {
						   c1 = memchr(hextab, tolower((int) cp[0]), 16);
						   c2 = memchr(hextab, tolower((int) cp[1]), 16);
						   cp += 2;
						   if (*cp == ':') cp++;
					} else {
						c1 = c2 = NULL;
					}
					if (!c1 || !c2 || (length >= sizeof(vp->vp_ether))) {
						fr_strerror_printf("failed to parse Ethernet address \"%s\"", value);
						return NULL;
					}
					vp->vp_ether[length] = ((c1-hextab)<<4) + (c2-hextab);
					length++;
				}
			}
			vp->length = 6;
			break;

		case PW_TYPE_COMBO_IP:
			if (inet_pton(AF_INET6, value, vp->vp_strvalue) > 0) {
				vp->type = PW_TYPE_IPV6ADDR;
				vp->length = 16; /* length of IPv6 address */
				vp->vp_strvalue[vp->length] = '\0';

			} else {
				fr_ipaddr_t ipaddr;

				if (ip_hton(value, AF_INET, &ipaddr) < 0) {
					fr_strerror_printf("Failed to find IPv4 address for %s", value);
					return NULL;
				}

				vp->type = PW_TYPE_IPADDR;
				vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
				vp->length = 4;
			}
			break;

		case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
			vp->vp_signed = (int32_t) strtol(value, &p, 10);
			vp->length = 4;
			break;

		case PW_TYPE_TLV: /* don't use this! */
			if (strncasecmp(value, "0x", 2) != 0) {
				fr_strerror_printf("Invalid TLV specification");
				return NULL;
			}
			length = strlen(value + 2) / 2;
			if (vp->length < length) {
				free(vp->vp_tlv);
				vp->vp_tlv = NULL;
			}
			vp->vp_tlv = malloc(length);
			if (!vp->vp_tlv) {
				fr_strerror_printf("No memory");
				return NULL;
			}
			if (fr_hex2bin(value + 2, vp->vp_tlv,
				       length) != length) {
				fr_strerror_printf("Invalid hex data in TLV");
				return NULL;
			}
			vp->length = length;
			break;

			/*
			 *  Anything else.
			 */
		default:
			fr_strerror_printf("unknown attribute type %d", vp->type);
			return NULL;
	}
Exemple #8
0
int
main(int argc, char **argv)
{
	int					sockfd, n;
	char				recvline[MAXLINE + 1];
	struct sockaddr_in	servaddr;

	if (argc != 3)
		err_sys("usage: exe  <IPaddress> <port>");

	if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		err_sys("socket error");
		
	setnonblocking(sockfd); //设置非阻塞,需要判断errno
		
	int port = atoi(argv[2]);
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port   = htons(port);	/* daytime server */
	if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
		printf("inet_pton error for %s", argv[1]);
	
	int ret;
	ret=connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
	if(ret<0 && errno == EINPROGRESS)
	{
		fd_set wset, rset;
		FD_ZERO(&wset);
		FD_SET(sockfd, &wset);
		struct timeval timeout;
		timeout.tv_sec = 5;
		timeout.tv_usec = 0;
		rset = wset;
		
		switch(select(sockfd+1,&rset,&wset,NULL,&timeout))
		{
			case -1: //select错误
            case  0:  close(sockfd); exit(-1);break; //超时 推出
            default:
		#ifndef _YOUHUA
            if(!FD_ISSET(sockfd,&wset)) //测试sock是否可读,即是否网络上有数据
            {
				printf("connect error\n");
				close(sockfd);
				exit(0);
            }// end if break;
		#else
			//改进的非阻塞socket connet连接判断
			//如果connect成功,fd变为可写,如果失败fd可读可惜
			if(FD_ISSET(sockfd,&wset) ||FD_ISSET(sockfd,&rset)  )
			{
				int error = 0;
                socklen_t len = sizeof(error);              //防止connect三次握手的第三个ACK包被丢掉。
                if(getsockopt(sock_fd,SOL_SOCKET,SO_ERROR,&error,&len) < 0)      
                 {
                     perror("get sock opt fail:");
                 }
                 if(error == 0)
                 {
                     //printf("connect success\n");
                     //sleep(1);
                 }
                 else
                 {
                 	//printf("connect fail\n");
					close(sockfd);
					exit(0);
                 }
           }
		#endif
		}	
	}
	//printf("connect ok\n");

	sleep(3);
	int counter = 0;
	loop:
	
	long urlid;
	scanf("%ld", &urlid);
	//sprintf(recvline,"client msg[%d]  [%d], wait response", sockfd,counter++);
	sprintf(recvline,"%ld|url_dianping_1|", urlid );
	write(sockfd, recvline,strlen(recvline));
	
	//printf("request msg[%d]  send over\n",counter);
	
	/*
	for (;;) {
		fd_set cli_set;
		FD_ZERO(&cli_set);
		FD_SET(sockfd, &cli_set);
		int r = select (sockfd + 1, &cli_set, NULL, NULL, NULL);
		if (r == -1 && errno == EINTR) continue;
        if (r < 0) {
            exit (1);
        }
		
		if (FD_ISSET (sockfd, &cli_set)) {
			if(read(sockfd, recvline, MAXLINE) >0)
				printf("==msg %\n",  recvline);
		}
	*/
	sleep(1);
	//非阻塞模式使用
	while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
		recvline[n] = 0;	
		printf("%s", recvline);	
	}
	//printf("recv response over\n");	
	if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
	{
		printf("  goto loop \n");
		goto loop;
	}
	else
	{
		//close(sockfd);
		//长连接的话,进行重连
		//
	}
	/*if( (n = read(sockfd, recvline, MAXLINE)) > 0) {
		recvline[n] = 0;	
		printf("recv response[%d](%s)\n",counter-1, recvline);	
		
	goto loop;}*/
	close(sockfd);
	//printf("receive over exit  %d \n", n);
	
	if (n < 0)
		err_sys("read error");

	exit(0);
}
Exemple #9
0
/* This handshake handler waits a PROXY protocol header at the beginning of the
 * raw data stream. The header looks like this :
 *
 *   "PROXY" <SP> PROTO <SP> SRC3 <SP> DST3 <SP> SRC4 <SP> <DST4> "\r\n"
 *
 * There must be exactly one space between each field. Fields are :
 *  - PROTO : layer 4 protocol, which must be "TCP4" or "TCP6".
 *  - SRC3  : layer 3 (eg: IP) source address in standard text form
 *  - DST3  : layer 3 (eg: IP) destination address in standard text form
 *  - SRC4  : layer 4 (eg: TCP port) source address in standard text form
 *  - DST4  : layer 4 (eg: TCP port) destination address in standard text form
 *
 * This line MUST be at the beginning of the buffer and MUST NOT wrap.
 *
 * The header line is small and in all cases smaller than the smallest normal
 * TCP MSS. So it MUST always be delivered as one segment, which ensures we
 * can safely use MSG_PEEK and avoid buffering.
 *
 * Once the data is fetched, the values are set in the connection's address
 * fields, and data are removed from the socket's buffer. The function returns
 * zero if it needs to wait for more data or if it fails, or 1 if it completed
 * and removed itself.
 */
int conn_recv_proxy(struct connection *conn, int flag)
{
	char *line, *end;
	struct proxy_hdr_v2 *hdr_v2;
	const char v2sig[] = PP2_SIGNATURE;
	int tlv_length = 0;
	int tlv_offset = 0;

	/* we might have been called just after an asynchronous shutr */
	if (conn->flags & CO_FL_SOCK_RD_SH)
		goto fail;

	if (!conn_ctrl_ready(conn))
		goto fail;

	if (!fd_recv_ready(conn->t.sock.fd))
		return 0;

	do {
		trash.len = recv(conn->t.sock.fd, trash.str, trash.size, MSG_PEEK);
		if (trash.len < 0) {
			if (errno == EINTR)
				continue;
			if (errno == EAGAIN) {
				fd_cant_recv(conn->t.sock.fd);
				return 0;
			}
			goto recv_abort;
		}
	} while (0);

	if (!trash.len) {
		/* client shutdown */
		conn->err_code = CO_ER_PRX_EMPTY;
		goto fail;
	}

	if (trash.len < 6)
		goto missing;

	line = trash.str;
	end = trash.str + trash.len;

	/* Decode a possible proxy request, fail early if it does not match */
	if (strncmp(line, "PROXY ", 6) != 0)
		goto not_v1;

	line += 6;
	if (trash.len < 9) /* shortest possible line */
		goto missing;

	if (memcmp(line, "TCP4 ", 5) == 0) {
		u32 src3, dst3, sport, dport;

		line += 5;

		src3 = inetaddr_host_lim_ret(line, end, &line);
		if (line == end)
			goto missing;
		if (*line++ != ' ')
			goto bad_header;

		dst3 = inetaddr_host_lim_ret(line, end, &line);
		if (line == end)
			goto missing;
		if (*line++ != ' ')
			goto bad_header;

		sport = read_uint((const char **)&line, end);
		if (line == end)
			goto missing;
		if (*line++ != ' ')
			goto bad_header;

		dport = read_uint((const char **)&line, end);
		if (line > end - 2)
			goto missing;
		if (*line++ != '\r')
			goto bad_header;
		if (*line++ != '\n')
			goto bad_header;

		/* update the session's addresses and mark them set */
		((struct sockaddr_in *)&conn->addr.from)->sin_family      = AF_INET;
		((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = htonl(src3);
		((struct sockaddr_in *)&conn->addr.from)->sin_port        = htons(sport);

		((struct sockaddr_in *)&conn->addr.to)->sin_family        = AF_INET;
		((struct sockaddr_in *)&conn->addr.to)->sin_addr.s_addr   = htonl(dst3);
		((struct sockaddr_in *)&conn->addr.to)->sin_port          = htons(dport);
		conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
	}
	else if (memcmp(line, "TCP6 ", 5) == 0) {
		u32 sport, dport;
		char *src_s;
		char *dst_s, *sport_s, *dport_s;
		struct in6_addr src3, dst3;

		line += 5;

		src_s = line;
		dst_s = sport_s = dport_s = NULL;
		while (1) {
			if (line > end - 2) {
				goto missing;
			}
			else if (*line == '\r') {
				*line = 0;
				line++;
				if (*line++ != '\n')
					goto bad_header;
				break;
			}

			if (*line == ' ') {
				*line = 0;
				if (!dst_s)
					dst_s = line + 1;
				else if (!sport_s)
					sport_s = line + 1;
				else if (!dport_s)
					dport_s = line + 1;
			}
			line++;
		}

		if (!dst_s || !sport_s || !dport_s)
			goto bad_header;

		sport = read_uint((const char **)&sport_s,dport_s - 1);
		if (*sport_s != 0)
			goto bad_header;

		dport = read_uint((const char **)&dport_s,line - 2);
		if (*dport_s != 0)
			goto bad_header;

		if (inet_pton(AF_INET6, src_s, (void *)&src3) != 1)
			goto bad_header;

		if (inet_pton(AF_INET6, dst_s, (void *)&dst3) != 1)
			goto bad_header;

		/* update the session's addresses and mark them set */
		((struct sockaddr_in6 *)&conn->addr.from)->sin6_family      = AF_INET6;
		memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, &src3, sizeof(struct in6_addr));
		((struct sockaddr_in6 *)&conn->addr.from)->sin6_port        = htons(sport);

		((struct sockaddr_in6 *)&conn->addr.to)->sin6_family        = AF_INET6;
		memcpy(&((struct sockaddr_in6 *)&conn->addr.to)->sin6_addr, &dst3, sizeof(struct in6_addr));
		((struct sockaddr_in6 *)&conn->addr.to)->sin6_port          = htons(dport);
		conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
	}
	else if (memcmp(line, "UNKNOWN\r\n", 9) == 0) {
		/* This can be a UNIX socket forwarded by an haproxy upstream */
		line += 9;
	}
	else {
		/* The protocol does not match something known (TCP4/TCP6/UNKNOWN) */
		conn->err_code = CO_ER_PRX_BAD_PROTO;
		goto fail;
	}

	trash.len = line - trash.str;
	goto eat_header;

 not_v1:
	/* try PPv2 */
	if (trash.len < PP2_HEADER_LEN)
		goto missing;

	hdr_v2 = (struct proxy_hdr_v2 *)trash.str;

	if (memcmp(hdr_v2->sig, v2sig, PP2_SIGNATURE_LEN) != 0 ||
	    (hdr_v2->ver_cmd & PP2_VERSION_MASK) != PP2_VERSION) {
		conn->err_code = CO_ER_PRX_NOT_HDR;
		goto fail;
	}

	if (trash.len < PP2_HEADER_LEN + ntohs(hdr_v2->len))
		goto missing;

	switch (hdr_v2->ver_cmd & PP2_CMD_MASK) {
	case 0x01: /* PROXY command */
		switch (hdr_v2->fam) {
		case 0x11:  /* TCPv4 */
			if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET)
				goto bad_header;

			((struct sockaddr_in *)&conn->addr.from)->sin_family = AF_INET;
			((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = hdr_v2->addr.ip4.src_addr;
			((struct sockaddr_in *)&conn->addr.from)->sin_port = hdr_v2->addr.ip4.src_port;
			((struct sockaddr_in *)&conn->addr.to)->sin_family = AF_INET;
			((struct sockaddr_in *)&conn->addr.to)->sin_addr.s_addr = hdr_v2->addr.ip4.dst_addr;
			((struct sockaddr_in *)&conn->addr.to)->sin_port = hdr_v2->addr.ip4.dst_port;
			conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
			tlv_offset = PP2_HEADER_LEN + PP2_ADDR_LEN_INET;
			tlv_length = ntohs(hdr_v2->len) - PP2_ADDR_LEN_INET;
			break;
		case 0x21:  /* TCPv6 */
			if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET6)
				goto bad_header;

			((struct sockaddr_in6 *)&conn->addr.from)->sin6_family = AF_INET6;
			memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, hdr_v2->addr.ip6.src_addr, 16);
			((struct sockaddr_in6 *)&conn->addr.from)->sin6_port = hdr_v2->addr.ip6.src_port;
			((struct sockaddr_in6 *)&conn->addr.to)->sin6_family = AF_INET6;
			memcpy(&((struct sockaddr_in6 *)&conn->addr.to)->sin6_addr, hdr_v2->addr.ip6.dst_addr, 16);
			((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = hdr_v2->addr.ip6.dst_port;
			conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
			tlv_offset = PP2_HEADER_LEN + PP2_ADDR_LEN_INET6;
			tlv_length = ntohs(hdr_v2->len) - PP2_ADDR_LEN_INET6;
			break;
		}

		/* TLV parsing */
		if (tlv_length > 0) {
			while (tlv_offset + TLV_HEADER_SIZE <= trash.len) {
				const struct tlv *tlv_packet = (struct tlv *) &trash.str[tlv_offset];
				const int tlv_len = get_tlv_length(tlv_packet);
				tlv_offset += tlv_len + TLV_HEADER_SIZE;

				switch (tlv_packet->type) {
#ifdef CONFIG_HAP_NS
				case PP2_TYPE_NETNS: {
					const struct netns_entry *ns;
					ns = netns_store_lookup((char*)tlv_packet->value, tlv_len);
					if (ns)
						conn->proxy_netns = ns;
					break;
				}
#endif
				default:
					break;
				}
			}
		}

		/* unsupported protocol, keep local connection address */
		break;
	case 0x00: /* LOCAL command */
		/* keep local connection address for LOCAL */
		break;
	default:
		goto bad_header; /* not a supported command */
	}

	trash.len = PP2_HEADER_LEN + ntohs(hdr_v2->len);
	goto eat_header;

 eat_header:
	/* remove the PROXY line from the request. For this we re-read the
	 * exact line at once. If we don't get the exact same result, we
	 * fail.
	 */
	do {
		int len2 = recv(conn->t.sock.fd, trash.str, trash.len, 0);
		if (len2 < 0 && errno == EINTR)
			continue;
		if (len2 != trash.len)
			goto recv_abort;
	} while (0);

	conn->flags &= ~flag;
	return 1;

 missing:
	/* Missing data. Since we're using MSG_PEEK, we can only poll again if
	 * we have not read anything. Otherwise we need to fail because we won't
	 * be able to poll anymore.
	 */
	conn->err_code = CO_ER_PRX_TRUNCATED;
	goto fail;

 bad_header:
	/* This is not a valid proxy protocol header */
	conn->err_code = CO_ER_PRX_BAD_HDR;
	goto fail;

 recv_abort:
	conn->err_code = CO_ER_PRX_ABORT;
	conn->flags |= CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH;
	goto fail;

 fail:
	__conn_sock_stop_both(conn);
	conn->flags |= CO_FL_ERROR;
	return 0;
}
int main(int argc, char argv[])
{
	int listfd;
	listfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (listfd < 0)
	{
		fprintf(stdout, "socket error:%s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	
	int ret;
	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port	= htons(8000);
	inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr);
	ret = bind(listfd, (struct sockaddr*)&saddr, sizeof(saddr));
	if (ret < 0)
	{
		fprintf(stdout, "bind error :%s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	ret = listen(listfd, 10);
	if (ret < 0)
	{
		fprintf(stdout, "listen error :%s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

	fd_set set;
	FD_ZERO(&set);
	FD_SET(listfd, &set);
	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	fprintf(stdout, "before pselect\n");
	
	pselect(listfd + 1, &set, NULL, NULL, NULL, &mask);

	fprintf(stdout, "after pselect\n");
	int connfd;
	connfd = accept(listfd, NULL, NULL);
	if (connfd < 0)
	{
		fprintf(stdout, "accept error :%s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	fprintf(stdout, "check avalable connfd:%d\n", connfd);
	int n;
	char buf[1024];
	int nrd;
	nrd = 0;
	bzero(buf, sizeof(buf));
	while (1)
	{
		n = recv(connfd, buf, sizeof(buf), 0);
		if (n < 0)
		{
			fprintf(stdout, "receive error :%s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}
		else if(n == 0)
		{
			fprintf(stdout, "peer close\n");
			exit(EXIT_FAILURE);
		}
		fprintf(stdout, "received buf :%s\n", buf);
		n = send(connfd, buf, n, 0);
		if (n < 0)
		{
			fprintf(stdout, "send error :%s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}
		else if (n == 0)
		{
			fprintf(stdout, "peer close\n");
			exit(EXIT_FAILURE);
		}

	}
	
	return 0;
}
Exemple #11
0
int main(int argc, char *argv[])
{
        int fd = -1;

        struct sockaddr_in sin;

        int serv_port = MULTICAST_PORT;

        /* 参数处理*/
        if( argc < 2 || argc >3 ) {
                usage(argv[0]);
                exit(EXIT_FAILURE);
        }
        if(argc == 3) {
                serv_port = atoi(argv[2]);
        }

        /* 1.创建UDP套接字*/
        if( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                perror("socket");
                exit(1);
        }
	/* 加入多播组 */
	struct ip_mreq mreq;
	bzero(&mreq, sizeof(mreq));
	mreq.imr_multiaddr.s_addr = inet_addr(argv[1]);
	mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* 本地端口建议使用INADDR_ANY*/
	
	if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq))< 0) {
		perror("multicast setsockopt error");
		exit(EXIT_FAILURE);
	}

	/* 2. 绑定 */
        /*2.1 填充sockaddr_in结构体,填充绑定的IP地址和端口号 */
        sin.sin_family = AF_INET;
        sin.sin_port = htons(MULTICAST_PORT);
#if 0
        if(inet_pton(AF_INET,SERV_IP, &sin.sin_addr) != 1) {
                perror("inet_pton");
                exit(EXIT_FAILURE);
        }
#else
        sin.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
        bzero(sin.sin_zero, 8);

        /* 允许地址快速重用 **/
        int b_reuse =1;
        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int));

        /* 2.2 调用bind()函数去绑定在本地的某个IP地址+端口上*/
        if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
                perror("bind");
                exit(EXIT_FAILURE);
        }
	
	char buf[BUFSIZ];
	int ret = -1;
	char cli_ip_addr[16];

	struct sockaddr_in cin;
	int clen = sizeof(struct sockaddr_in);
	printf("Multicast demo staring....OK!\n");
	while(1) {
		bzero(buf, BUFSIZ);
		do {
			ret = recvfrom(fd, buf, BUFSIZ-1, 0, (struct sockaddr *)&cin, &clen); 
		}while (ret < 0 && EINTR == errno);
		if(ret < 0) {
			perror("recvfrom");
			continue;
		}	
		
		if( inet_ntop(AF_INET, &cin.sin_addr.s_addr, cli_ip_addr,sizeof(cin)) != NULL) {
               		printf("Client(%s:%d) said:%s\n", cli_ip_addr, ntohs(cin.sin_port), buf);
        	} else {
                	perror("inet_ntop");
			printf("Client said:%s\n", buf);
        	}

		if(!ret || !strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) {  /* 对方输入了quit,或对方已经关闭*/ 
			printf("client(%s:%d) is exited.\n", cli_ip_addr, ntohs(cin.sin_port));
		}
	}
	
	close(fd);
}
Exemple #12
0
int main(int argc, char *argv[])
{
	int ch, hold, packlen;
	u_char *packet;
	char *target;
	struct addrinfo hints, *ai;
	int gai;
	struct sockaddr_in6 firsthop;
	int socket_errno;
	struct icmp6_filter filter;
	int err;
#ifdef __linux__
	int csum_offset, sz_opt;
#endif
	static uint32_t scope_id = 0;

	icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
	socket_errno = errno;

	uid = getuid();
	if (setuid(uid)) {
		perror("ping: setuid");
		exit(-1);
	}

	source.sin6_family = AF_INET6;
	memset(&firsthop, 0, sizeof(firsthop));
	firsthop.sin6_family = AF_INET6;

	preload = 1;
	while ((ch = getopt(argc, argv, COMMON_OPTSTR "F:")) != EOF) {
		switch(ch) {
		case 'F':
			sscanf(optarg, "%x", &flowlabel);
			options |= F_FLOWINFO;
			break;
		case 'Q':
			sscanf(optarg, "%x", &tclass);
			options |= F_TCLASS;
			break;
		case 'I':
			if (strchr(optarg, ':')) {
				char *p, *addr = strdup(optarg);

				if (!addr) {
					fprintf(stderr, "ping: out of memory\n");
					exit(2);
				}

				p = strchr(addr, SCOPE_DELIMITER);
				if (p) {
					*p = '\0';
					device = optarg + (p - addr) + 1;
				}

				if (inet_pton(AF_INET6, addr, (char*)&source.sin6_addr) <= 0) {
					fprintf(stderr, "ping: invalid source address %s\n", optarg);
					exit(2);
				}

				options |= F_STRICTSOURCE;

				free(addr);
			} else {
				device = optarg;
			}
			break;
		case 'M':
			if (strcmp(optarg, "do") == 0)
				pmtudisc = IPV6_PMTUDISC_DO;
			else if (strcmp(optarg, "dont") == 0)
				pmtudisc = IPV6_PMTUDISC_DONT;
			else if (strcmp(optarg, "want") == 0)
				pmtudisc = IPV6_PMTUDISC_WANT;
			else {
				fprintf(stderr, "ping: wrong value for -M: do, dont, want are valid ones.\n");
				exit(2);
			}
			break;
		case 'V':
			printf("ping6 utility, iputils-ss%s\n", SNAPSHOT);
			exit(0);
		COMMON_OPTIONS
			common_options(ch);
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	while (argc > 1) {
		struct in6_addr *addr;

		if (srcrt == NULL) {
			int space;

			space = inet6_srcrt_space(IPV6_SRCRT_TYPE_0, argc - 1);

			if (space == 0)	{
				fprintf(stderr, "srcrt_space failed\n");
				exit(2);
			}
			if (space + cmsglen > sizeof(cmsgbuf)) {
				fprintf(stderr, "no room for options\n");
				exit(2);
			}

			srcrt = (struct cmsghdr*)(cmsgbuf+cmsglen);
			cmsglen += CMSG_ALIGN(space);
			inet6_srcrt_init(srcrt, IPV6_SRCRT_TYPE_0);
		}

		target = *argv;

		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_INET6;
		gai = getaddrinfo(target, NULL, &hints, &ai);
		if (gai) {
			fprintf(stderr, "unknown host\n");
			exit(2);
		}
		addr = &((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr;
		inet6_srcrt_add(srcrt, addr);
		if (ipv6_addr_any(&firsthop.sin6_addr)) {
			memcpy(&firsthop.sin6_addr, addr, 16);
#ifdef HAVE_SIN6_SCOPEID
			firsthop.sin6_scope_id = ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_scope_id;
			/* Verify scope_id is the same as previous nodes */
			if (firsthop.sin6_scope_id && scope_id && firsthop.sin6_scope_id != scope_id) {
				fprintf(stderr, "scope discrepancy among the nodes\n");
				exit(2);
			} else if (!scope_id) {
				scope_id = firsthop.sin6_scope_id;
			}
#endif
		}
		freeaddrinfo(ai);

		argv++;
		argc--;
	}

	if (argc != 1)
		usage();
	target = *argv;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET6;
	gai = getaddrinfo(target, NULL, &hints, &ai);
	if (gai) {
		fprintf(stderr, "unknown host\n");
		exit(2);
	}

	memcpy(&whereto, ai->ai_addr, sizeof(whereto));
	whereto.sin6_port = htons(IPPROTO_ICMPV6);

	if (memchr(target, ':', strlen(target)))
		options |= F_NUMERIC;

	freeaddrinfo(ai);

	if (ipv6_addr_any(&firsthop.sin6_addr)) {
		memcpy(&firsthop.sin6_addr, &whereto.sin6_addr, 16);
#ifdef HAVE_SIN6_SCOPEID
		firsthop.sin6_scope_id = whereto.sin6_scope_id;
		/* Verify scope_id is the same as intermediate nodes */
		if (firsthop.sin6_scope_id && scope_id && firsthop.sin6_scope_id != scope_id) {
			fprintf(stderr, "scope discrepancy among the nodes\n");
			exit(2);
		} else if (!scope_id) {
			scope_id = firsthop.sin6_scope_id;
		}
#endif
	}

	hostname = target;

	if (ipv6_addr_any(&source.sin6_addr)) {
		socklen_t alen;
		int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);

		if (probe_fd < 0) {
			perror("socket");
			exit(2);
		}
		if (device) {
#if defined(IPV6_RECVPKTINFO) || defined(HAVE_SIN6_SCOPEID)
			unsigned int iface = if_name2index(device);
#endif
#ifdef IPV6_RECVPKTINFO
			struct in6_pktinfo ipi;

			memset(&ipi, 0, sizeof(ipi));
			ipi.ipi6_ifindex = iface;
#endif

#ifdef HAVE_SIN6_SCOPEID
			if (IN6_IS_ADDR_LINKLOCAL(&firsthop.sin6_addr) ||
			    IN6_IS_ADDR_MC_LINKLOCAL(&firsthop.sin6_addr))
				firsthop.sin6_scope_id = iface;
#endif
			if (
#ifdef IPV6_RECVPKTINFO
			    setsockopt(probe_fd, IPPROTO_IPV6, IPV6_PKTINFO, &ipi, sizeof(ipi)) == -1 &&
#endif
			    setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1) {
				perror("setsockopt(SO_BINDTODEVICE)");
			}
		}
		firsthop.sin6_port = htons(1025);
		if (connect(probe_fd, (struct sockaddr*)&firsthop, sizeof(firsthop)) == -1) {
			perror("connect");
			exit(2);
		}
		alen = sizeof(source);
		if (getsockname(probe_fd, (struct sockaddr*)&source, &alen) == -1) {
			perror("getsockname");
			exit(2);
		}
		source.sin6_port = 0;
		close(probe_fd);
	}
#ifdef HAVE_SIN6_SCOPEID
	else if (device && (IN6_IS_ADDR_LINKLOCAL(&source.sin6_addr) ||
			    IN6_IS_ADDR_MC_LINKLOCAL(&source.sin6_addr)))
		source.sin6_scope_id = if_name2index(device);
#endif

	if (icmp_sock < 0) {
		errno = socket_errno;
		perror("ping: icmp open socket");
		exit(2);
	}

	if (device) {
		struct cmsghdr *cmsg;
		struct in6_pktinfo *ipi;

		cmsg = (struct cmsghdr*)cmsgbuf;
		cmsglen += CMSG_SPACE(sizeof(*ipi));
		cmsg->cmsg_len = CMSG_LEN(sizeof(*ipi));
		cmsg->cmsg_level = SOL_IPV6;
		cmsg->cmsg_type = IPV6_PKTINFO;

		ipi = (struct in6_pktinfo*)CMSG_DATA(cmsg);
		memset(ipi, 0, sizeof(*ipi));
		ipi->ipi6_ifindex = if_name2index(device);
	}

	if ((whereto.sin6_addr.s6_addr16[0]&htons(0xff00)) == htons (0xff00)) {
		if (uid) {
			if (interval < 1000) {
				fprintf(stderr, "ping: multicast ping with too short interval.\n");
				exit(2);
			}
			if (pmtudisc >= 0 && pmtudisc != IPV6_PMTUDISC_DO) {
				fprintf(stderr, "ping: multicast ping does not fragment.\n");
				exit(2);
			}
		}
		if (pmtudisc < 0)
			pmtudisc = IPV6_PMTUDISC_DO;
	}

	if (pmtudisc >= 0) {
		if (setsockopt(icmp_sock, SOL_IPV6, IPV6_MTU_DISCOVER, &pmtudisc, sizeof(pmtudisc)) == -1) {
			perror("ping: IPV6_MTU_DISCOVER");
			exit(2);
		}
	}

	if ((options&F_STRICTSOURCE) &&
	    bind(icmp_sock, (struct sockaddr*)&source, sizeof(source)) == -1) {
		perror("ping: bind icmp socket");
		exit(2);
	}

	if (datalen >= sizeof(struct timeval))	/* can we time transfer */
		timing = 1;
	packlen = datalen + 8 + 4096 + 40 + 8; /* 4096 for rthdr */
	if (!(packet = (u_char *)malloc((u_int)packlen))) {
		fprintf(stderr, "ping: out of memory.\n");
		exit(2);
	}

	working_recverr = 1;
	hold = 1;
	if (setsockopt(icmp_sock, SOL_IPV6, IPV6_RECVERR, (char *)&hold, sizeof(hold))) {
		fprintf(stderr, "WARNING: your kernel is veeery old. No problems.\n");
		working_recverr = 0;
	}

	/* Estimate memory eaten by single packet. It is rough estimate.
	 * Actually, for small datalen's it depends on kernel side a lot. */
	hold = datalen+8;
	hold += ((hold+511)/512)*(40+16+64+160);
	sock_setbufs(icmp_sock, hold);

#ifdef __linux__
	csum_offset = 2;
	sz_opt = sizeof(int);

	err = setsockopt(icmp_sock, SOL_RAW, IPV6_CHECKSUM, &csum_offset, sz_opt);
	if (err < 0) {
		/* checksum should be enabled by default and setting this
		 * option might fail anyway.
		 */
		fprintf(stderr, "setsockopt(RAW_CHECKSUM) failed - try to continue.");
	}
#endif

	/*
	 *	select icmp echo reply as icmp type to receive
	 */

	ICMP6_FILTER_SETBLOCKALL(&filter);

	if (!working_recverr) {
		ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &filter);
		ICMP6_FILTER_SETPASS(ICMP6_PACKET_TOO_BIG, &filter);
		ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &filter);
		ICMP6_FILTER_SETPASS(ICMP6_PARAM_PROB, &filter);
	}

	ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);

	err = setsockopt(icmp_sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
			 sizeof(struct icmp6_filter));

	if (err < 0) {
		perror("setsockopt(ICMP6_FILTER)");
		exit(2);
	}

	if (options & F_NOLOOP) {
		int loop = 0;
		if (setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
							&loop, sizeof(loop)) == -1) {
			perror ("can't disable multicast loopback");
			exit(2);
		}
	}
	if (options & F_TTL) {
		if (setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
			       &ttl, sizeof(ttl)) == -1) {
			perror ("can't set multicast hop limit");
			exit(2);
		}
		if (setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
			       &ttl, sizeof(ttl)) == -1) {
			perror ("can't set unicast hop limit");
			exit(2);
		}
	}

	if (1) {
		int on = 1;
		if (
#ifdef IPV6_RECVHOPLIMIT
		    setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
			       &on, sizeof(on)) == -1 &&
		    setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_2292HOPLIMIT,
			       &on, sizeof(on)) == -1
#else
		    setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_HOPLIMIT,
			       &on, sizeof(on)) == -1
#endif
		   ){
			perror ("can't receive hop limit");
			exit(2);
		}
	}

	if (options&F_FLOWINFO) {
#ifdef IPV6_FLOWLABEL_MGR
		char freq_buf[CMSG_ALIGN(sizeof(struct in6_flowlabel_req)) + cmsglen];
		struct in6_flowlabel_req *freq = (struct in6_flowlabel_req *)freq_buf;
		int freq_len = sizeof(*freq);
		if (srcrt)
			freq_len = CMSG_ALIGN(sizeof(*freq)) + srcrt->cmsg_len;
		memset(freq, 0, sizeof(*freq));
		freq->flr_label = htonl(flowlabel&0xFFFFF);
		freq->flr_action = IPV6_FL_A_GET;
		freq->flr_flags = IPV6_FL_F_CREATE;
		freq->flr_share = IPV6_FL_S_EXCL;
		memcpy(&freq->flr_dst, &whereto.sin6_addr, 16);
		if (srcrt)
			memcpy(freq_buf + CMSG_ALIGN(sizeof(*freq)), srcrt, srcrt->cmsg_len);
		if (setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_FLOWLABEL_MGR,
			       freq, freq_len) == -1) {
			perror ("can't set flowlabel");
			exit(2);
		}
		flowlabel = freq->flr_label;
		if (srcrt) {
			cmsglen = (char*)srcrt - (char*)cmsgbuf;
			srcrt = NULL;
		}
#else
		fprintf(stderr, "Flow labels are not supported.\n");
		exit(2);
#endif
	}
	if (options&(F_FLOWINFO|F_TCLASS)) {
#ifdef IPV6_FLOWINFO_SEND
		int on = 1;
		whereto.sin6_flowinfo = flowlabel | htonl((tclass&0xFF)<<20);
		if (setsockopt(icmp_sock, IPPROTO_IPV6, IPV6_FLOWINFO_SEND,
			       &on, sizeof(on)) == -1) {
			perror ("can't send flowinfo");
			exit(2);
		}
#else
		fprintf(stderr, "Flowinfo is not supported.\n");
		exit(2);
#endif
	}

	printf("PING %s(%s) ", hostname, pr_addr(&whereto.sin6_addr));
	if (flowlabel)
		printf(", flow 0x%05x, ", (unsigned)ntohl(flowlabel));
	if (device || (options&F_STRICTSOURCE)) {
		printf("from %s %s: ",
		       pr_addr_n(&source.sin6_addr), device ? : "");
	}
Exemple #13
0
int main(int argc, char **argv)  {
	int optval = 1;
	int print_help = 0;
	int send_packets = 5;
	int fastmode = 0;
	int c;
	struct sockaddr_in si_me;
	struct mt_packet packet;
	int i;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while (1) {
		c = getopt(argc, argv, "fs:c:hv?");

		if (c == -1) {
			break;
		}

		switch (c) {
			case 'f':
				fastmode = 1;
				break;

			case 's':
				ping_size = atoi(optarg) - 18;
				break;

			case 'v':
				print_version();
				exit(0);
				break;

			case 'c':
				send_packets = atoi(optarg);
				break;

			case 'h':
			case '?':
				print_help = 1;
				break;

		}
	}

	/* We don't want people to use this for the wrong reasons */
	if (fastmode && (send_packets <= 0 || send_packets > 100)) {
		fprintf(stderr, _("Number of packets to send must be more than 0 and up to 100 in fast mode.\n"));
		return 1;
	}

	if (argc - optind < 1 || print_help) {
		print_version();
		fprintf(stderr, _("Usage: %s <MAC> [-h] [-f] [-c <count>] [-s <packet size>]\n"), argv[0]);

		if (print_help) {
			fprintf(stderr, _("\nParameters:\n"
			"  MAC       MAC-Address of the RouterOS/mactelnetd device.\n"
			"  -f        Fast mode, do not wait before sending next ping request.\n"
			"  -s        Specify size of ping packet.\n"
			"  -c        Number of packets to send. (0 = unlimited)\n"
			"  -h        This help.\n"
			"\n"));
		}
		return 1;
	}

	if (ping_size > ETH_FRAME_LEN - 42) {
		fprintf(stderr, _("Packet size must be between 18 and %d\n"), ETH_FRAME_LEN - 42 + 18);
		exit(1);
	}

	/* Mikrotik RouterOS does not answer unless the packet has the correct recipient mac-address in
	 * the ethernet frame. Unlike real MacTelnet connections where the OS is ok with it being a
	 * broadcast mac address.
	 */
	if (geteuid() != 0) {
		fprintf(stderr, _("You need to have root privileges to use %s.\n"), argv[0]);
		return 1;
	}

	/* Get mac-address from string, or check for hostname via mndp */
	if (!query_mndp_or_mac(argv[optind], dstmac, 1)) {
		/* No valid mac address found, abort */
		return 1;
	}

	sockfd = net_init_raw_socket();

	insockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (insockfd < 0) {
		perror("insockfd");
		return 1;
	}

	/* Set initialize address/port */
	memset((char *) &si_me, 0, sizeof(si_me));
	si_me.sin_family = AF_INET;
	si_me.sin_port = htons(MT_MACTELNET_PORT);
	si_me.sin_addr.s_addr = htonl(INADDR_ANY);

	setsockopt(insockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));

	/* Bind to specified address/port */
	if (bind(insockfd, (struct sockaddr *)&si_me, sizeof(si_me))==-1) {
		fprintf(stderr, _("Error binding to %s:%d\n"), inet_ntoa(si_me.sin_addr), MT_MNDP_PORT);
		return 1;
	}

	/* Listen address*/
	inet_pton(AF_INET, (char *)"0.0.0.0", &sourceip);

	/* Set up global info about the connection */
	inet_pton(AF_INET, (char *)"255.255.255.255", &destip);

	srand(time(NULL));

	/* Enumerate available interfaces */
	net_get_interfaces(&interfaces);

	if (ping_size < sizeof(struct timeval)) {
		ping_size = sizeof(struct timeval);
	}

	signal(SIGINT, display_results);

	for (i = 0; i < send_packets || send_packets <= 0; ++i) {
		fd_set read_fds;
		static struct timeval lasttimestamp;
		int reads, result;
		struct timeval timeout;
		int ii;
		int sent = 0;
		int waitforpacket;
		struct timeval timestamp;
		unsigned char pingdata[MT_PACKET_LEN];
		struct net_interface *interface;

		gettimeofday(&timestamp, NULL);
		memcpy(pingdata, &timestamp, sizeof(timestamp));
		for (ii = sizeof(timestamp); ii < ping_size; ++ii) {
			pingdata[ii] = rand() % 256;
		}

		LL_FOREACH(interfaces, interface) {
			if (!interface->has_mac) {
				continue;
			}

			init_pingpacket(&packet, interface->mac_addr, dstmac);
			add_packetdata(&packet, pingdata, ping_size);
			result = net_send_udp(sockfd, interface, interface->mac_addr, dstmac, &sourceip, MT_MACTELNET_PORT, &destip, MT_MACTELNET_PORT, packet.data, packet.size);

			if (result > 0) {
				sent++;
			}

		}
		if (sent == 0) {
			fprintf(stderr, _("Error sending packet.\n"));
			continue;
		}
		ping_sent++;

		FD_ZERO(&read_fds);
		FD_SET(insockfd, &read_fds);

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;

		waitforpacket = 1;

		while (waitforpacket) {
			/* Wait for data or timeout */
			reads = select(insockfd+1, &read_fds, NULL, NULL, &timeout);
			if (reads <= 0) {
				waitforpacket = 0;
				fprintf(stderr, _("%s ping timeout\n"), ether_ntoa((struct ether_addr *)&dstmac));
				break;
			}

			unsigned char buff[MT_PACKET_LEN];
			struct sockaddr_in saddress;
			unsigned int slen = sizeof(saddress);
			struct mt_mactelnet_hdr pkthdr;

			result = recvfrom(insockfd, buff, sizeof(buff), 0, (struct sockaddr *)&saddress, &slen);
			/* Check for exact size */
			if (result != 18 + ping_size) {
				continue;
			}
			parse_packet(buff, &pkthdr);

			/* TODO: Check that we are the receiving host */
			if (pkthdr.ptype != MT_PTYPE_PONG) {
				/* Wait for the correct packet */
				continue;
			}
			
			struct timeval pongtimestamp;
			struct timeval nowtimestamp;

			waitforpacket = 0;
			gettimeofday(&nowtimestamp, NULL);

			memcpy(&pongtimestamp, pkthdr.data - 4, sizeof(pongtimestamp));
			if (memcmp(pkthdr.data - 4, pingdata, ping_size) == 0) {
				float diff = toddiff(&nowtimestamp, &pongtimestamp) / 1000.0f;

				if (diff < min_ms) {
					min_ms = diff;
				}

				if (diff > max_ms) {
					max_ms = diff;
				}

				avg_ms += diff;

				printf(_("%s %d byte, ping time %.2f ms%s\n"), ether_ntoa((struct ether_addr *)&(pkthdr.srcaddr)), result, diff, (char *)(memcmp(&pongtimestamp,&lasttimestamp,sizeof(lasttimestamp)) == 0 ? " DUP" : ""));
			} else {
				printf(_("%s Reply of %d bytes of unequal data\n"), ether_ntoa((struct ether_addr *)&(pkthdr.srcaddr)), result);
			}
			pong_received++;
			memcpy(&lasttimestamp, &pongtimestamp, sizeof(pongtimestamp));
			if (!fastmode) {
				sleep(1);
			}
		}
	}

	/* Display statistics and exit */
	display_results();

	return 0;
}
Exemple #14
0
char *http_process_request(char *url, int method, char **type, int *code, int *size, const char *contype, char *post) {
	struct sockaddr_in serv_addr;
	int sockfd = 0, bytes = 0;
	int has_code = 0, has_type = 0;
	int pos = 0;
	size_t bufsize = BUFFER_SIZE;
	char ip[INET_ADDRSTRLEN+1], *content = NULL, *host = NULL, *auth = NULL, *auth64 = NULL;
	char *page = NULL, *tok = NULL;
	char recvBuff[BUFFER_SIZE+1], *header = MALLOC(bufsize);
	unsigned short port = 0, sslfree = 0, entropyfree = 0;
	size_t len = 0, tlen = 0, plen = 0;

	entropy_context entropy;
	ctr_drbg_context ctr_drbg;
	ssl_context ssl;

	*size = 0;

	if(header == NULL) {
		fprintf(stderr, "out of memory\n");
		exit(EXIT_FAILURE);
	}
	
	memset(header, '\0', bufsize);
	memset(recvBuff, '\0', BUFFER_SIZE+1);
	memset(&serv_addr, '\0', sizeof(struct sockaddr_in));

	/* Check which port we need to use based on the http(s) protocol */
	if(strncmp(url, "http://", 7) == 0) {
		port = 80;
		plen = 8;
	} else if(strncmp(url, "https://", 8) == 0) {
		port = 443;
		plen = 9;
	} else {
		logprintf(LOG_ERR, "an url should start with either http:// or https://", url);
		*code = -1;
		goto exit;
	}

	/* Split the url into a host and page part */
	len = strlen(url);
	if((tok = strstr(&url[plen], "/"))) {
		tlen = (size_t)(tok-url)-plen+1;
		if((host = MALLOC(tlen+1)) == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}
		strncpy(host, &url[plen-1], tlen);
		host[tlen] = '\0';
		if((page = MALLOC(len-tlen)) == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}		
		strcpy(page, &url[tlen+(plen-1)]);
	} else {
		tlen = strlen(url)-(plen-1);
		if((host = MALLOC(tlen+1)) == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}
		strncpy(host, &url[(plen-1)], tlen);
		host[tlen] = '\0';
		if((page = MALLOC(2)) == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}
		strcpy(page, "/");
	}
	if((tok = strstr(host, "@"))) {
		size_t pglen = strlen(page);
		if(strcmp(page, "/") == 0) {
			pglen -= 1;
		}
		tlen = (size_t)(tok-host);
		if((auth = MALLOC(tlen+1)) == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}
		strncpy(auth, &host[0], tlen);
		auth[tlen] = '\0';
		strncpy(&host[0], &url[plen+tlen], len-(plen+tlen+pglen));
		host[len-(plen+tlen+pglen)] = '\0';
		auth64 = base64encode(auth, strlen(auth));
	}

#ifdef _WIN32
	WSADATA wsa;

	if(WSAStartup(0x202, &wsa) != 0) {
		logprintf(LOG_ERR, "could not initialize new socket");
		*code = -1;
		goto exit;
	}
#endif

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		logprintf(LOG_ERR, "could not http create socket");
		*code = -1;
		goto exit;
	}
  setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, 0, 0);

	char *w = ip;
	if(host2ip(host, w) == -1) {
		*code = -1;
		goto exit;
	}

	serv_addr.sin_family = AF_INET;
	if(inet_pton(AF_INET, ip, (void *)(&(serv_addr.sin_addr.s_addr))) <= 0) {
		logprintf(LOG_ERR, "%s is not a valid ip address", ip);
		*code = -1;
		goto exit;
	}
	serv_addr.sin_port = htons(port);

	/* Proper socket timeout testing */
	switch(socket_timeout_connect(sockfd, (struct sockaddr *)&serv_addr, 3)) {
		case -1:
			logprintf(LOG_ERR, "could not connect to http socket (%s)", url);
			*code = -1;
			goto exit;
		case -2:
			logprintf(LOG_ERR, "http socket connection timeout (%s)", url);
			*code = -1;
			goto exit;
		case -3:
			logprintf(LOG_ERR, "error in http socket connection", url);
			*code = -1;
			goto exit;
		default:
		break;
	}

	if(method == HTTP_POST) {
		len = (size_t)snprintf(&header[0], bufsize, "POST %s HTTP/1.0\r\n", page);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "Host: %s\r\n", host);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		if(auth64 != NULL) {
			len += (size_t)snprintf(&header[len], bufsize - len, "Authorization: Basic %s\r\n", auth64);
			if(len >= bufsize) {
				bufsize += BUFFER_SIZE;
				if((header = REALLOC(header, bufsize)) == NULL) {
					fprintf(stderr, "out of memory\n");
					exit(EXIT_FAILURE);
				}
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "User-Agent: %s\r\n", USERAGENT);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "Content-Type: %s\r\n", contype);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "Content-Length: %d\r\n\r\n", (int)strlen(post));
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "%s", post);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
	} else if(method == HTTP_GET) {
		len = (size_t)snprintf(&header[0], bufsize, "GET %s HTTP/1.0\r\n", page);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "Host: %s\r\n", host);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		if(auth64 != NULL) {
			len += (size_t)snprintf(&header[len], bufsize - len, "Authorization: Basic %s\r\n", auth64);
			if(len >= bufsize) {
				bufsize += BUFFER_SIZE;
				if((header = REALLOC(header, bufsize)) == NULL) {
					fprintf(stderr, "out of memory\n");
					exit(EXIT_FAILURE);
				}
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "User-Agent: %s\r\n", USERAGENT);
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
		len += (size_t)snprintf(&header[len], bufsize - len, "Connection: close\r\n\r\n");
		if(len >= bufsize) {
			bufsize += BUFFER_SIZE;
			if((header = REALLOC(header, bufsize)) == NULL) {
				fprintf(stderr, "out of memory\n");
				exit(EXIT_FAILURE);
			}
		}
	}

	if(port == 443) {
		memset(&ssl, '\0', sizeof(ssl_context));
		entropy_init(&entropy);
		entropyfree = 1;
		if((ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, (const unsigned char *)USERAGENT, 6)) != 0) {
			logprintf(LOG_ERR, "ctr_drbg_init failed");
			*code = -1;
			goto exit;
		}

		if((ssl_init(&ssl)) != 0) {
			logprintf(LOG_ERR, "ssl_init failed");
			*code = -1;
			goto exit;
		}
		sslfree = 1;

		ssl_set_endpoint(&ssl, SSL_IS_CLIENT);
		ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg);
		ssl_set_bio(&ssl, net_recv, &sockfd, net_send, &sockfd);

		int ret = 0;
		while((ret = ssl_handshake(&ssl)) != 0) {
			if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
				logprintf(LOG_ERR, "ssl_handshake failed");
				*code = -1;
				goto exit;
			}
		}

		while((ret = ssl_write(&ssl, (const unsigned char *)header, len)) <= 0) {
			if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
				if(ret == -76) {
					logprintf(LOG_ERR, "ssl_write timed out");
				} else {
					logprintf(LOG_ERR, "ssl_write failed");
				}
				*code = -1;
				goto exit;
			}
		}
	} else {
		if((bytes = send(sockfd, header, len, 0)) <= 0) {
			logprintf(LOG_ERR, "sending header to http server failed");
			*code = -1;
			goto exit;
		}
	}

	char *nl = NULL;
	char *tp = *type;
	memset(recvBuff, '\0', sizeof(recvBuff));

	while(1) {
		if(port == 443) {
			bytes = ssl_read(&ssl, (unsigned char *)recvBuff, BUFFER_SIZE);
			if(bytes == POLARSSL_ERR_NET_WANT_READ || bytes == POLARSSL_ERR_NET_WANT_WRITE) {
				continue;
			}
			if(bytes == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) {
				break;
			}
		} else {
			bytes = recv(sockfd, recvBuff, BUFFER_SIZE, 0);
		}

		if(bytes <= 0) {
			if(*size == 0) {
				logprintf(LOG_ERR, "http(s) read failed (%s)", url);
			}
			break;
		}

		if((content = REALLOC(content, (size_t)(*size+bytes+1))) == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}

		memset(&content[*size], '\0', (size_t)(bytes+1));
		strncpy(&content[*size], recvBuff, (size_t)(bytes));
		*size += bytes;

		char **array = NULL;
		char *p = recvBuff;
		/* Let's first normalize the HEADER terminator */
		str_replace("\r\n", "\n\r", &p);
		unsigned int n = explode(recvBuff, "\n\r", &array), q = 0;
		int z = 0;
		for(q=0;q<n;q++) {
			if(has_code == 0 && sscanf(array[q], "HTTP/1.%d%*[ ]%d%*s%*[ \n\r]", &z, code)) {
				has_code = 1;
			}
			// ;%*[ A-Za-z0-9\\/=+- \n\r]
			if(has_type == 0 && sscanf(array[q], "Content-%*[tT]ype:%*[ ]%[A-Za-z\\/+-]", tp)) {
				has_type = 1;
			}
		}
		array_free(&array, n);
		memset(recvBuff, '\0', sizeof(recvBuff));
	}
	if(content != NULL) {
		/* Remove the header */
		if((nl = strstr(content, "\r\n\r\n"))) {
			pos = (nl-content)+4;
			memmove(&content[0], &content[pos], (size_t)(*size-pos));
			*size-=pos;
		}
		/* Remove the footer */
		if((nl = strstr(content, "0\r\n\r\n"))) {
			*size -= 5;
		}
	}

exit:
	if(port == 443) {
		if(sslfree == 1) {
			ssl_free(&ssl);
		}
		if(entropyfree == 1) {
			entropy_free(&entropy);
		}
	}
	if(header) FREE(header);
	if(auth) FREE(auth);
	if(auth64) FREE(auth64);
	if(page) FREE(page);
	if(host) FREE(host);
	if(sockfd > 0) {
		close(sockfd);
	}

	if(*size > 0) {
		content[*size] = '\0';
		return content;
	} else {
		return NULL;
	}
	return NULL;
}
Exemple #15
0
static int
interface_send_packet4(struct interface *iface, struct iovec *iov, int iov_len)
{
	static size_t cmsg_data[( CMSG_SPACE(sizeof(struct in_pktinfo)) / sizeof(size_t)) + 1];
	static struct sockaddr_in a;
	static struct msghdr m = {
		.msg_name = (struct sockaddr *) &a,
		.msg_namelen = sizeof(a),
		.msg_control = cmsg_data,
		.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo)),
	};
	struct in_pktinfo *pkti;
	struct cmsghdr *cmsg;
	int fd = iface->fd.fd;

	a.sin_family = AF_INET;
	a.sin_port = htons(MCAST_PORT);
	m.msg_iov = iov;
	m.msg_iovlen = iov_len;

	memset(cmsg_data, 0, sizeof(cmsg_data));
	cmsg = CMSG_FIRSTHDR(&m);
	cmsg->cmsg_len = m.msg_controllen;
	cmsg->cmsg_level = IPPROTO_IP;
	cmsg->cmsg_type = IP_PKTINFO;

	pkti = (struct in_pktinfo*) CMSG_DATA(cmsg);
	pkti->ipi_ifindex = iface->ifindex;

	a.sin_addr.s_addr = inet_addr(MCAST_ADDR);

	return sendmsg(fd, &m, 0);
}

static int
interface_send_packet6(struct interface *iface, struct iovec *iov, int iov_len)
{
	static size_t cmsg_data[( CMSG_SPACE(sizeof(struct in6_pktinfo)) / sizeof(size_t)) + 1];
	static struct sockaddr_in6 a;
	static struct msghdr m = {
		.msg_name = (struct sockaddr *) &a,
		.msg_namelen = sizeof(a),
		.msg_control = cmsg_data,
		.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo)),
	};
	struct in6_pktinfo *pkti;
	struct cmsghdr *cmsg;
	int fd = iface->fd.fd;

	a.sin6_family = AF_INET6;
	a.sin6_port = htons(MCAST_PORT);
	m.msg_iov = iov;
	m.msg_iovlen = iov_len;

	memset(cmsg_data, 0, sizeof(cmsg_data));
	cmsg = CMSG_FIRSTHDR(&m);
	cmsg->cmsg_len = m.msg_controllen;
	cmsg->cmsg_level = IPPROTO_IPV6;
	cmsg->cmsg_type = IPV6_PKTINFO;

	pkti = (struct in6_pktinfo*) CMSG_DATA(cmsg);
	pkti->ipi6_ifindex = iface->ifindex;

	inet_pton(AF_INET6, MCAST_ADDR6, &a.sin6_addr);

	return sendmsg(fd, &m, 0);
}

int
interface_send_packet(struct interface *iface, struct iovec *iov, int iov_len)
{
	if (debug > 1) {
		fprintf(stderr, "TX ipv%d: %s\n", iface->v6 * 2 + 4, iface->name);
		fprintf(stderr, "  multicast: %d\n", iface->multicast);
	}

	if (iface->v6)
		return interface_send_packet6(iface, iov, iov_len);

	return interface_send_packet4(iface, iov, iov_len);
}

static void interface_close(struct interface *iface)
{
	if (iface->fd.fd < 0)
		return;

	announce_free(iface);
	uloop_fd_delete(&iface->fd);
	close(iface->fd.fd);
	iface->fd.fd = -1;
}

static void interface_free(struct interface *iface)
{
	interface_close(iface);
	free(iface);
}

static int
interface_valid_src(void *ip1, void *mask, void *ip2, int len)
{
	uint8_t *i1 = ip1;
	uint8_t *i2 = ip2;
	uint8_t *m = mask;
	int i;

	if (cfg_no_subnet)
		return 0;

	for (i = 0; i < len; i++, i1++, i2++, m++) {
		if ((*i1 & *m) != (*i2 & *m))
			return -1;
	}

	return 0;
}
int main (int argc, char** argv)
{
    int     	sockfd = 0;
    struct  	sockaddr_in servAddr;
    CYASSL* 	ssl = 0;
    CYASSL_CTX* ctx = 0;
    char        cert_array[]  = "../certs/ca-cert.pem";
    char*       certs = cert_array;

    if (argc != 2) {
        printf("usage: udpcli <IP address>\n");
        return 1;
    }

    CyaSSL_Init();
    /* CyaSSL_Debugging_ON(); */

    if ( (ctx = CyaSSL_CTX_new(CyaDTLSv1_2_client_method())) == NULL) {
        fprintf(stderr, "CyaSSL_CTX_new error.\n");
        return 1;
    }

    if (CyaSSL_CTX_load_verify_locations(ctx, certs, 0)
            != SSL_SUCCESS) {
        fprintf(stderr, "Error loading %s, please check the file.\n", certs);
        return 1;
    }

    ssl = CyaSSL_new(ctx);
    if (ssl == NULL) {
        printf("unable to get ssl object");
        return 1;
    }

    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(SERV_PORT);
    if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) {
        printf("Error and/or invalid IP address");
        return 1;
    }

    CyaSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr));

    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        printf("cannot create a socket.");
        return 1;
    }
    CyaSSL_set_fd(ssl, sockfd);
    if (CyaSSL_connect(ssl) != SSL_SUCCESS) {
        int err1 = CyaSSL_get_error(ssl, 0);
        printf("err = %d, %s\n", err1, CyaSSL_ERR_reason_error_string(err1));
        printf("SSL_connect failed");
        return 1;
    }

    DatagramClient(ssl);

    CyaSSL_shutdown(ssl);
    CyaSSL_free(ssl);
    close(sockfd);
    CyaSSL_CTX_free(ctx);
    CyaSSL_Cleanup();

    return 0;
}
si_item_t *
si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err)
{
	int i, status, want;
	uint32_t if4, if6;
	struct in_addr addr4;
	struct in6_addr addr6;
	si_item_t *item4, *item6;
	build_hostent_t *out;
	struct hostent *h;
	uint64_t unused;

	memset(&addr4, 0, sizeof(struct in_addr));
	memset(&addr6, 0, sizeof(struct in6_addr));

	if (err != NULL) *err = 0;

	if (family == AF_INET)
	{
		status = inet_aton(name, &addr4);
		if (status == 1)
		{
			/* create a host entry */
			item4 = make_hostent(si, name, addr4);
			if (item4 == NULL)
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}

			return item4;
		}
	}
	else if (family == AF_INET6)
	{
		status = inet_pton(family, name, &addr6);
		if (status == 1)
		{
			/* create a host entry */
			item6 = make_hostent6(si, name, addr6);
			if (item6 == NULL)
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}

			return item6;
		}

		status = inet_aton(name, &addr4);
		if (status == 1)
		{
			if (!(flags & (AI_V4MAPPED | AI_V4MAPPED_CFG)))
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
				return NULL;
			}

			addr6.__u6_addr.__u6_addr32[0] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[1] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
			memmove(&(addr6.__u6_addr.__u6_addr32[3]), &(addr4.s_addr), IPV4_ADDR_LEN);

			/* create a host entry */
			item6 = make_hostent6(si, name, addr6);
			if (item6 == NULL)
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}

			return item6;
		}
	}
	else
	{
		if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
		return NULL;
	}

	/*
	 * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
	 */

	if4 = 0;
	if6 = 0;

	if (flags & AI_ADDRCONFIG)
	{
		if (si_inet_config(&if4, &if6) < 0)
		{
			if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
			return NULL;
		}

		/* Bail out if there are no interfaces */
		if ((if4 == 0) && (if6 == 0))
		{
			if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
			return NULL;
		}
	}

	/*
	 * Figure out what we want.
	 * If user asked for AF_INET, we only want V4 addresses.
	 */
	want = WANT_A4_ONLY;

	if (family == AF_INET)
	{
		if ((flags & AI_ADDRCONFIG) && (if4 == 0))
		{
			if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
			return NULL;
		}
	}
	else if (family == AF_INET6)
	{
		/* family == AF_INET6 */
		want = WANT_A6_ONLY;

		if (flags & (AI_V4MAPPED | AI_V4MAPPED_CFG))
		{
			if (flags & AI_ALL)
			{
				want = WANT_A6_PLUS_MAPPED_A4;
			}
			else
			{
				want = WANT_A6_OR_MAPPED_A4_IF_NO_A6;
			}
		}
		else
		{
			if ((flags & AI_ADDRCONFIG) && (if6 == 0)) 
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}
		}
	}
	else
	{
		if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
		return NULL;
	}

	item6 = NULL;
	item4 = NULL;

	/* fetch IPv6 data if required */
	if ((want == WANT_A6_ONLY) || (want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) || (want == WANT_A6_PLUS_MAPPED_A4))
	{
		item6 = si_host_byname(si, name, AF_INET6, interface, (uint32_t *)err);
	}

	/* fetch IPv4 data if required */
	if ((want == WANT_A4_ONLY) || (want == WANT_A6_PLUS_MAPPED_A4) || ((want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) && (item6 == NULL)))
	{
		item4 = si_host_byname(si, name, AF_INET, interface, (uint32_t *)err);
	}

	if (want == WANT_A4_ONLY)
	{
		si_item_release(item6);
		if ((item4 == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
		return item4;
	}

	if (want == WANT_A6_ONLY)
	{
		si_item_release(item4);
		if ((item6 == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
		return item6;
	}

	if ((item6 == NULL) && (item4 == NULL))
	{
		if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
		return NULL;
	}

	/* output item will have IPv6 + mapped IPv4 addresses */

	out = (build_hostent_t *)calloc(1, sizeof(build_hostent_t));
	if (out == NULL)
	{
		si_item_release(item4);
		si_item_release(item6);
		if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
		return NULL;
	}

	if (item4 != NULL)
	{
		h = (struct hostent *)((uintptr_t)item4 + sizeof(si_item_t));

		out->host.h_name = lower_case(h->h_name);

		if (h->h_aliases != NULL)
		{
			for (i = 0; h->h_aliases[i] != NULL; i++) merge_alias(h->h_aliases[i], out);
		}

		for (i = 0; h->h_addr_list[i] != 0; i++)
		{
			addr6.__u6_addr.__u6_addr32[0] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[1] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
			memmove(&(addr6.__u6_addr.__u6_addr32[3]), h->h_addr_list[i], IPV4_ADDR_LEN);
			append_addr((const char *)&addr6, IPV6_ADDR_LEN, out);
		}
	}

	if (item6 != NULL)
	{
		h = (struct hostent *)((uintptr_t)item6 + sizeof(si_item_t));

		if (out->host.h_name == NULL) out->host.h_name = lower_case(h->h_name);

		if (h->h_aliases != NULL)
		{
			for (i = 0; h->h_aliases[i] != NULL; i++) merge_alias(h->h_aliases[i], out);
		}

		for (i = 0; h->h_addr_list[i] != 0; i++) append_addr(h->h_addr_list[i], IPV6_ADDR_LEN, out);
	}

	si_item_release(item4);
	si_item_release(item6);

	unused = 0;

	item6 = (si_item_t *)LI_ils_create("L4488s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, unused, unused, out->host.h_name, out->host.h_aliases, AF_INET6, IPV6_ADDR_LEN, out->host.h_addr_list);

	free_build_hostent(out);

	return item6;
}
Exemple #18
0
/// Checks whether the parameter string consists of a valid IP4 address
/// Requires WinSocket2 library in Windows (ws2_32), not available in Windows XP and below
bool validateAddress(const std::string& address)
{
	unsigned long dummy = 0;
	return 0 != inet_pton(AF_INET, address.c_str(), &dummy);
}
Exemple #19
0
/*%
 * Form update packets.
 * Returns the size of the resulting packet if no error
 *
 * On error,
 *	returns 
 *\li              -1 if error in reading a word/number in rdata
 *		   portion for update packets
 *\li		-2 if length of buffer passed is insufficient
 *\li		-3 if zone section is not the first section in
 *		   the linked list, or section order has a problem
 *\li		-4 on a number overflow
 *\li		-5 unknown operation or no records
 */
int
res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
	ns_updrec *rrecp_start = rrecp_in;
	HEADER *hp;
	u_char *cp, *sp2, *startp, *endp;
	int n, i, soanum, multiline;
	ns_updrec *rrecp;
	struct in_addr ina;
	struct in6_addr in6a;
        char buf2[MAXDNAME];
	u_char buf3[MAXDNAME];
	int section, numrrs = 0, counts[ns_s_max];
	u_int16_t rtype, rclass;
	u_int32_t n1, rttl;
	u_char *dnptrs[20], **dpp, **lastdnptr;
#ifndef _LIBC
	int siglen;
#endif
	int keylen, certlen;

	/*
	 * Initialize header fields.
	 */
	if ((buf == NULL) || (buflen < HFIXEDSZ))
		return (-1);
	memset(buf, 0, HFIXEDSZ);
	hp = (HEADER *) buf;
	hp->id = htons(++statp->id);
	hp->opcode = ns_o_update;
	hp->rcode = NOERROR;
	cp = buf + HFIXEDSZ;
	buflen -= HFIXEDSZ;
	dpp = dnptrs;
	*dpp++ = buf;
	*dpp++ = NULL;
	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];

	if (rrecp_start == NULL)
		return (-5);
	else if (rrecp_start->r_section != S_ZONE)
		return (-3);

	memset(counts, 0, sizeof counts);
	for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) {
		numrrs++;
                section = rrecp->r_section;
		if (section < 0 || section >= ns_s_max)
			return (-1);
		counts[section]++;
		for (i = section + 1; i < ns_s_max; i++)
			if (counts[i])
				return (-3);
		rtype = rrecp->r_type;
		rclass = rrecp->r_class;
		rttl = rrecp->r_ttl;
		/* overload class and type */
		if (section == S_PREREQ) {
			rttl = 0;
			switch (rrecp->r_opcode) {
			case YXDOMAIN:
				rclass = C_ANY;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXDOMAIN:
				rclass = C_NONE;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXRRSET:
				rclass = C_NONE;
				rrecp->r_size = 0;
				break;
			case YXRRSET:
				if (rrecp->r_size == 0)
					rclass = C_ANY;
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		} else if (section == S_UPDATE) {
			switch (rrecp->r_opcode) {
			case DELETE:
				rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
				break;
			case ADD:
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		}

		/*
		 * XXX	appending default domain to owner name is omitted,
		 *	fqdn must be provided
		 */
		if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
				 lastdnptr)) < 0)
			return (-1);
		cp += n;
		ShrinkBuffer(n + 2*INT16SZ);
		PUTSHORT(rtype, cp);
		PUTSHORT(rclass, cp);
		if (section == S_ZONE) {
			if (numrrs != 1 || rrecp->r_type != T_SOA)
				return (-3);
			continue;
		}
		ShrinkBuffer(INT32SZ + INT16SZ);
		PUTLONG(rttl, cp);
		sp2 = cp;  /*%< save pointer to length byte */
		cp += INT16SZ;
		if (rrecp->r_size == 0) {
			if (section == S_UPDATE && rclass != C_ANY)
				return (-1);
			else {
				PUTSHORT(0, sp2);
				continue;
			}
		}
		startp = rrecp->r_data;
		endp = startp + rrecp->r_size - 1;
		/* XXX this should be done centrally. */
		switch (rrecp->r_type) {
		case T_A:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);
			break;
		case T_CNAME:
		case T_MB:
		case T_MG:
		case T_MR:
		case T_NS:
		case T_PTR:
		case ns_t_dname:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_MINFO:
		case T_SOA:
		case T_RP:
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
				return (-1);
				n = dn_comp(buf2, cp, buflen,
					    dnptrs, lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			if (rrecp->r_type == T_SOA) {
				ShrinkBuffer(5 * INT32SZ);
				while (isspace(*startp) || !*startp)
					startp++;
				if (*startp == '(') {
					multiline = 1;
					startp++;
				} else
					multiline = 0;
				/* serial, refresh, retry, expire, minimum */
				for (i = 0; i < 5; i++) {
					soanum = getnum_str(&startp, endp);
					if (soanum < 0)
						return (-1);
					PUTLONG(soanum, cp);
				}
				if (multiline) {
					while (isspace(*startp) || !*startp)
						startp++;
					if (*startp != ')')
						return (-1);
				}
			}
			break;
		case T_MX:
		case T_AFSDB:
		case T_RT:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_SRV:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_PX:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			PUTSHORT(n, cp);
			ShrinkBuffer(INT16SZ);
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				n = dn_comp(buf2, cp, buflen, dnptrs,
					    lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			break;
		case T_WKS: {
			char bm[MAXPORT/8];
			unsigned int maxbm = 0;

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if ((i = res_protocolnumber(buf2)) < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = i & 0xff;
			 
			for (i = 0; i < MAXPORT/8 ; i++)
				bm[i] = 0;

			while (getword_str(buf2, sizeof buf2, &startp, endp)) {
				if ((n = res_servicenumber(buf2)) <= 0)
					return (-1);

				if (n < MAXPORT) {
					bm[n/8] |= (0x80>>(n%8));
					if ((unsigned)n > maxbm)
						maxbm = n;
				} else
					return (-1);
			}
			maxbm = maxbm/8 + 1;
			ShrinkBuffer(maxbm);
			memcpy(cp, bm, maxbm);
			cp += maxbm;
			break;
		}
		case T_HINFO:
			for (i = 0; i < 2; i++) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0)
					return (-1);
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case T_TXT:
			for (;;) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0) {
					if (cp != (sp2 + INT16SZ))
						break;
					return (-1);
				}
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case T_X25:
			/* RFC1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case T_ISDN:
			/* RFC1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if ((n > 255) || (n == 0))
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				n = 0;
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case T_NSAP:
			if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else {
				return (-1);
			}
			break;
		case T_LOC:
			if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else
				return (-1);
			break;
		case ns_t_sig:
#ifdef _LIBC
			return (-1);
#else
		    {
			int sig_type, success, dateerror;
			u_int32_t exptime, timesigned;

			/* type */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			sig_type = sym_ston(__p_type_syms, buf2, &success);
			if (!success || sig_type == ns_t_any)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(sig_type, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* labels */
			n = getnum_str(&startp, endp);
			if (n <= 0 || n > 255)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* ottl  & expire */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			exptime = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(INT32SZ);
				PUTLONG(rttl, cp);
			}
			else {
				char *ulendp;
				u_int32_t ottl;

				errno = 0;
				ottl = strtoul(buf2, &ulendp, 10);
				if (errno != 0 ||
				    (ulendp != NULL && *ulendp != '\0'))
					return (-1);
				ShrinkBuffer(INT32SZ);
				PUTLONG(ottl, cp);
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				exptime = ns_datetosecs(buf2, &dateerror);
				if (dateerror)
					return (-1);
			}
			/* expire */
			ShrinkBuffer(INT32SZ);
			PUTLONG(exptime, cp);
			/* timesigned */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			timesigned = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(INT32SZ);
				PUTLONG(timesigned, cp);
			}
			else
				return (-1);
			/* footprint */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* signer name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			/* sig */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			siglen = b64_pton(buf2, buf3, sizeof(buf3));
			if (siglen < 0)
				return (-1);
			ShrinkBuffer(siglen);
			memcpy(cp, buf3, siglen);
			cp += siglen;
			break;
		    }
#endif
		case ns_t_key:
			/* flags */
			n = gethexnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* proto */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* key */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			keylen = b64_pton(buf2, buf3, sizeof(buf3));
			if (keylen < 0)
				return (-1);
			ShrinkBuffer(keylen);
			memcpy(cp, buf3, keylen);
			cp += keylen;
			break;
		case ns_t_nxt:
		    {
			int success, nxt_type;
			u_char data[32];
			int maxtype;

			/* next name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			maxtype = 0;
			memset(data, 0, sizeof data);
			for (;;) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					break;
				nxt_type = sym_ston(__p_type_syms, buf2,
						    &success);
				if (!success || !ns_t_rr_p(nxt_type))
					return (-1);
				NS_NXT_BIT_SET(nxt_type, data);
				if (nxt_type > maxtype)
					maxtype = nxt_type;
			}
			n = maxtype/NS_NXT_BITS+1;
			ShrinkBuffer(n);
			memcpy(cp, data, n);
			cp += n;
			break;
		    }
		case ns_t_cert:
			/* type */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* key tag */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* cert */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			certlen = b64_pton(buf2, buf3, sizeof(buf3));
			if (certlen < 0)
				return (-1);
			ShrinkBuffer(certlen);
			memcpy(cp, buf3, certlen);
			cp += certlen;
			break;
		case ns_t_aaaa:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (inet_pton(AF_INET6, buf2, &in6a) <= 0)
				return (-1);
			ShrinkBuffer(NS_IN6ADDRSZ);
			memcpy(cp, &in6a, NS_IN6ADDRSZ);
			cp += NS_IN6ADDRSZ;
			break;
		case ns_t_naptr:
			/* Order Preference Flags Service Replacement Regexp */
			/* Order */
			n = getnum_str(&startp, endp);
			if (n < 0 || n > 65535)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* Preference */
			n = getnum_str(&startp, endp);
			if (n < 0 || n > 65535)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* Flags */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Service Classes */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Pattern */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Replacement */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		default:
			return (-1);
		} /*switch*/
Exemple #20
0
int main(int argc,char** argv) {
// vars
// loops
int paramloop;
int loop;

// some miscellaneous vars:
int ret;

// verboselevel
int verboselevel;

// active modules
int modactive[3];

// vars for source and destination ipaddresses and ports
char *s_ipaddress, *d_ipaddress;
int s_port, d_port, d_portincr;
struct in_addr myaddr_bin;
char * myipaddress;

// vars related to receiving data
unsigned char receivebuffer[ETHERNETMTU];
int packetsize;
int udp_packetsize;
int dstar_data_len;

// vars to process streams
int packetsequence;
int direction;
int streamid;
int streamid_instream;

// vars related to sending data
unsigned char sendbuffer[ETHERNETMTU];
struct sockaddr_in6 MulticastOutAddr;

// vars to deal with DSTK frames
dstkheader_str * dstkhead_in, *dstkhead_out;
void * dstkdata;

// dealing with IP, UDP and DSTAR headers
struct iphdr * iphead;
struct udphdr * udphead;
struct dstar_rpc_header * dstar_rpc_head;
unsigned char * dstardata;

struct dstar_dv_rf_header * dv_rf_header;
struct dstar_dv_header * dv_header;
struct dstar_dv_data * dv_data;
uint8_t this_sequence;

char thismodule_c;
int thismodule_i;

int activestatus[3];
int activedirection[3];
u_short activestreamid[3];

// networking vars
int sock_in, sock_out;


// vars for timed interrupts
struct sigaction sa;
struct sigevent sev;
timer_t timerid;
struct itimerspec its;

// ////// data definition done ///


// main program starts here ///
// part 1: initialise vars and check cli-arguments

verboselevel=0;
s_ipaddress=default_s_ipaddress; s_port=default_s_port;
d_ipaddress=default_d_ipaddress; d_port=default_d_port;
d_portincr=default_d_portincr;
myipaddress=default_myipaddress;

modactive[0]=0; modactive[1]=0; modactive[2]=0;

activestatus[0]=0; activestatus[1]=0;activestatus[2]=0;

global.inbound_timeout[0]=0; global.inbound_timeout[1]=0; 
global.inbound_timeout[2]=0; 

// CLI option decoding
// format: rpc2amb [-v ] [-myip ipaddress] [-si ipaddress ] [-sp port] [-di ipaddress] [-dp port ] [-dpi portincease] module ... [module]

for (paramloop=1;paramloop<argc;paramloop++) {
	char * thisarg=argv[paramloop];

	if (strcmp(thisarg,"-V") == 0) {
		// -V = version
		fprintf(stderr,"%s version %s\n",argv[0],VERSION);
		exit(0);
	} else if (strcmp(thisarg,"-h") == 0) {
		// -h = help
		help(argv[0]);
		exit(0);
	} else if (strcmp(thisarg,"-v") == 0) {
		// -v = verbose
		verboselevel++;
	} else if (strcmp(thisarg,"-myip") == 0) {
		// -myip = my ipaddress on interface facing RPC
		if (paramloop+1 < argc) {
			paramloop++;
			myipaddress=argv[paramloop];
		}; // end if
	} else if (strcmp(thisarg,"-si") == 0) {
		// -si = SOURCE ipaddress
		if (paramloop+1 < argc) {
			paramloop++;
			s_ipaddress=argv[paramloop];
		}; // end if
	} else if (strcmp(thisarg,"-sp") == 0) {
		// -si = SOURCE port
		if (paramloop+1 < argc) {
			paramloop++;
			s_port=atoi(argv[paramloop]);
		}; // end if
	} else if (strcmp(thisarg,"-di") == 0) {
		// -di = DESTINATION ipaddress
		if (paramloop+1 < argc) {
			paramloop++;
			d_ipaddress=argv[paramloop];
		}; // end if
	} else if (strcmp(thisarg,"-dp") == 0) {
		// -dp = DESTINATION port
		if (paramloop+1 < argc) {
			paramloop++;
			d_port=atoi(argv[paramloop]);
		}; // end if
	} else if (strcmp(thisarg,"-dpi") == 0) {
		// -dp = DESTINATION port increase
		if (paramloop+1 < argc) {
			paramloop++;
			d_portincr=atoi(argv[paramloop]);
		}; // end if
	} else {
		// modules: can be 'a' up to 'c'
		if ((thisarg[0] == 'a') || (thisarg[0] == 'A')) {
			modactive[0]=1;
		} else if ((thisarg[0] == 'b') || (thisarg[0] == 'B')) {
			modactive[1]=1;
		} else if ((thisarg[0] == 'c') || (thisarg[0] == 'C')) {
			modactive[2]=1;
		} else {
			fprintf(stderr,"Warning: unknown module %c\n",thisarg[0]);
			usage(argv[0]);
		}; // end elsif (...) - if
	}; // end elsif - elsif - elsif - if
}; // end for


// we should have at least one active module
if (!(modactive[0] | modactive[1] | modactive[2])) {
	fprintf(stderr,"Error: At least one active module expected! \n");
	usage(argv[0]);
	exit(-1);
}; // end if

// main program stats here:

// start timed functions

// establing handler for signal 
sa.sa_flags = 0;
sa.sa_handler = funct_heartbeat;
sigemptyset(&sa.sa_mask);

ret=sigaction(SIGRTMIN, &sa, NULL);
if (ret <0) {
	fprintf(stderr,"Error in sigaction!\n");
	exit(-1);
}; // end if

/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = &timerid;

ret=timer_create(CLOCKID, &sev, &timerid);
if (ret < 0) {
	fprintf(stderr,"Error in timer_create!\n");
	exit(-1);
}; // end if

// start timed function, every second
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 1; // immediatly
its.it_interval.tv_sec = 1; // 1 second
its.it_interval.tv_nsec = 0;

ret=timer_settime(timerid, 0, &its, NULL);
if (ret < 0) {
	fprintf(stderr,"Error in timer_settime!\n");
	exit(-1);
}; // end if


// open inbound socket
sock_in=open_and_join_mc(s_ipaddress,s_port,verboselevel);
if (sock_in <= 0) {
	fprintf(stderr,"Error during open_and_join_mc!\n");
	exit(-1);
}; // end if

sock_out=open_for_multicast_out(verboselevel);
if (sock_out <= 0) {
	fprintf(stderr,"Error during open_for_multicast_out!\n");
	exit(-1);
}; // end if 


// convert my own ip-address into binary format
ret=inet_pton(AF_INET,myipaddress,(void *)&myaddr_bin);

// fill in fixed parts of outbound socket
MulticastOutAddr.sin6_family=AF_INET6;
MulticastOutAddr.sin6_scope_id=1;

ret=inet_pton(AF_INET6,d_ipaddress,(void *)&MulticastOutAddr.sin6_addr);
if (ret != 1) {
	fprintf(stderr,"Error: could not convert %s into valid address. Exiting\n",d_ipaddress);
	exit(1);
}; // end if


// init outbuffer
// set pointer dstkheader to beginning of buffer
dstkhead_out = (dstkheader_str *) sendbuffer;
dstkdata = (void *) sendbuffer + sizeof(dstkheader_str);

// fill in fixed parts 
dstkhead_out->version=1;

// this version of this application only contains one single DSTK-subframe
// inside one superframe. So, "last" is set to 1
dstkhead_out->flags = DSTK_FLG_LAST;


streamid=0;
packetsequence=0;

while (forever) {
	// some local vars
	int foundit;
	int giveup;
	int dstkheaderoffset;
	int thisorigin;
 	int otherfound;


	// Start receiving data from multicast stream
	// The payload of the ipv6 multicast-stream are the ipv4
	// UDP packets exchanged by the gateway-server and the
	// repeater controller	
	packetsize=recvfrom(sock_in,receivebuffer,ETHERNETMTU,0,NULL,0);

	if (packetsize == -1) {
		// no data received. Wait 2 ms and try again
		usleep(2000);
		continue;
	}; // end if

	// We should have received at least 20 octets (the size of the DSTK-header)
	if (packetsize < 20) {
		fprintf(stderr,"Packetsize to small! \n");
		continue;
	}; // end if


	// check packet: We should find a DSTK frame:
	foundit=0; giveup=0; dstkheaderoffset=0; otherfound=0;

	while ((! foundit) && (! giveup)) {
		// check DSTK packet header
		dstkhead_in = (dstkheader_str *) (receivebuffer + dstkheaderoffset);

		if (dstkhead_in->version != 1) {
			fprintf(stderr,"DSTK header version 1 expected. Got %d\n",dstkhead_in->version);
			giveup=1;
			break;
		} else if ((ntohl(dstkhead_in->type) & TYPEMASK_FILT_NOFLAGS) == TYPE_RPC_IP) {
			// OK, found Ethernet frames of RPC-stream
			foundit=1;
			break;
		};

		// OK, we found something, but it's not what we are looking for
		otherfound=1;


		// is there another subframe in the DSTK superframe?
		if ( (!(dstkhead_in->flags | DSTK_FLG_LAST))  && (dstkheaderoffset+ntohs(dstkhead_in->size)+sizeof(dstkheader_str) +sizeof(dstk_signature) <= packetsize )) {

			// not yet found, but there is a pointer to a structure further
			// on in the received packet
			// And it is still within the limits of the received packet

			// move up pointer
			dstkheaderoffset+=ntohs(dstkhead_in->size)+sizeof(dstkhead_in->size);

			// check for signature 'DSTK'
			if (memcmp(&receivebuffer[dstkheaderoffset],dstk_signature,sizeof(dstk_signature))) {
				// signature not found: give up
				giveup=1;
			} else {
				// signature found: move up pointer by 4 octets and repeat while-loop
				dstkheaderoffset += sizeof(dstk_signature);
			}; // end if                            

		} else {
			// give up
			giveup=1;
		}; // end else - elsif - elsif - if
	}; // end while

	if (giveup) {
		if (verboselevel >= 1) {
			if (otherfound) {
				fprintf(stderr,"Warning: received packet does not contain RPCIP sub-packet!\n");
			} else {
				fprintf(stderr,"Warning: received packet is not a DSTK packet!\n");
			}; // end else - if
			continue;
		}; // end if
	}; // end if

	// copy streamid
	streamid_instream=dstkhead_in->streamid1; // no need to convert
	// byte-order as we will just pass it on the outgoing stream

	// copy origin
	thisorigin=dstkhead_in->origin; // no need to convert as we just copy it to
	// from the incoming to the outgoing packets

	// sanity-check: check if the packet that has been received is large enough to
	// contain all data (error-check on overloading limits)
	// we are currently at the beginning of the DSTK header, the frame should be at least large
	// enough to hold the DATH header + the IP header + UDP header
	if (packetsize < dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct udphdr) + sizeof(struct iphdr) ) {
		if (verboselevel >= 1) {
			fprintf(stderr,"Warning: received frame is not large enough to contain DSTK_HEADER + IP header + UDP header\n");
		}; // end if
		continue;
	}; // end if


	// we should have received an ipv4 IP-packet with UDP
	iphead = (struct iphdr *) (receivebuffer + dstkheaderoffset + sizeof(dstkheader_str));

	// is it UDP?
	if (iphead->protocol != IPPROTO_UDP) {
		// not UDP
		if (verboselevel >= 1) {
			fprintf(stderr,"Warning: received packet is not a UDP packet!\n");
		}; // end if
		continue;
	}; // end if

	// Determine direction
	// if it send by me?
	ret=bcmp(&iphead->saddr, &myaddr_bin, sizeof(struct in_addr));

	if (ret == 0) {
		direction=1; // outbound
#if DEBUG > 1
fprintf(stderr,"OUTBOUND! \n");
#endif

	} else {
		// was it addressed to me?
		ret=bcmp(&iphead->daddr, &myaddr_bin, sizeof(struct in_addr));

		if (ret == 0) {
#if DEBUG > 1
fprintf(stderr,"INBOUND! \n");
#endif
			direction=0; // inbound
		} else {
			// not send by me or addressed to me. Ignore it
			if (verboselevel >= 1) {
				fprintf(stderr,"Error: received packet is not send by or addressed to me!\n");
			}; // end if
			continue;
		}; // end else - if
	}; // end else - if

	// go to UDP header, fetch length
	udphead = (struct udphdr *) (receivebuffer + dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct iphdr));

	udp_packetsize=ntohs(udphead->len) - 8; // note: udp length includes 8 bytes of the UDP header

	// sanity-check: now we know the size of the UDP-packet, we can verify if the 
	// packet that has been received is large enough to contain all data
	// (error-check on overloading limits)
	// we are currently at the beginning of the DSTK header, the frame should be at least large
	// enough to hold the DATH header + the IP header + UDP header + "udp_packet-size" of data
	if (packetsize < dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct udphdr) + sizeof(struct iphdr) + udp_packetsize ) {
		if (verboselevel >= 1) {
			fprintf(stderr,"Warning: received frame is not large enough to contain DSTK_HEADER + IP header + UDP header\n");
		}; // end if
		continue;
	}; // end if

	// go to dstar header
	dstar_rpc_head = (struct dstar_rpc_header *) (receivebuffer + dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct iphdr) + sizeof(struct udphdr) );


	// the first 4 octets of the header contain "DSTR"
	ret = strncmp("DSTR", (char *) dstar_rpc_head, 4);

	if (ret != 0) {
		// signature not found: not a star header
		if (verboselevel >= 1) {
			fprintf(stderr,"Error: received packet does not contain DSTAR signature\n");
		}; // end if
		continue;
	}; // end if

	// dive further into package
	dstar_data_len = ntohs(dstar_rpc_head->dstar_data_len);
#if DEBUG > 0
	fprintf(stderr,"dstar_data_len = %d \n",dstar_data_len);
#endif

	dstardata=(unsigned char *) (receivebuffer + dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dstar_rpc_header) );




	// dstar_data_len can have the following values:
	// 48: first frame of DV stream
	// 19: normal frame of DV stream
	// 22: extended frame of DV stream (= normal frame + 3 octets at the end)

	// The data-transfer between the gateway-server and repeater-controller
	// happens in two phases:
	// the packet is send by one side. (rs-flag is set to 0x73)
	// after that, the reception of this packet is acknowleged by the remote
	// side (rs-flag is set to 0x72)

	// This program assumes that the exchange between the gateway-server and
	// works OK, so will just take a single-phase approach and ignore the
	// ACK messages 

	if (dstar_rpc_head->dstar_rs_flag == 0x72) {
		if (verboselevel >= 3) {
			fprintf(stderr,"RStype ACK! \n");
		}; // end if
		continue;
	}; // end if

	if (dstar_rpc_head->dstar_rs_flag != 0x73) {
		if (verboselevel >= 2) {
			fprintf(stderr,"NOT TYPE 0x73! \n");
		}; // end if
		continue;
	}; // end if


//fprintf(stderr,"dstar pkt type = %X \n",dstar_rpc_head->dstar_pkt_type);
	if (dstar_rpc_head->dstar_pkt_type != DSTAR_PKT_TYPE_DV) {
		// not a packet used for DV: ignore it
		if (verboselevel >= 2) {
			//fprintf(stderr,"Error: not a DV type packet: %X \n",dstar_rpc_head->dstar_pkt_type);
			fprintf(stderr,"NDV ");
		}; // end if
		continue;
	}; // end if


	// Check size
	if ((dstar_data_len != 19) && (dstar_data_len != 22) && (dstar_data_len != 48)) {
		if (verboselevel >= 1) {
			fprintf(stderr,"Error: Received DV packet has incorrect length: %d\n",dstar_data_len);
		}; // end if
		continue;
	}; // end if


	// set pointers to dv_header
	dv_header=(struct dstar_dv_header *) dstardata;

	// info: status: 0 = no DV stream active, 1 = stream active

#if DEBUG > 1
fprintf(stderr,"dstar_data_len = %d \n",dstar_data_len);
#endif



	// what kind of packet it is?
	// is it a start-of-stream packet
	if (dstar_data_len == 48) {
		// set pointer for rf_header
		dv_rf_header=(struct dstar_dv_rf_header *) (receivebuffer + dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dstar_rpc_header) + sizeof(struct dstar_dv_header) );

		// determine module
		if (direction) {
			// outbound -> module is last character of rpt 2
			thismodule_c=dv_rf_header->rpt2_callsign[7];
		} else {
			// inbound -> compair with last character of rpt 1
			thismodule_c=dv_rf_header->rpt1_callsign[7];
		}; // end if

		if ((thismodule_c == 'A' || thismodule_c == 'a')) {
			thismodule_i=0; thismodule_c='A';
		} else if ((thismodule_c == 'B' || thismodule_c == 'b')) {
			thismodule_i=1; thismodule_c='B';
		} else if ((thismodule_c == 'C' || thismodule_c == 'c')) {
			thismodule_i=2; thismodule_c='C';
		} else {
			fprintf(stderr,"Warning, received stream-start packet does not have valid module-name: %c\n",thismodule_c);
			continue;
		}; // end if

		// if is a module we are interested in?
		if (! (modactive[thismodule_i])) {
			if (verboselevel >= 2) {
				fprintf(stderr,"Message, received packet for module we are not interested in: %d\n",thismodule_i);
			}; // end if
			continue;
		}; // end if

		// accept it when
		// status is 0 (no DV-stream active)
		// or when timeout (additional check to deal with
		// stale sessions where we did not receive an "end-of-stream" packet

		// the "inbound timeout" value is "armed" with 50 in this function and decreased by
		// one in the "serialsend" function. As that function is started every 20 ms, the
		// session will timeout after 1 second.

		if ((activestatus[thismodule_i] == 0) || (global.inbound_timeout[thismodule_i] == 0)) {

			// copy streamid, set frame counter, set status and go to next packet
			if (verboselevel >= 1) {
				fprintf(stderr,"NS%X/%04X \n",direction,dv_header->dv_stream_id);
			}; // end if

			activestreamid[thismodule_i]=dv_header->dv_stream_id;
			activedirection[thismodule_i]=direction;
			activestatus[thismodule_i]=1;

		} else {
			if (verboselevel >= 2) {
				//fprintf(stderr,"Error: DV header received when DV voice-frame expected\n");
				fprintf(stderr,"DVH ");
			}; // end if
			continue;
		}; // end else
	
		// frame is OK, fill in packet-type in header outgoing packet
		if (direction) {
			dstkhead_out->type=htonl(TYPE_AMB_CFG | TYPEMASK_FLG_DIR);
		} else {
			dstkhead_out->type=htonl(TYPE_AMB_CFG);
		}; // end else - if


	} else {
		// DV-data received

		// set pointer for rf_data
		dv_data=(struct dstar_dv_data *) (receivebuffer + dstkheaderoffset + sizeof(dstkheader_str) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dstar_rpc_header) + sizeof(struct dstar_dv_header) );

		thismodule_i=-1;
		// determine module, based on streamid
		for (loop=0;((loop<=2) && (thismodule_i==-1));loop++) {
			if ((modactive[loop]) && (dv_header->dv_stream_id == activestreamid[loop])) {
				thismodule_i=loop;
				thismodule_c=(char) (0x41+loop);
			}; // end if
		}; // end for
			
		if (thismodule_i == -1) {
			if (verboselevel >= 2) {
//				fprintf(stderr,"Warning: received stream not linked to any active streams: %04X\n",dv_header->dv_stream_id);
				fprintf(stderr,"NAS%X/%04X ",direction,dv_header->dv_stream_id);
			}; // end if
			continue;
		};


		// is it the correct direction?
		if (direction != activedirection[thismodule_i]) {
			if (verboselevel >= 1) {
				fprintf(stderr,"Warning: Receiving stream in opposite direction for stream %04X on module %d\n",dv_header->dv_stream_id,thismodule_i);
			}; // end if
			continue;
		}; // end if


		// check sequence number: should be between 0 and 20
		this_sequence=(uint8_t) dv_data->dv_seqnr & 0x1f;

		// error check
		if (this_sequence > 20) {
			if (verboselevel >= 1) {
				fprintf(stderr,"Error: Invalid sequence number received: %d\n",this_sequence);
			}; // end if
			continue;
		}; // end if

		// last frame of stream? (6th bit set?)
		if ((uint8_t) dv_data->dv_seqnr & 0x40) {
			// set status to "off"
			activestatus[thismodule_i]=0;
fprintf(stderr,"ES%04X \n",dv_header->dv_stream_id);
		}; // end if

		// frame is OK, fill in packet-type in header outgoing packet
		if (dstar_data_len == 19) {
			// standard digital voice frame
			if (direction) {
				dstkhead_out->type=htonl(TYPE_AMB_DV | TYPEMASK_FLG_DIR);
			} else {
				dstkhead_out->type=htonl(TYPE_AMB_DV);
			}; // end else - if
		} else {
			// extended digital voice frame (length 22)
			if (direction) {
				dstkhead_out->type=htonl(TYPE_AMB_DVE | TYPEMASK_FLG_DIR);
			} else {
				dstkhead_out->type=htonl(TYPE_AMB_DVE);
			}; // end else - if
		}; // end else - if


	}; // end else - if

	
	// OK, if the packet has not been rejected by all these checkes, re-broadcast it
	// fill in rest of header
	dstkhead_out->seq1=htons(packetsequence);
	dstkhead_out->seq2=0;

	packetsequence++;
	dstkhead_out->streamid1=htons((uint32_t)dv_header->dv_stream_id);
	// streamid2 is copy of streamid1 of incoming 
	dstkhead_out->streamid2=streamid_instream;

	// origin
	dstkhead_out->origin=thisorigin;

	// copy data to dstkdata
	memcpy(dstkdata,dstardata,dstar_data_len);

	// set size
	dstkhead_out->size=htons(dstar_data_len);

	// set port
	MulticastOutAddr.sin6_port=htons((unsigned short int) d_port + thismodule_i * d_portincr);

	// copy data
	ret=sendto(sock_out,dstkhead_out,sizeof(dstkheader_str) + dstar_data_len,0,(struct sockaddr *) &MulticastOutAddr, sizeof(struct sockaddr_in6));
fprintf(stderr,"%c",thismodule_c);

	if (ret < 0) {
		fprintf(stderr,"Warning: sendto fails (error = %d(%s))\n",errno,strerror(errno));
	}; // end if
	global.inbound_timeout[thismodule_i]=3;

}; // end while (forever)


// outside "forever" loop: we should never get here unless something went wrong



return(0);

};
Exemple #21
0
int
tls_process_segment(packet_t *packet, struct tcphdr *tcp)
{
    struct SSLConnection *conn;
    const u_char *payload = packet_payload(packet);
    uint32_t size_payload = packet_payloadlen(packet);
    uint8_t *out;
    uint32_t outl = packet->payload_len;
    out = sng_malloc(outl);
    struct in_addr ip_src, ip_dst;
    uint16_t sport = packet->src.port;
    uint16_t dport = packet->dst.port;

    // Convert addresses
    inet_pton(AF_INET, packet->src.ip, &ip_src);
    inet_pton(AF_INET, packet->dst.ip, &ip_dst);

    // Try to find a session for this ip
    if ((conn = tls_connection_find(ip_src, sport))) {
        // Update last connection direction
        conn->direction = tls_connection_dir(conn, ip_src, sport);

        // Check current connection state
        switch (conn->state) {
            case TCP_STATE_SYN:
                // First SYN received, this package must be SYN/ACK
                if (tcp->th_flags & TH_SYN & ~TH_ACK)
                    conn->state = TCP_STATE_SYN_ACK;
                break;
            case TCP_STATE_SYN_ACK:
                // We expect an ACK packet here
                if (tcp->th_flags & ~TH_SYN & TH_ACK)
                    conn->state = TCP_STATE_ESTABLISHED;
                break;
            case TCP_STATE_ACK:
            case TCP_STATE_ESTABLISHED:
                // Process data segment!
                if (tls_process_record(conn, payload, size_payload, &out, &outl) == 0) {
                    if ((int32_t) outl > 0) {
                        packet_set_payload(packet, out, outl);
                        packet_set_type(packet, PACKET_SIP_TLS);
                        return 0;
                    }
                }
                break;
            case TCP_STATE_FIN:
            case TCP_STATE_CLOSED:
                // We can delete this connection
                tls_connection_destroy(conn);
                break;
        }
    } else {
        if (tcp->th_flags & TH_SYN & ~TH_ACK) {
            // New connection, store it status and leave
            tls_connection_create(ip_src, sport, ip_dst, dport);
        }
    }

    sng_free(out);
    return 0;
}
Exemple #22
0
int main(_unused int argc, char* const argv[])
{
	// Allocate ressources
	const char *pidfile = NULL;
	const char *script = "/usr/sbin/odhcp6c-update";
	ssize_t l;
	uint8_t buf[134];
	char *optpos;
	uint16_t opttype;
	enum odhcp6c_ia_mode ia_na_mode = IA_MODE_TRY;
	enum odhcp6c_ia_mode ia_pd_mode = IA_MODE_TRY;
	static struct in6_addr ifid = IN6ADDR_ANY_INIT;
	int sol_timeout = DHCPV6_SOL_MAX_RT;

#ifdef EXT_BFD_PING
	int bfd_interval = 0, bfd_loss = 3;
#endif

	bool help = false, daemonize = false;
	int logopt = LOG_PID;
	int c, request_pd = 0;
	while ((c = getopt(argc, argv, "S::N:P:FB:c:i:r:s:kt:hedp:")) != -1) {
		switch (c) {
		case 'S':
			allow_slaac_only = (optarg) ? atoi(optarg) : -1;
			break;

		case 'N':
			if (!strcmp(optarg, "force")) {
				ia_na_mode = IA_MODE_FORCE;
				allow_slaac_only = -1;
			} else if (!strcmp(optarg, "none")) {
				ia_na_mode = IA_MODE_NONE;
			} else if (!strcmp(optarg, "try")) {
				ia_na_mode = IA_MODE_TRY;
			} else{
				help = true;
			}
			break;

		case 'P':
			if (allow_slaac_only >= 0 && allow_slaac_only < 10)
				allow_slaac_only = 10;

			request_pd = strtoul(optarg, NULL, 10);
			if (request_pd == 0)
				request_pd = -1;

			break;

		case 'F':
			allow_slaac_only = -1;
			ia_pd_mode = IA_MODE_FORCE;
			break;

#ifdef EXT_BFD_PING
		case 'B':
			bfd_interval = atoi(optarg);
			break;
#endif

		case 'c':
			l = script_unhexlify(&buf[4], sizeof(buf) - 4, optarg);
			if (l > 0) {
				buf[0] = 0;
				buf[1] = DHCPV6_OPT_CLIENTID;
				buf[2] = 0;
				buf[3] = l;
				odhcp6c_add_state(STATE_CLIENT_ID, buf, l + 4);
			} else {
				help = true;
			}
			break;

		case 'i':
			if (inet_pton(AF_INET6, optarg, &ifid) != 1)
				help = true;
			break;

		case 'r':
			optpos = optarg;
			while (optpos[0]) {
				opttype = htons(strtoul(optarg, &optpos, 10));
				if (optpos == optarg)
					break;
				else if (optpos[0])
					optarg = &optpos[1];
				odhcp6c_add_state(STATE_ORO, &opttype, 2);
			}
			break;

		case 's':
			script = optarg;
			break;

		case 'k':
			release = false;
			break;

		case 't':
			sol_timeout = atoi(optarg);
			break;

		case 'e':
			logopt |= LOG_PERROR;
			break;

		case 'd':
			daemonize = true;
			break;

		case 'p':
			pidfile = optarg;
			break;

		default:
			help = true;
			break;
		}
	}

	openlog("odhcp6c", logopt, LOG_DAEMON);
	const char *ifname = argv[optind];

	if (help || !ifname)
		return usage();

	signal(SIGIO, sighandler);
	signal(SIGHUP, sighandler);
	signal(SIGINT, sighandler);
	signal(SIGCHLD, sighandler);
	signal(SIGTERM, sighandler);
	signal(SIGUSR1, sighandler);
	signal(SIGUSR2, sighandler);

	if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 ||
			init_dhcpv6(ifname, request_pd, sol_timeout) ||
			ra_init(ifname, &ifid) || script_init(script, ifname)) {
		syslog(LOG_ERR, "failed to initialize: %s", strerror(errno));
		return 3;
	}

	if (daemonize) {
		openlog("odhcp6c", LOG_PID, LOG_DAEMON); // Disable LOG_PERROR
		if (daemon(0, 0)) {
			syslog(LOG_ERR, "Failed to daemonize: %s",
					strerror(errno));
			return 4;
		}

		char pidbuf[128];
		if (!pidfile) {
			snprintf(pidbuf, sizeof(pidbuf),
					"/var/run/odhcp6c.%s.pid", ifname);
			pidfile = pidbuf;
		}

		int fd = open(pidfile, O_WRONLY | O_CREAT);
		if (fd >= 0) {
			char buf[8];
			int len = snprintf(buf, sizeof(buf), "%i\n", getpid());
			write(fd, buf, len);
			close(fd);
		}
	}

	script_call("started");

	while (do_signal != SIGTERM) { // Main logic
		odhcp6c_clear_state(STATE_SERVER_ID);
		odhcp6c_clear_state(STATE_IA_NA);
		odhcp6c_clear_state(STATE_IA_PD);
		odhcp6c_clear_state(STATE_SNTP_IP);
		odhcp6c_clear_state(STATE_SNTP_FQDN);
		odhcp6c_clear_state(STATE_SIP_IP);
		odhcp6c_clear_state(STATE_SIP_FQDN);
		dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode);
		bound = false;

		syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);

		do_signal = 0;
		int mode = dhcpv6_request(DHCPV6_MSG_SOLICIT);
		odhcp6c_signal_process();

		if (mode < 0)
			continue;

		do {
			int res = dhcpv6_request(mode == DHCPV6_STATELESS ?
					DHCPV6_MSG_INFO_REQ : DHCPV6_MSG_REQUEST);

			odhcp6c_signal_process();
			if (res > 0)
				break;
			else if (do_signal > 0) {
				mode = -1;
				break;
			}

			mode = dhcpv6_promote_server_cand();
		} while (mode > DHCPV6_UNKNOWN);

		if (mode < 0)
			continue;

		switch (mode) {
		case DHCPV6_STATELESS:
			bound = true;
			syslog(LOG_NOTICE, "entering stateless-mode on %s", ifname);

			while (do_signal == 0 || do_signal == SIGUSR1) {
				do_signal = 0;
				script_call("informed");					

				int res = dhcpv6_poll_reconfigure();
				odhcp6c_signal_process();

				if (res > 0)
					continue;

				if (do_signal == SIGUSR1) {
					do_signal = 0; // Acknowledged
					continue;
				} else if (do_signal > 0)
					break;

				res = dhcpv6_request(DHCPV6_MSG_INFO_REQ);
				odhcp6c_signal_process();
				if (do_signal == SIGUSR1)
					continue;
				else if (res < 0)
					break;
			}
			break;

		case DHCPV6_STATEFUL:
			script_call("bound");
			bound = true;
			syslog(LOG_NOTICE, "entering stateful-mode on %s", ifname);
#ifdef EXT_BFD_PING
			if (bfd_interval > 0)
				bfd_start(ifname, bfd_loss, bfd_interval);
#endif

			while (do_signal == 0 || do_signal == SIGUSR1) {
				// Renew Cycle
				// Wait for T1 to expire or until we get a reconfigure
				int res = dhcpv6_poll_reconfigure();
				odhcp6c_signal_process();
				if (res > 0) {
					script_call("updated");
					continue;
				}

				// Handle signal, if necessary
				if (do_signal == SIGUSR1)
					do_signal = 0; // Acknowledged
				else if (do_signal > 0)
					break; // Other signal type

				// Send renew as T1 expired
				size_t ia_pd_len, ia_na_len;
				odhcp6c_get_state(STATE_IA_PD, &ia_pd_len);
				odhcp6c_get_state(STATE_IA_NA, &ia_na_len);

				// If we have any IAs, send renew, otherwise request
				if (ia_pd_len == 0 && ia_na_len == 0)
					res = dhcpv6_request(DHCPV6_MSG_REQUEST);
				else
					res = dhcpv6_request(DHCPV6_MSG_RENEW);

				odhcp6c_signal_process();
				if (res > 0) { // Renew was succesfull
					// Publish updates
					script_call("updated");
					continue; // Renew was successful
				}
				
				odhcp6c_clear_state(STATE_SERVER_ID); // Remove binding

				// If we have IAs, try rebind otherwise restart
				res = dhcpv6_request(DHCPV6_MSG_REBIND);
				odhcp6c_signal_process();

				if (res > 0)
					script_call("rebound");
				else {
#ifdef EXT_BFD_PING
					bfd_stop();
#endif
					break;
				}
			}
			break;

		default:
			break;
		}

		size_t ia_pd_len, ia_na_len, server_id_len;
		odhcp6c_get_state(STATE_IA_PD, &ia_pd_len);
		odhcp6c_get_state(STATE_IA_NA, &ia_na_len);
		odhcp6c_get_state(STATE_SERVER_ID, &server_id_len);

		// Add all prefixes to lost prefixes
		bound = false;
		script_call("unbound");

		if (server_id_len > 0 && (ia_pd_len > 0 || ia_na_len > 0) && release)
			dhcpv6_request(DHCPV6_MSG_RELEASE);

		odhcp6c_clear_state(STATE_IA_NA);
		odhcp6c_clear_state(STATE_IA_PD);
	}

	script_call("stopped");
	return 0;
}
static void
sendquery(isc_task_t *task, isc_event_t *event) {
	struct in_addr inaddr;
	isc_sockaddr_t address;
	isc_region_t r;
	isc_result_t result;
	dns_fixedname_t keyname;
	dns_fixedname_t ownername;
	isc_buffer_t namestr, keybuf;
	unsigned char keydata[9];
	dns_message_t *query;
	dns_request_t *request;
	static char keystr[] = "0123456789ab";

	isc_event_free(&event);

	result = ISC_R_FAILURE;
	if (inet_pton(AF_INET, "10.53.0.1", &inaddr) != 1)
		CHECK("inet_pton", result);
	isc_sockaddr_fromin(&address, &inaddr, PORT);

	dns_fixedname_init(&keyname);
	isc_buffer_constinit(&namestr, "tkeytest.", 9);
	isc_buffer_add(&namestr, 9);
	result = dns_name_fromtext(dns_fixedname_name(&keyname), &namestr,
				   NULL, 0, NULL);
	CHECK("dns_name_fromtext", result);

	dns_fixedname_init(&ownername);
	isc_buffer_constinit(&namestr, ownername_str, strlen(ownername_str));
	isc_buffer_add(&namestr, strlen(ownername_str));
	result = dns_name_fromtext(dns_fixedname_name(&ownername), &namestr,
				   NULL, 0, NULL);
	CHECK("dns_name_fromtext", result);

	isc_buffer_init(&keybuf, keydata, 9);
	result = isc_base64_decodestring(keystr, &keybuf);
	CHECK("isc_base64_decodestring", result);

	isc_buffer_usedregion(&keybuf, &r);

	initialkey = NULL;
	result = dns_tsigkey_create(dns_fixedname_name(&keyname),
				    DNS_TSIG_HMACMD5_NAME,
				    isc_buffer_base(&keybuf),
				    isc_buffer_usedlength(&keybuf),
				    ISC_FALSE, NULL, 0, 0, mctx, ring,
				    &initialkey);
	CHECK("dns_tsigkey_create", result);

	query = NULL;
	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
	CHECK("dns_message_create", result);

	result = dns_tkey_builddhquery(query, ourkey,
				       dns_fixedname_name(&ownername),
				       DNS_TSIG_HMACMD5_NAME, &nonce, 3600);
	CHECK("dns_tkey_builddhquery", result);

	request = NULL;
	result = dns_request_create(requestmgr, query, &address,
				    DNS_REQUESTOPT_TCP, initialkey,
				    TIMEOUT, task, recvquery, query,
				    &request);
	CHECK("dns_request_create", result);
}
Exemple #24
0
/**
 * @brief Start the storage server.
 *
 * This is the main entry point for the storage server.  It reads the
 * configuration file, starts listening on a port, and proccesses
 * commands from clients.
 */
int main(int argc, char *argv[])
{


	Table database[MAX_DATABASE_LEN];

	//printf("Setting time\n");//remove
	  time ( &rawtime );
	  timeinfo2 = localtime ( &rawtime );
	  //printf("Finished rawtime stuff\n"); //remove

	  //printf("About to do strftime\n"); //remove
	  strftime (buffer2,40,"Server-%Y-%m-%d-%H-%M-%S.log",timeinfo2);
	  puts (buffer2);
	  //printf("Finished setting time\n");//remove

	// Process command line arguments.
	// This program expects exactly one argument: the config file name.
	assert(argc > 0);
	if (argc != 2) {
		printf("Usage %s <config_file>\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	char *config_file = argv[1];

	// Read the config file.
	struct config_params params;
	int status = read_config(config_file, &params);
	if (status != 0) {
		printf("Error processing config file.\n");
		exit(EXIT_FAILURE);
	}

	n = sprintf(message, "Server on %s:%d\n", params.server_host, params.server_port);
	//printf("%i", n);
	fp = fopen(buffer2, "a+");
	logger(LOGGING, fp, message);
	fclose(fp);

	// Create a socket.
	int listensock = socket(PF_INET, SOCK_STREAM, 0);
	if (listensock < 0) {
		printf("Error creating socket.\n");
		exit(EXIT_FAILURE);
	}

	// Allow listening port to be reused if defunct.
	int yes = 1;
	status = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
	if (status != 0) {
		printf("Error configuring socket.\n");
		exit(EXIT_FAILURE);
	}

	// Bind it to the listening port.
	struct sockaddr_in listenaddr;
	memset(&listenaddr, 0, sizeof listenaddr);
	listenaddr.sin_family = AF_INET;
	listenaddr.sin_port = htons(params.server_port);
	inet_pton(AF_INET, params.server_host, &(listenaddr.sin_addr)); // bind to local IP address
	status = bind(listensock, (struct sockaddr*) &listenaddr, sizeof listenaddr);
	if (status != 0) {
		printf("Error binding socket.\n");
		exit(EXIT_FAILURE);
	}

	// Listen for connections.
	status = listen(listensock, MAX_LISTENQUEUELEN);
	if (status != 0) {
		printf("Error listening on socket.\n");
		exit(EXIT_FAILURE);
	}

	// Listen loop.
	int wait_for_connections = 1;
	while (wait_for_connections) {
		// Wait for a connection.
		struct sockaddr_in clientaddr;
		socklen_t clientaddrlen = sizeof clientaddr;
		int clientsock = accept(listensock, (struct sockaddr*)&clientaddr, &clientaddrlen);
		if (clientsock < 0) {
			printf("Error accepting a connection.\n");
			exit(EXIT_FAILURE);
		}
		n = sprintf(message, "Got a connection from %s:%d.\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
		fp = fopen(buffer2, "a+");
		logger(LOGGING, fp, message);
		fclose(fp);

		// Get commands from client.
		int wait_for_commands = 1;
		do {
			// Read a line from the client.
			char cmd[MAX_CMD_LEN];
			int status = recvline(clientsock, cmd, MAX_CMD_LEN);
			if (status != 0) {
				// Either an error occurred or the client closed the connection.
				wait_for_commands = 0;
			} else {
				// Handle the command from the client.
				int status = handle_command(clientsock, cmd, database, params.username, params.password);
				if (status != 0)
					wait_for_commands = 0; // Oops.  An error occured.
			}
		} while (wait_for_commands);

		// Close the connection with the client.
		close(clientsock);
		n = sprintf(message, "Closed connection from %s:%d.\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
		fp = fopen(buffer2, "a+");
		logger(LOGGING, fp, message);
		fclose(fp);
	}

	// Stop listening for connections.
	close(listensock);

	return EXIT_SUCCESS;
}
Exemple #25
0
/****************************************************************************
 * Name: ReceiveTimeout
 *
 * Description:
 *   Blocking connect and receive with SO_RCVTIMEO
 *
 * Input Parameters:
 *   dconf - socket daemon configuration
 *
 * Returned Value:
 *   None
 *
 * Assumptions/Limitations:
 *   None
 *
 ****************************************************************************/
static void ReceiveTimeout(struct usrsocktest_daemon_conf_s *dconf)
{
  ssize_t ret;
  size_t datalen;
  void *data;
  struct sockaddr_in addr;
  char databuf[5];
  struct timeval tv;

  /* Start test daemon. */

  dconf->endpoint_addr = "127.0.0.1";
  dconf->endpoint_port = 255;
  dconf->endpoint_block_connect = true;
  dconf->endpoint_block_send = true;
  dconf->endpoint_recv_avail_from_start = false;
  dconf->endpoint_recv_avail = 7;
  TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
  started = true;
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());

  /* Open socket */

  sd = socket(AF_INET, SOCK_STREAM, 0);
  TEST_ASSERT_TRUE(sd >= 0);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Do connect, should succeed (after connect block released). */

  inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
  addr.sin_family = AF_INET;
  addr.sin_port = htons(255);
  TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
  ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
  TEST_ASSERT_EQUAL(0, ret);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Setup recv timeout. */

  tv.tv_sec = 0;
  tv.tv_usec = 100 * 1000;
  ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv,
                   sizeof(tv));
  TEST_ASSERT_EQUAL(0, ret);

  /* Receive data from remote */

  data = databuf;
  datalen = sizeof(databuf);
  ret = recvfrom(sd, data, datalen, 0, NULL, 0);
  TEST_ASSERT_EQUAL(-1, ret);
  TEST_ASSERT_EQUAL(ETIMEDOUT, errno);
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes());
  TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());

  /* Close socket */

  TEST_ASSERT_TRUE(close(sd) >= 0);
  sd = -1;
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());

  /* Stopping daemon should succeed. */

  TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
  started = false;
  TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
  TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
  TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
  TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
Exemple #26
0
/***************************************************************************
  Function: push_to_cloud
  Description: 
  Input: mt
            action_str
            old_str
            new_str
  Output: none
  Return: 0:receive status[1(if modifypassword) or 2(if modifyalias)]            
              positive:receive status[(-9,-10)(if modifypassword) or (-11,-12,-13)(if modifyalias)]
              negative:other error
  Others:  none
***************************************************************************/
static int push_to_cloud(modifyType mt, const char *action_str, const char *old_str, const char *new_str)
{
    cJSON *send_json, *receive_json, *status_json;
    char *json_send_out;
	char send_str[CA_PUSH_TO_CLOUD_LEN], receive_str[CA_PUSH_TO_CLOUD_LEN];
	int fd, nwrite, nread, re, nfd;
	struct sockaddr_in	servaddr;

	// Section1: prepare for push
    send_json = cJSON_CreateObject();
	if (!send_json) {
		CA_DEBUG("create send_json failed\n");
		return -1;
	}
	cJSON_AddStringToObject(send_json, "action", action_str);
	switch (mt) {
		case modifyPasswordType:
			cJSON_AddStringToObject(send_json, "old_password", old_str);
			cJSON_AddStringToObject(send_json, "new_password", new_str);
			break;
		case modifyAliasType:
			cJSON_AddStringToObject(send_json, "old_alias", old_str);
			cJSON_AddStringToObject(send_json, "new_alias", new_str);
			break;
		default:
			CA_DEBUG("undefined modifyType:%d\n", mt);
			cJSON_Delete(send_json);
			return -1;
	}
    if ( (json_send_out = cJSON_PrintUnformatted(send_json)) == 0 ) {
		CA_DEBUG("%d print send_json failed\n", mt);
		cJSON_Delete(send_json);
		return -1;
    }
	
    cJSON_Delete(send_json);	
    nwrite = snprintf(send_str, CA_PUSH_TO_CLOUD_LEN, "%s", json_send_out);
	nwrite += 1; // including the terminated null 
    free(json_send_out);

    // Section2: send and receive
    // reWrite the next line
	//fd = Tcp_connect("192.168.1.121", FEATURE_GDGL_CPROXY_CA_PUSH_PORT_STR);
	if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
        CA_DEBUG("%d socket error\n", mt);
		return -2;
	}
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(FEATURE_GDGL_CPROXY_CA_PUSH_PORT);
	//if ( (re = inet_pton(AF_INET, "192.168.1.238", &servaddr.sin_addr)) <= 0) {
	if ( (re = inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr)) <= 0) {
		CA_DEBUG("%d inet_pton error:%d\n", mt, re);
		close(fd);
		return -2;
	}	
	if ( connect(fd, (SA *) &servaddr, sizeof(servaddr)) < 0 ) {
		CA_DEBUG("%d connect error\n", mt);
		close(fd);
		return -2;
	}	
	
    if ( writen(fd, send_str, nwrite) != nwrite ) {
		CA_DEBUG("%d write error\n", mt);
		close(fd);
		return -2;
    }

    if ( (nfd = readable_timeo(fd, PUSH_TO_CLOUD_TIMEOUT)) < 0) {
		CA_DEBUG("%d readable_timeo error\n", mt);
		close(fd);
		return -2;
	}
	else if (nfd == 0) { //timeout, close connection
		CA_DEBUG("%d readable_timeo timeout\n", mt);
		close(fd);
		return -2;
	}

	while (1) {
	    if ( (nread = read(fd, receive_str, CA_PUSH_TO_CLOUD_LEN - 1)) < 0) {
			if (errno == EINTR) 
				continue;
			else {
		        CA_DEBUG("%d read error\n", mt);
		        close(fd);
		        return -2;
			}
	    }
		else if (nread == 0) {
			CA_DEBUG("%d closed by other end\n", mt);
		    close(fd);
		    return -2;
		}
		else
			break;
	}
	close(fd);
	receive_str[nread] = 0; // add the terminated null 
	CA_DEBUG("%d receive:\n%s\n", mt, receive_str);

	// Section3: parse result
	receive_json = cJSON_Parse(receive_str);
	if (!receive_json) {
		CA_DEBUG("%d receive_json parse Error before:%s\n", mt, cJSON_GetErrorPtr());
		return -3;
	}

   	status_json = cJSON_GetObjectItem(receive_json, "status");
	if (!status_json) {
		cJSON_Delete(receive_json);
		CA_DEBUG("%d receive no status\n", mt);
		return -3;
	}
    if (status_json->type != cJSON_Number) {		
		CA_DEBUG("%d receive status but not a number\n", mt);
		cJSON_Delete(receive_json);
		return -3;
	}
	switch (status_json->valueint) {
		case PUSH_TO_CLOUD_RESPONSE_JSON_PARSE_FAILED:
			CA_DEBUG("%d receive [json parse failed]\n", mt);
		    cJSON_Delete(receive_json);
		    return -3;

		case PUSH_TO_CLOUD_RESPONSE_REQ_HANDLER_INVALID:
			CA_DEBUG("%d receive [request handler invalid]\n", mt);
		    cJSON_Delete(receive_json);
		    return -3;

		case PUSH_TO_CLOUD_RESPONSE_INVALID_ACTION:
			CA_DEBUG("%d receive [invalid action]\n", mt);
		    cJSON_Delete(receive_json);
		    return -3;
			
		case PUSH_TO_CLOUD_RESPONSE_UNKNOWN_ACTION:
			CA_DEBUG("%d receive [unknown action]\n", mt);
		    cJSON_Delete(receive_json);
		    return -3;
									
		default:
			break;
	}
	if (mt == modifyPasswordType) {
	    switch (status_json->valueint) {
		    case PUSH_TO_CLOUD_RESPONSE_PASSWD_SUCCESS:
			    cJSON_Delete(receive_json);
	            return 0;

		    case PUSH_TO_CLOUD_RESPONSE_INVALID_OLD_PASSWD:
			    CA_DEBUG("%d receive [invalid old_password]\n", mt);
		        cJSON_Delete(receive_json);
		        return -3;

		    case PUSH_TO_CLOUD_RESPONSE_INVALID_NEW_PASSWD:
			    CA_DEBUG("%d receive [invalid new_password]\n", mt);
		        cJSON_Delete(receive_json);
		        return -3;
						
		    case PUSH_TO_CLOUD_RESPONSE_OLD_PASSWD_ERR:
			    CA_DEBUG("%d receive [old password not correct]\n", mt);
		        cJSON_Delete(receive_json);
		        return clientAdminPushToCloudOldPasswdErr;
			
		    case PUSH_TO_CLOUD_RESPONSE_PASSWD_SAME:
			    CA_DEBUG("%d receive [same passwords]\n", mt);
		        cJSON_Delete(receive_json);
		        return clientAdminPushToCloudPasswdSame;
						
		    default:
			    CA_DEBUG("%d receive unsupported status:[%d]\n", mt, status_json->valueint);
		        cJSON_Delete(receive_json);
		        return -3;
	    }
	}
	else if (mt == modifyAliasType) {
	    switch (status_json->valueint) {
		    case PUSH_TO_CLOUD_RESPONSE_ALIAS_SUCCESS:
			    cJSON_Delete(receive_json);
	            return 0;
			    				
		    case PUSH_TO_CLOUD_RESPONSE_INVALID_OLD_ALIAS:
			    CA_DEBUG("%d receive [invalid old_alias]\n", mt);
		        cJSON_Delete(receive_json);
		        return -3;

		    case PUSH_TO_CLOUD_RESPONSE_INVALID_NEW_ALIAS:
			    CA_DEBUG("%d receive [invalid new_alias]\n", mt);
		        cJSON_Delete(receive_json);
		        return -3;
						
		    case PUSH_TO_CLOUD_RESPONSE_OLD_ALIAS_NOT_EXIST:
			    CA_DEBUG("%d receive [old alias not exist]\n", mt);
		        cJSON_Delete(receive_json);
		        return clientAdminPushToCloudOldAliasNotExist;
			
		    case PUSH_TO_CLOUD_RESPONSE_NEW_ALIAS_EXIST:
			    CA_DEBUG("%d receive [new alias already exist]\n", mt);
		        cJSON_Delete(receive_json);
		        return clientAdminPushToCloudNewAliasExist;
			
		    case PUSH_TO_CLOUD_RESPONSE_ALIAS_SAME:
			    CA_DEBUG("%d receive [same aliases]\n", mt);
		        cJSON_Delete(receive_json);
		        return clientAdminPushToCloudAliasSame;
			
		    default:
			    CA_DEBUG("%d receive unsupported status:[%d]\n", mt, status_json->valueint);
		        cJSON_Delete(receive_json);
		        return -3;
	    }
	}
	else {
		CA_DEBUG("undefined modifyType:%d\n", mt);
		cJSON_Delete(receive_json);
		return -3;
	}
}
Exemple #27
0
/*
 * RFC2428 states...
 *
 *     AF Number   Protocol 
 *     ---------   --------         
 *     1           Internet Protocol, Version 4 
 *     2           Internet Protocol, Version 6 
 *     
 *     AF Number   Address Format      Example         
 *     ---------   --------------      -------         
 *     1           dotted decimal      132.235.1.2         
 *     2           IPv6 string         1080::8:800:200C:417A                     
 *                 representations                     
 *                 defined in 
 *     
 *     The following are sample EPRT commands:         
 *          EPRT |1|132.235.1.2|6275|         
 *          EPRT |2|1080::8:800:200C:417A|5282|
 *     
 *     The first command specifies that the server should use IPv4 to open a    
 *     data connection to the host "132.235.1.2" on TCP port 6275.  The    
 *     second command specifies that the server should use the IPv6 network    
 *     protocol and the network address "1080::8:800:200C:417A" to open a    
 *     TCP data connection on port 5282.
 * 
 * ... which means in fact that RFC2428 is capable to handle both, 
 * IPv4 and IPv6 so we have to care about the address family and properly
 * act depending on it.
 * 
 */
static gboolean
parse_eprt_request(const guchar* line, gint linelen, guint32 *eprt_af, 
        guint32 *eprt_ip, guint16 *eprt_ipv6, guint16 *ftp_port, 
        guint32 *eprt_ip_len, guint32 *ftp_port_len) 
{
    gint      delimiters_seen = 0;
    gchar     delimiter;
    gint      fieldlen;
    gchar    *field;
    gint      n;
    gint      lastn;
    char     *args, *p;
    gboolean  ret = TRUE;


    if (!line)
        return FALSE;
    /* Copy the rest of the line into a null-terminated buffer. */
    args = ep_strndup(line, linelen);
    p = args;

    /*
     * RFC2428 sect. 2 states ...
     * 
     *     The EPRT command keyword MUST be followed by a single space (ASCII
     *     32). Following the space, a delimiter character (<d>) MUST be
     *     specified.
     *
     * ... the preceding <space> is already stripped so we know that the first
     * character must be the delimiter and has just to be checked to be valid.
     */
    if (!isvalid_rfc2428_delimiter(*p))
        return FALSE;  /* EPRT command does not follow a vaild delimiter;
                        * malformed EPRT command - immediate escape */

    delimiter = *p; 
    /* Validate that the delimiter occurs 4 times in the string */
    for (n = 0; n < linelen; n++) {
        if (*(p+n) == delimiter) 
            delimiters_seen++;
    }
    if (delimiters_seen != 4)
        return FALSE; /* delimiter doesn't occur 4 times 
                       * probably no EPRT request - immediate escape */

    /* we know that the first character is a delimiter... */
    delimiters_seen = 1;
    lastn = 0;
    /* ... so we can start searching from the 2nd onwards */
    for (n=1; n < linelen; n++) {

        if (*(p+n) != delimiter)
            continue;

        /* we found a delimiter */
        delimiters_seen++;

        fieldlen = n - lastn - 1;
        if (fieldlen<=0)
            return FALSE; /* all fields must have data in them */
        field =  p + lastn + 1;

        if (delimiters_seen == 2) {     /* end of address family field */
            gchar *af_str;
            af_str = ep_strndup(field, fieldlen);
            *eprt_af = atoi(af_str);
        }
        else if (delimiters_seen == 3) {/* end of IP address field */
            gchar *ip_str;
            ip_str = ep_strndup(field, fieldlen);

            if (*eprt_af == EPRT_AF_IPv4) {
                if (inet_pton(AF_INET, ip_str, eprt_ip) == 1)
                   ret = TRUE;
                else
                   ret = FALSE;
            }
            else if (*eprt_af == EPRT_AF_IPv6) {
                if (inet_pton(AF_INET6, ip_str, eprt_ipv6) == 1)
                   ret = TRUE;
                else
                   ret = FALSE;
            }
            else
                return FALSE; /* invalid/unknown address family */

            *eprt_ip_len = fieldlen;
        }
        else if (delimiters_seen == 4) {/* end of port field */
            gchar *pt_str;
            pt_str = ep_strndup(field, fieldlen);

            *ftp_port = atoi(pt_str);
            *ftp_port_len = fieldlen;
        }

        lastn = n;
    }

    return ret;
}
Exemple #28
0
NOEXPORT int getaddrinfo(const char *node, const char *service,
        const struct addrinfo *hints, struct addrinfo **res) {
    struct hostent *h;
#ifndef _WIN32_WCE
    struct servent *p;
#endif
    u_short port;
    struct addrinfo *ai;
    int retval;
    char *tmpstr;

    if(!node)
        node=hints->ai_flags&AI_PASSIVE ? DEFAULT_ANY : DEFAULT_LOOPBACK;
#if defined(USE_WIN32) && !defined(_WIN32_WCE)
    if(s_getaddrinfo)
        return s_getaddrinfo(node, service, hints, res);
#endif
    /* decode service name */
    port=htons((u_short)strtol(service, &tmpstr, 10));
    if(tmpstr==service || *tmpstr) { /* not a number */
#ifdef _WIN32_WCE
        return EAI_NONAME;
#else /* defined(_WIN32_WCE) */
        p=getservbyname(service, "tcp");
        if(!p)
            return EAI_NONAME;
        port=(u_short)p->s_port;
#endif /* defined(_WIN32_WCE) */
    }

    /* allocate addrlist structure */
    ai=str_alloc(sizeof(struct addrinfo));
    if(hints)
        memcpy(ai, hints, sizeof(struct addrinfo));

    /* try to decode numerical address */
#if defined(USE_IPv6) && !defined(USE_WIN32)
    ai->ai_family=AF_INET6;
    ai->ai_addrlen=sizeof(struct sockaddr_in6);
    ai->ai_addr=str_alloc((size_t)ai->ai_addrlen);
    ai->ai_addr->sa_family=AF_INET6;
    if(inet_pton(AF_INET6, node,
            &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr)>0) {
#else
    ai->ai_family=AF_INET;
    ai->ai_addrlen=sizeof(struct sockaddr_in);
    ai->ai_addr=str_alloc(ai->ai_addrlen);
    ai->ai_addr->sa_family=AF_INET;
    ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr=inet_addr(node);
    if(((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr+1) {
    /* (signed)((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr!=-1 */
#endif
        ((struct sockaddr_in *)ai->ai_addr)->sin_port=port;
        *res=ai;
        return 0; /* numerical address resolved */
    }
    str_free(ai->ai_addr);
    str_free(ai);

    /* not numerical: need to call resolver library */
    *res=NULL;
    ai=NULL;
    CRYPTO_w_lock(stunnel_locks[LOCK_INET]);
#ifdef HAVE_GETHOSTBYNAME2
    h=gethostbyname2(node, AF_INET6);
    if(h) /* some IPv6 addresses found */
        alloc_addresses(h, hints, port, res, &ai); /* ignore the error */
#endif
    h=gethostbyname(node); /* get list of addresses */
    if(h)
        retval=ai ?
            alloc_addresses(h, hints, port, &ai->ai_next, &ai) :
            alloc_addresses(h, hints, port, res, &ai);
    else if(!*res)
        retval=EAI_NONAME; /* no results */
    else
        retval=0;
#ifdef HAVE_ENDHOSTENT
    endhostent();
#endif
    CRYPTO_w_unlock(stunnel_locks[LOCK_INET]);
    if(retval) { /* error: free allocated memory */
        freeaddrinfo(*res);
        *res=NULL;
    }
    return retval;
}

NOEXPORT int alloc_addresses(struct hostent *h, const struct addrinfo *hints,
        u_short port, struct addrinfo **head, struct addrinfo **tail) {
    int i;
    struct addrinfo *ai;

    /* copy addresses */
    for(i=0; h->h_addr_list[i]; i++) {
        ai=str_alloc(sizeof(struct addrinfo));
        if(hints)
            memcpy(ai, hints, sizeof(struct addrinfo));
        ai->ai_next=NULL; /* just in case */
        if(*tail) { /* list not empty: add a node */
            (*tail)->ai_next=ai;
            *tail=ai;
        } else { /* list empty: create it */
            *head=ai;
            *tail=ai;
        }
        ai->ai_family=h->h_addrtype;
#if defined(USE_IPv6)
        if(h->h_addrtype==AF_INET6) {
            ai->ai_addrlen=sizeof(struct sockaddr_in6);
            ai->ai_addr=str_alloc((size_t)ai->ai_addrlen);
            memcpy(&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
                h->h_addr_list[i], (size_t)h->h_length);
        } else
#endif
        {
            ai->ai_addrlen=sizeof(struct sockaddr_in);
            ai->ai_addr=str_alloc((size_t)ai->ai_addrlen);
            memcpy(&((struct sockaddr_in *)ai->ai_addr)->sin_addr,
                h->h_addr_list[i], (size_t)h->h_length);
        }
        ai->ai_addr->sa_family=(u_short)h->h_addrtype;
        /* offsets of sin_port and sin6_port should be the same */
        ((struct sockaddr_in *)ai->ai_addr)->sin_port=port;
    }
    return 0; /* success */
}
Exemple #29
0
/**
 * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests
 * specifying ip and port sources and destinations
 *
 * \param payload pointer to the payloadd buffer
 * \param payload_len pointer to the length of the payload
 * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP
 * \param src pointer to a string containing the ip source
 * \param dst pointer to a string containing the ip destination
 * \param sport pointer to a string containing the port source
 * \param dport pointer to a string containing the port destination
 *
 * \retval Packet pointer to the built in packet
 */
Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len,
                           uint8_t ipproto, char *src, char *dst,
                           uint16_t sport, uint16_t dport)
{
    struct in_addr in;

    Packet *p = PacketGetFromAlloc();
    if (unlikely(p == NULL))
        return NULL;

    struct timeval tv;
    TimeGet(&tv);
    COPY_TIMESTAMP(&tv, &p->ts);

    p->src.family = AF_INET;
    p->dst.family = AF_INET;
    p->payload = payload;
    p->payload_len = payload_len;
    p->proto = ipproto;

    if (inet_pton(AF_INET, src, &in) != 1)
        goto error;
    p->src.addr_data32[0] = in.s_addr;
    p->sp = sport;

    if (inet_pton(AF_INET, dst, &in) != 1)
        goto error;
    p->dst.addr_data32[0] = in.s_addr;
    p->dp = dport;

    p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p);
    if (p->ip4h == NULL)
        goto error;

    p->ip4h->s_ip_src.s_addr = p->src.addr_data32[0];
    p->ip4h->s_ip_dst.s_addr = p->dst.addr_data32[0];
    p->ip4h->ip_proto = ipproto;
    p->ip4h->ip_verhl = sizeof(IPV4Hdr);
    p->proto = ipproto;

    int hdr_offset = sizeof(IPV4Hdr);
    switch (ipproto) {
        case IPPROTO_UDP:
            p->udph = (UDPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
            if (p->udph == NULL)
                goto error;

            p->udph->uh_sport = sport;
            p->udph->uh_dport = dport;
            hdr_offset += sizeof(UDPHdr);
            break;
        case IPPROTO_TCP:
            p->tcph = (TCPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
            if (p->tcph == NULL)
                goto error;

            p->tcph->th_sport = htons(sport);
            p->tcph->th_dport = htons(dport);
            hdr_offset += sizeof(TCPHdr);
            break;
        case IPPROTO_ICMP:
            p->icmpv4h = (ICMPV4Hdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
            if (p->icmpv4h == NULL)
                goto error;

            hdr_offset += sizeof(ICMPV4Hdr);
            break;
        default:
            break;
        /* TODO: Add more protocols */
    }

    if (payload && payload_len) {
        PacketCopyDataOffset(p, hdr_offset, payload, payload_len);
    }
    SET_PKT_LEN(p, hdr_offset + payload_len);
    p->payload = GET_PKT_DATA(p)+hdr_offset;

    return p;

error:
    SCFree(p);
    return NULL;
}
Exemple #30
0
int main(int argc, char *argv[])
{
    struct sockaddr_in srv;
    int sock_fd, chk, con_fd;
    pthread_attr_t attr;

    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("socket error!");
        return -1;
    }

    bzero(&srv, sizeof(srv));
    srv.sin_family = AF_INET;
    srv.sin_port = htons(_port_);

    /* inet_pton: support ipv6 and ipv4, set the ipaddr */
    if (inet_pton(AF_INET, _addr_, &srv.sin_addr) < 0)
    {
        printf("inet_pton error!");
        return -1;
    }

    chk = bind(sock_fd, (struct sockaddr*)&srv, sizeof(srv));
    if (chk < 0)
    {
        printf("bind error!");
        return -1;
    }

    chk = listen(sock_fd, MAX_LISTEN_QUEUE);
    if (chk < 0)
    {
        printf("listen error!");
        return -1;
    }

    /* 初始化线程参数 */
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    cli_que_len = 0;
    while (1)
    {
        con_fd = accept(sock_fd, (struct sockaddr*)NULL, NULL);
        printf("a client connected!\n");
        
        /* get the nickname of the client */
        cli[cli_que_len].con_fd = con_fd;
        printf("fd = %d\n", con_fd);
        strcpy(cli[cli_que_len].nick, "f**k");

        /* create server thread for a new client */
        chk = pthread_create(cli_thrd + cli_que_len, &attr, recv_thrd, cli + cli_que_len);
        if (chk)
        {
            printf("create thread error!");
            continue;
        }
        ++cli_que_len;
    }
    close(sock_fd);

    return 0;
}