int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_) { // Find the ':' at end that separates address from the port number. const char *delimiter = strrchr (name_, ':'); if (!delimiter) { errno = EINVAL; return -1; } // Separate the address/port. std::string addr_str (name_, delimiter - name_); std::string port_str (delimiter + 1); // Remove square brackets around the address, if any. if (addr_str.size () >= 2 && addr_str [0] == '[' && addr_str [addr_str.size () - 1] == ']') addr_str = addr_str.substr (1, addr_str.size () - 2); uint16_t port; // Allow 0 specifically, to detect invalid port error in atoi if not if (port_str == "*" || port_str == "0") // Resolve wildcard to 0 to allow autoselection of port port = 0; else { // Parse the port number (0 is not a valid port). port = (uint16_t) atoi (port_str.c_str ()); if (port == 0) { errno = EINVAL; return -1; } } // Resolve the IP address. int rc; if (local_) rc = resolve_interface (addr_str.c_str (), ipv4only_); else rc = resolve_hostname (addr_str.c_str (), ipv4only_); if (rc != 0) return -1; // Set the port into the address structure. if (address.generic.sa_family == AF_INET6) address.ipv6.sin6_port = htons (port); else address.ipv4.sin_port = htons (port); return 0; }
int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_, bool is_src_) { if (!is_src_) { // Test the ';' to know if we have a source address in name_ const char *src_delimiter = strrchr (name_, ';'); if (src_delimiter) { std::string src_name (name_, src_delimiter - name_); const int rc = resolve (src_name.c_str (), local_, ipv6_, true); if (rc != 0) return -1; name_ = src_delimiter + 1; _has_src_addr = true; } } // Find the ':' at end that separates address from the port number. const char *delimiter = strrchr (name_, ':'); if (!delimiter) { errno = EINVAL; return -1; } // Separate the address/port. std::string addr_str (name_, delimiter - name_); std::string port_str (delimiter + 1); // Remove square brackets around the address, if any, as used in IPv6 if (addr_str.size () >= 2 && addr_str [0] == '[' && addr_str [addr_str.size () - 1] == ']') addr_str = addr_str.substr (1, addr_str.size () - 2); // Test the '%' to know if we have an interface name / zone_id in the address // Reference: https://tools.ietf.org/html/rfc4007 std::size_t pos = addr_str.rfind("%"); uint32_t zone_id = 0; if (pos != std::string::npos) { std::string if_str = addr_str.substr(pos + 1); addr_str = addr_str.substr(0, pos); if (isalpha (if_str.at (0))) zone_id = if_nametoindex(if_str.c_str()); else zone_id = (uint32_t) atoi (if_str.c_str ()); if (zone_id == 0) { errno = EINVAL; return -1; } } // Allow 0 specifically, to detect invalid port error in atoi if not uint16_t port; if (port_str == "*" || port_str == "0") // Resolve wildcard to 0 to allow autoselection of port port = 0; else { // Parse the port number (0 is not a valid port). port = (uint16_t) atoi (port_str.c_str ()); if (port == 0) { errno = EINVAL; return -1; } } // Resolve the IP address. int rc; if (local_ || is_src_) rc = resolve_interface (addr_str.c_str (), ipv6_, is_src_); else rc = resolve_hostname (addr_str.c_str (), ipv6_, is_src_); if (rc != 0) return -1; // Set the port into the address structure. if (is_src_) { if (source_address.generic.sa_family == AF_INET6) { source_address.ipv6.sin6_port = htons (port); source_address.ipv6.sin6_scope_id = zone_id; } else source_address.ipv4.sin_port = htons (port); } else { if (address.generic.sa_family == AF_INET6) { address.ipv6.sin6_port = htons (port); address.ipv6.sin6_scope_id = zone_id; } else address.ipv4.sin_port = htons (port); } return 0; }
static int send_netflow_v5(const struct pfsync_state *st, u_int n, u_int *flows_exp) { char now_s[64]; int i, j, offset, num_packets, err; socklen_t errsz; struct NF5_FLOW *flw = NULL; struct NF5_HEADER *hdr = NULL; struct timeval now_tv; struct tm now_tm; time_t now; u_int32_t uptime_ms; u_int8_t packet[NF5_MAXPACKET_SIZE]; #ifdef NF9 int src_idx, dst_idx; #endif #if __FreeBSD_version > 900000 const struct pfsync_state_key *nk; #endif if (verbose_flag) { now = time(NULL); localtime_r(&now, &now_tm); strftime(now_s, sizeof(now_s), "%Y-%m-%dT%H:%M:%S", &now_tm); } gettimeofday(&now_tv, NULL); uptime_ms = timeval_sub_ms(&now_tv, &start_time); hdr = (struct NF5_HEADER *)packet; for(num_packets = offset = j = i = 0; i < n; i++) { struct pf_state_host src, dst; u_int32_t bytes_in, bytes_out, packets_in, packets_out; u_int32_t creation; char src_s[64], dst_s[64], rt_s[64], pbuf[16], creation_s[64]; time_t creation_tt; struct tm creation_tm; if (netflow_socket != -1 && j >= NF5_MAXFLOWS - 1) { if (verbose_flag) { syslog(LOG_DEBUG, "Sending flow packet len = %d", offset); } hdr->flows = htons(hdr->flows); errsz = sizeof(err); getsockopt(netflow_socket, SOL_SOCKET, SO_ERROR, &err, &errsz); /* Clear ICMP errors */ if (send(netflow_socket, packet, (size_t)offset, 0) == -1) { syslog(LOG_DEBUG, "send: %s", strerror(errno)); return -1; } j = 0; num_packets++; } if (netflow_socket != -1 && j == 0) { memset(&packet, '\0', sizeof(packet)); hdr->version = htons(5); hdr->flows = 0; /* Filled in as we go */ hdr->uptime_ms = htonl(uptime_ms); hdr->time_sec = htonl(now_tv.tv_sec); hdr->time_nanosec = htonl(now_tv.tv_usec * 1000); hdr->flow_sequence = htonl(*flows_exp); /* Other fields are left zero */ offset = sizeof(*hdr); } if (st[i].af != AF_INET) continue; if (direction != 0 && st[i].direction != direction) continue; /* Copy/convert only what we can eat */ creation = ntohl(st[i].creation) * 1000; if (creation > uptime_ms) creation = uptime_ms; /* Avoid u_int wrap */ #if __FreeBSD_version > 900000 if (st[i].direction == PF_OUT) { nk = &st[i].key[PF_SK_WIRE]; } else { nk = &st[i].key[PF_SK_STACK]; } src.addr = nk->addr[1]; src.port = nk->port[1]; dst.addr = nk->addr[0]; dst.port = nk->port[0]; #else if (st[i].direction == PF_OUT) { memcpy(&src, &st[i].lan, sizeof(src)); memcpy(&dst, &st[i].ext, sizeof(dst)); } else { memcpy(&src, &st[i].ext, sizeof(src)); memcpy(&dst, &st[i].lan, sizeof(dst)); } #endif #ifdef NF9 src_idx = resolve_interface(&src.addr, st[i].af); dst_idx = resolve_interface(&dst.addr, st[i].af); #endif flw = (struct NF5_FLOW *)(packet + offset); #ifdef NF9 if (netflow_socket != -1 && st[i].packets[0][1] != 0) #else if (netflow_socket != -1 && st[i].packets[0][0] != 0) #endif { flw->src_ip = src.addr.v4.s_addr; flw->dest_ip = dst.addr.v4.s_addr; flw->src_port = src.port; flw->dest_port = dst.port; #ifdef NF9 flw->flow_packets = st[i].packets[0][1]; flw->flow_octets = st[i].bytes[0][1]; flw->if_index_in = htons(src_idx); flw->if_index_out= htons(dst_idx); #else flw->flow_packets = st[i].packets[0][0]; flw->flow_octets = st[i].bytes[0][0]; #endif flw->flow_start = htonl(uptime_ms - creation); flw->flow_finish = htonl(uptime_ms); flw->tcp_flags = 0; flw->protocol = st[i].proto; offset += sizeof(*flw); j++; hdr->flows++; } flw = (struct NF5_FLOW *)(packet + offset); #ifdef NF9 if (netflow_socket != -1 && st[i].packets[1][1] != 0) #else if (netflow_socket != -1 && st[i].packets[1][0] != 0) #endif { flw->src_ip = dst.addr.v4.s_addr; flw->dest_ip = src.addr.v4.s_addr; flw->src_port = dst.port; flw->dest_port = src.port; #ifdef NF9 flw->flow_packets = st[i].packets[1][1]; flw->flow_octets = st[i].bytes[1][1]; flw->if_index_in = htons(dst_idx); flw->if_index_out= htons(src_idx); #else flw->flow_packets = st[i].packets[1][0]; flw->flow_octets = st[i].bytes[1][0]; #endif flw->flow_start = htonl(uptime_ms - creation); flw->flow_finish = htonl(uptime_ms); flw->tcp_flags = 0; flw->protocol = st[i].proto; offset += sizeof(*flw); j++; hdr->flows++; } flw = (struct NF5_FLOW *)(packet + offset); if (verbose_flag) { #ifdef NF9 packets_out = ntohl(st[i].packets[0][1]); packets_in = ntohl(st[i].packets[1][1]); bytes_out = ntohl(st[i].bytes[0][1]); bytes_in = ntohl(st[i].bytes[1][1]); #else packets_out = ntohl(st[i].packets[0][0]); packets_in = ntohl(st[i].packets[1][0]); bytes_out = ntohl(st[i].bytes[0][0]); bytes_in = ntohl(st[i].bytes[1][0]); #endif creation_tt = now - (creation / 1000); localtime_r(&creation_tt, &creation_tm); strftime(creation_s, sizeof(creation_s), "%Y-%m-%dT%H:%M:%S", &creation_tm); format_pf_host(src_s, sizeof(src_s), &src, st[i].af); format_pf_host(dst_s, sizeof(dst_s), &dst, st[i].af); inet_ntop(st[i].af, &st[i].rt_addr, rt_s, sizeof(rt_s)); if (st[i].proto == IPPROTO_TCP || st[i].proto == IPPROTO_UDP) { snprintf(pbuf, sizeof(pbuf), ":%d", ntohs(src.port)); strlcat(src_s, pbuf, sizeof(src_s)); snprintf(pbuf, sizeof(pbuf), ":%d", ntohs(dst.port)); strlcat(dst_s, pbuf, sizeof(dst_s)); } syslog(LOG_DEBUG, "IFACE %s", st[i].ifname); syslog(LOG_DEBUG, "GWY %s", rt_s); syslog(LOG_DEBUG, "FLOW proto %d direction %d", st[i].proto, st[i].direction); syslog(LOG_DEBUG, "\tstart %s(%u) finish %s(%u)", creation_s, uptime_ms - creation, now_s, uptime_ms); syslog(LOG_DEBUG, "\t%s -> %s %d bytes %d packets", src_s, dst_s, bytes_out, packets_out); syslog(LOG_DEBUG, "\t%s -> %s %d bytes %d packets", dst_s, src_s, bytes_in, packets_in); } } /* Send any leftovers */ if (netflow_socket != -1 && j != 0) { if (verbose_flag) { syslog(LOG_DEBUG, "Sending flow packet len = %d", offset); } hdr->flows = htons(hdr->flows); errsz = sizeof(err); getsockopt(netflow_socket, SOL_SOCKET, SO_ERROR, &err, &errsz); /* Clear ICMP errors */ if (send(netflow_socket, packet, (size_t)offset, 0) == -1) { syslog(LOG_DEBUG, "send: %s", strerror(errno)); return -1; } num_packets++; } return (ntohs(hdr->flows)); }