Softflowd source and destination interface id as 0



  • We are trying to analyze the network traffic of each interface. After we installed the softflowd package we ran a Wireshark capture and found that softflowd shows every interface id as 0.

    I attached an image of one flow captured with wireshark.

    When we ran the snmpwalk command, we can see every id of each interface:

    snmpwalk -v 2c -c ****** -O n 172.25.255.253:161 .1.3.6.1.2.1.2.2.1.2 | sed s/'.1.3.6.1.2.1.2.2.1.2.'// | sed s/'STRING: '//
    1 = vr0
    2 = vr1
    3 = vr2
    4 = enc0
    5 = pfsync0
    6 = pflog0
    7 = lo0
    8 = vr0_vlan2
    9 = vr0_vlan4
    10 = vr0_vlan255

    When we were investigating the cause, we found some lines in the softflowd code that may be the problem.

    case 'i':
      if (capfile != NULL || dev != NULL) {
        fprintf(stderr, "Packet source already "
            "specified.\n\n");
        usage();
        exit(1);
      }
      dev = strsep(&optarg, ":");
      if (optarg != NULL) {
        if_index = (u_int16_t) atoi(dev);
        dev = optarg;
      }
      if (verbose_flag)
        fprintf(stderr, "Using %s (idx: %d)\n", dev, if_index);
      break;

    Any ideas on how could we solve this problem?



  • (necro'd because this is the only relevant thread I could find about this issue, and Google results are forever - if I found searching for this issue, someone else will too)

    I'm experiencing this same thing 3 years later, on pfSense 2.3.4 - no matter what interface(s) I assign softflowd to, the output in the collector is always "if 0" for every flow. Has anyone gotten around this? I'd really like to analyze my netflow data by interface (especially since softflowd doesn't provide a way to send different interfaces to different collector ports…)



  • Well I was able to somewhat figure this out. It looks like OP was completely on the right track - the code in that section looks correct, but in any *BSD/Linux/etc. system it's getting tripped up because the interface name is not a pure number. As a result, the atoi() function returns 0 consistently, instead of some value which differentiates the interfaces.

    I made a custom patch to the package in order to output something unique. This probably isn't safe (I blindly assume we have strsep() without a macro for one), so I'm not going to send it upstream, but it worked out for me. It instead uses the individual characters of the interface name to generate a unique ~5-digit integer which can be used easily for filtering. To find out an interface's numerical representation, I just run softflowd -i <name> with no other args, which prints the info and crashes.

    Hope this helps someone!

    
    --- softflowd.c.orig    2017-04-25 22:26:07.000000000 +0000
    +++ softflowd.c 2017-08-03 07:31:41.194232000 +0000
    @@ -1781,17 +1781,12 @@
                                    usage();
                                    exit(1);
                            }
    -#if defined(HAVE_STRSEP)
                            dev = strsep(&optarg, ":");
    -#else /* defined(HAVE_STRSEP) */
    -                       dev = strtok(optarg, ":");
    -#endif /* defined(HAVE_STRSEP) */
    -                       if (optarg != NULL) {
    -                               if_index = (u_int16_t) atoi(dev);
    -                               dev = optarg;
    +                       int len = strlen(dev);
    +                       for(i=0; i<len; i++){<br="">+                               if_index = if_index * 10 + ( dev[i] - '0' );
                            }
    -                       if (verbose_flag)
    -                               fprintf(stderr, "Using %s (idx: %d)\n", dev, if_index);
    +                       fprintf(stderr, "Using %s (idx: %d)\n", dev, if_index);
                            break;
                    case 'r':
                            if (capfile != NULL || dev != NULL) {
    [/i]</len;>
    ```</name>

Log in to reply