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); }
/**************************************************************************** * 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); }
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; }
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); } }
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; }
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; }
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); }
/* 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; }
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); }
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 ? : ""); }
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(×tamp, NULL); memcpy(pingdata, ×tamp, 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; }
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; }
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; }
/// 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); }
/*% * 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*/
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); };
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; }
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); }
/** * @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, ¶ms); 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; }
/**************************************************************************** * 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); }
/*************************************************************************** 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; } }
/* * 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; }
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 */ }
/** * \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; }
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, "fuck"); /* 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; }