Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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));
}