コード例 #1
0
ファイル: utility_test.c プロジェクト: kazuyas/trema
static void
test_hash_mac() {
  uint8_t mac1[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  uint8_t mac2[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

  assert_true( hash_mac( mac1 ) == hash_mac( mac2 ) );
}
コード例 #2
0
ファイル: match_table.c プロジェクト: Milstein/trema
static unsigned int
hash_exact_match_entry( const void *key ) {
  assert( key != NULL );
  const struct ofp_match *match = key;

  uint16_t dl_vlan = match->dl_vlan;
  if ( dl_vlan != UINT16_MAX ) {
    dl_vlan = ( uint16_t ) ( dl_vlan & VLAN_VID_MASK );
  }
  uint8_t dl_vlan_pcp = ( uint8_t ) ( match->dl_vlan_pcp & VLAN_PCP_MASK );
  uint8_t nw_tos = ( uint8_t ) ( match->nw_tos & NW_TOS_MASK );

  unsigned int hash = 0;
  hash ^= ( unsigned int ) ( match->in_port << 16 );
  hash ^= ( unsigned int ) hash_mac( match->dl_src );
  hash ^= ( unsigned int ) hash_mac( match->dl_dst );
  hash ^= dl_vlan;
  hash ^= ( unsigned int ) ( dl_vlan_pcp << 24 );
  hash ^= ( unsigned int ) ( match->dl_type << 8 );
  hash ^= nw_tos;
  hash ^= ( unsigned int ) ( match->nw_proto << 24 );
  hash ^= match->nw_src;
  hash ^= match->nw_dst;
  hash ^= ( unsigned int ) ( match->tp_src << 16 );
  hash ^= match->tp_dst;

  return hash;
}
コード例 #3
0
ファイル: match_table.c プロジェクト: n-tada/trema
static unsigned int
hash_match_entry( const void *key ) {
  const struct ofp_match *ofp_match = key;
  unsigned int hash = 0;

  assert( ofp_match->wildcards == 0 );

  hash ^= ( unsigned int ) ( ofp_match->in_port << 16 );
  hash ^= ( unsigned int ) hash_mac( ofp_match->dl_src );
  hash ^= ( unsigned int ) hash_mac( ofp_match->dl_dst );
  hash ^= ofp_match->dl_vlan;
  hash ^= ( unsigned int ) ( ofp_match->dl_vlan_pcp << 24 );
  hash ^= ( unsigned int ) ( ofp_match->dl_type << 8 );
  hash ^= ofp_match->nw_tos;
  hash ^= ( unsigned int ) ( ofp_match->nw_proto << 24 );
  hash ^= ofp_match->nw_src;
  hash ^= ofp_match->nw_dst;
  hash ^= ( unsigned int ) ( ofp_match->tp_src << 16 );
  hash ^= ofp_match->tp_dst;

  return hash;
}
コード例 #4
0
ファイル: learning_switch.c プロジェクト: Milstein/trema
unsigned int
hash_forwarding_entry( const void *key ) {
  return hash_mac( ( ( const struct key * ) key )->mac );
}
コード例 #5
0
ファイル: mac.c プロジェクト: jkrauska/prads
/* load_mac: fill **macp with mac_entry
 *
 * sigp is a pointer to either
 ** a pointer to a preallocated buffer of size max_sigs * fp_entry OR
 ** a NULL pointer indicating that we should allocate max_sigs for you
 * max_sigs is the maximal size of the buffer, or 0 in which case we decide
 *
 * Theory:   snarf sigs in serially, easypeasy
 *
 * returns errno
 */
int load_mac(const char *file, mac_entry **sigp[], int hashsize)
{
    mac_entry **sig; // output
    uint32_t ln = 0;
    uint32_t sigcnt = 0;
    //debug("opening %s\n", file);
    FILE *f = fopen(file, "r");
    char buf[MAXLINE];
    char *p;
    if (!f) {
        perror("failed to open file");
        return errno;
    }
    if(!sigp) {
        fclose(f);
        perror("need a pointer to fill");
        return -1;
    }
    if(!hashsize)
        hashsize = MAC_HASHSIZE;
    if(*sigp == NULL) {
        *sigp = calloc(hashsize, sizeof(mac_entry *));
        sig = *sigp;
    }

    // read a line at a time and load it into the hash.
    while ((p = fgets(buf, sizeof(buf), f))) {
        mac_entry entry = {{0}}; //guarantee it's empty
        uint32_t l, lp;
        uint8_t octet = 0;
        char vendor[128] = {0};
        char *comment = 0;

        mac_entry *e;

        ln++;

        /* Remove leading and trailing blanks */
        SKIP_SPACES(p);
        l = strlen(p);
        while (l && isspace(*(p + l - 1)))
            *(p + (l--) - 1) = 0;

        /* Skip empty lines and comments */
        if (!l)
            continue;
        if (*p == '#')
            continue;

        /* first part: mac address */
        while (*p && !isspace(*p))
        {
            if (isxdigit(*p) && isxdigit(*(p+1))) {
                //mac.o[octet++] = strtol(p,&(p+1), 16);
                sscanf(p, "%2hhx", &entry.o[octet]);
                octet++;
                p += 2;
                continue;
            } else if (*p == '-' || *p == ':') {
                p++;
                continue;
            } else if (*p == '/') {
                // mac mask
                entry.mask = strtol(p+1, NULL, 10);
                p += 2;
                continue;
            } // else
            p++; // skip unknown chars...
        }
        SKIP_SPACES(p);
        /* second part: vendor */
        sscanf(p, "%127s", vendor);
        // scan forward..
        while (*p && !isspace(*p))
            p++;
        SKIP_SPACES(p);

        /* third part, #comment (optional) */
        if(*p == '#') {
            /* chomp it first */
            p++;
            SKIP_SPACES(p);
            lp = strlen(p);

            while (lp && isspace(*(p + lp - 1)))
                *(p + (lp--) - 1) = 0;

            /* then copy the comment */
            comment = calloc(1, lp + 1);
            strncpy(comment, p, lp);
        }

        /* roll hash */
        entry.vendor = strdup(vendor);
        entry.comment = comment;

        // if there is no mask, all octets count
        if(!entry.mask)
            entry.mask = octet * 8; //48 - octet * 8;

        int index = hash_mac(entry.o, octet);
        e = sig[index];

        if (!e) {
            sig[index] = alloc_mac(&entry);
        } else {
            int cc = 0;
            // collision!
            while (e->next) {
                e = e->next;
                cc++;
            }
            /*
            printf("hash collision %d: at index %d\n", cc, index);
            print_mac(&entry);
            */
            e->next = alloc_mac(&entry);
        }
        sigcnt++;
    }

    fclose(f);
#ifdef DEBUG_HASH
    {
        int i,max;
        mac_entry *p;
        printf("Hash table layout: ");
        max = 0;
        for (i = 0; i < MAC_HASHSIZE; i++) {
            int z = 0;
            p = sig[i];
            while (p) {
                p = p->next;
                z++;
            }
            max = (max > z)? max : z;
            printf("%d ", z);

        }
        putchar('\n');
        printf ("max : %d\n", max);
    }
#endif                          /* DEBUG_HASH */

    if (!sigcnt)
        debug("[!] WARNING: no signatures loaded from config file.\n");
    else
        dlog("%d sigs from %d lines\n", sigcnt, ln);

    return 0;
}
コード例 #6
0
ファイル: mac.c プロジェクト: jkrauska/prads
/* match mac with vendor list
 * most specific match first.
 *
 * how does this grab ya:
 * aa:bb:cc:dd:ee:ff matches
 * aa:bb:cc:d0/26
 * .. by searching upward from
 * aa:bb:cc:00
 */
mac_entry *match_mac(mac_entry **db, const uint8_t mac[], uint8_t mask)
{
    uint32_t index = hash_mac(mac, mask / 8);
    uint8_t r,i,ditch = 0;
    /* debug
    if(mask == 48) {
       print_mac(mac);
       printf("/%d match\n", mask);
    } */
    if(db == NULL) return NULL; // database not loaded!


    if(mask == 0)
        return NULL; // oopsy we run out of matches.

    // hash will only get us so far, we must search the rest of the way
    mac_entry *match = db[index];
    if(match) {

check_match:
        do {
            //print_mac_entry(match);

            /* XXX: we could definitely take advantage of
             * 64bit or SIMD instructions to speed this up, here and in the hash func
             */
            for(i = 0; i < match->mask / 8; i++) {
                if (mac[i] != match->o[i])
                    i = 6; // 7!? flag and break
            }
            if(i == 7) {
                continue; // we flagged and broke
            }
            // do we have a winner?
            r = match->mask % 8;
            if(r) {
                // there is more to match, maybe less than a nibble
                //dlog("nibble match! /%d :%d, %02x=?%02x\n", match->mask, r, mac[i] >> match->mask, match->o[i] >> match->mask);
                if(! ((mac[i] ^ match->o[i]) & (0xFF << (8 - r))) )
                    return match; // if the bits match, expression is 0
            } else {
                // easy case: we have a winner..
                return match;
            }
        } while (NULL != (match = match->next));
    }
    // tail recurse, defer to the wisdom of our elders
    if(! ditch ) {
        match = match_mac(db, mac, mask - 8);
    }

    // real tough case.. we didn't find anything down the road
    // and must search upwards :-P. This is the DITCH, we scan
    // 255 hashpoints per octet to find out if there is anything around..

    if(!match) {
        while(ditch++ < 0xFF) {
            match = db[(index + ditch) % MAC_HASHSIZE];
            if(match)
                goto check_match;
        }
    }
    return match;
}