openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

knet_rx.c (20605B)


      1 #include <signal.h>
      2 #include <inttypes.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <unistd.h>
      6 #include <string.h>
      7 #include <sys/socket.h>
      8 #include <features.h>
      9 #include <linux/if_packet.h>
     10 #include <linux/if_ether.h>
     11 #include <errno.h>
     12 #include <sys/ioctl.h>
     13 #include <net/if.h>
     14 #include <net/ethernet.h>
     15 #include <netinet/in.h>
     16 #include <netinet/ether.h>
     17 
     18 #define RCPU_SIGNATURE 0xB840
     19 #define RX_MAX  9100
     20 
     21 struct L2header {
     22     uint8_t     dest_mac[6];
     23     uint8_t     src_mac[6];
     24     uint32_t    tag;
     25     uint16_t    ether_type;
     26 };
     27 
     28 struct RCPUheader {
     29     uint16_t    signature;
     30     uint8_t     opcode;
     31     uint8_t     flags;
     32     uint16_t    trans_id;
     33     uint16_t    data_len;
     34     uint16_t    reply_len;
     35     uint32_t    reserved;
     36 };
     37 
     38 /* DEFINE for little endian processors */
     39 /* #define LE_HOST */
     40 
     41 /*
     42  * DMA Control Block - Type 21
     43  * Used on 56840 devices
     44  * 16 words
     45  */
     46 struct dcb21_s {
     47 #ifdef REMOVE
     48     uint32_t    addr;   /* T21.0: physical address */
     49     /* T21.1: Control 0 */
     50 #ifdef  LE_HOST
     51     uint32_t    c_count:16,     /* Requested byte count */
     52                 c_chain:1,      /* Chaining */
     53                 c_sg:1,         /* Scatter Gather */
     54                 c_reload:1,     /* Reload */
     55                 c_hg:1,         /* Higig (TX) */
     56                 c_stat:1,       /* Update stats (TX) */
     57                 c_pause:1,      /* Pause packet (TX) */
     58                 c_purge:1,      /* Purge packet (TX) */
     59     :           9;              /* Don't care */
     60 #else
     61                 uint32_t:9,     /* Don't care */
     62                 c_purge:1,      /* Purge packet (TX) */
     63                 c_pause:1,      /* Pause packet (TX) */
     64                 c_stat:1,       /* Update stats (TX) */
     65                 c_hg:1,         /* Higig (TX) */
     66                 c_reload:1,     /* Reload */
     67                 c_sg:1,         /* Scatter Gather */
     68                 c_chain:1,      /* Chaining */
     69                 c_count:16;     /* Requested byte count */
     70 #endif /* LE_HOST */
     71 #endif
     72     uint32_t    mh0;    /* T21.2: Module Header word 0 */
     73     uint32_t    mh1;    /* T21.3: Module Header word 1 */
     74     uint32_t    mh2;    /* T21.4: Module Header word 2 */
     75     uint32_t    mh3;    /* T21.5: Module Header word 3 */
     76 #ifdef  LE_HOST
     77     /* T21.6 */
     78                 uint32_t:3,     /* Reserved */
     79                 mtp_index:5,    /* MTP index */
     80                 cpu_cos:8,      /* Queue number for CPU packets */
     81                 inner_vid:12,   /* Inner VLAN ID */
     82                 inner_cfi:1,    /* Inner Canoncial Format Indicator */
     83                 inner_pri:3;    /* Inner priority */
     84 
     85     /* T21.7 */
     86     uint32_t    reason_hi:16,   /* CPU opcode (high bits) */
     87                 pkt_len:14,     /* Packet length */
     88     :           2;              /* Reserved */
     89 
     90     /* T21.8 */
     91     uint32_t    reason; /* CPU opcode (low bits) */
     92 
     93     /* T21.9 */
     94     uint32_t    dscp:6,         /* New DSCP */
     95     :           2,              /* Reserved */
     96                 chg_tos:1,      /* DSCP has been changed by HW */
     97                 decap_tunnel_type:4,    /* Tunnel type that was decapsulated */
     98                 regen_crc:1,    /* Packet modified and needs new CRC */
     99     :           2,              /* Reserved */
    100                 outer_vid:12,   /* Outer VLAN ID */
    101                 outer_cfi:1,    /* Outer Canoncial Format Indicator */
    102                 outer_pri:3;    /* Outer priority */
    103 
    104     /* T21.10 */
    105     uint32_t    timestamp;      /* Timestamp */
    106 
    107     /* T21.11 */
    108                 uint32_t:12,    /* Reserved */
    109                 ecn:2,          /* New ECN value */
    110                 chg_ecn:1,      /* ECN changed */
    111                 mcq:1,          /* Multicast queue indicator */
    112                 vfi:12,         /* Internal VFI value */
    113                 vfi_valid:1,    /* Validates VFI field */
    114                 dvp_nhi_sel:1,  /* DVP overlay indicator */
    115                 vntag_action:2; /* VN tag action */
    116 
    117     /* T21.12 */
    118     uint32_t    srcport:8,      /* Source port number */
    119                 hgi:2,          /* Higig Interface Format Indicator */
    120                 itag_status:2,  /* Ingress Inner tag status */
    121                 otag_action:2,  /* Ingress Outer tag action */
    122                 itag_action:2,  /* Ingress Inner tag action */
    123                 service_tag:1,  /* SD tag present */
    124                 switch_pkt:1,   /* Switched packet */
    125                 hg_type:1,      /* 0: Higig+, 1: Higig2 */
    126                 src_hg:1,       /* Source is Higig */
    127                 l3routed:1,     /* Any IP routed packet */
    128                 l3only:1,       /* L3 only IPMC packet */
    129                 replicated:1,   /* Replicated copy */
    130     :           2,              /* Reserved */
    131                 do_not_change_ttl:1,    /* Do not change TTL */
    132                 bpdu:1,         /* BPDU Packet */
    133     :           5;              /* Reserved */
    134 
    135     /* T21.13 */
    136     uint32_t    uc_cos:4,       /* COS value for unicast packet */
    137                 eh_seg_sel:3,   /* Extended Higig Seg Sel */
    138                 next_pass_cp:2, /* Next pass code point */
    139                 oam_pkt:1,      /* OAM packet */
    140     :           2,              /* Reserved */
    141                 eh_tag_type:2,  /* Extended Higig tag type */
    142                 eh_tm:1,        /* Extended Higig traffic mgr ctrl */
    143                 eh_queue_tag:16,/* Extended Higig queue tag */
    144                 hg2_ext_hdr:1;  /* Extended Higig2 header valid */
    145 
    146     /* T21.14 */
    147     uint32_t    l3_intf:14,     /* L3 Intf num / Next hop idx */
    148     :           2,              /* Reserved */
    149                 match_rule:8,   /* Matched FP rule */
    150                 mc_cos2:4,      /* COS2 value for multicast packets */
    151                 mc_cos1:4;      /* COS1 value for multicast packets */
    152 
    153     /* T21.15: DMA Status 0 */
    154     uint32_t    count:16,       /* Transferred byte count */
    155                 end:1,          /* End bit (RX) */
    156                 start:1,        /* Start bit (RX) */
    157                 error:1,        /* Cell Error (RX) */
    158     :           12,             /* Reserved */
    159                 done:1;         /* Descriptor Done */
    160 #else
    161     /* T21.6 */
    162     uint32_t    inner_pri:3,    /* Inner priority */
    163                 inner_cfi:1,    /* Inner Canoncial Format Indicator */
    164                 inner_vid:12,   /* Inner VLAN ID */
    165                 cpu_cos:8,      /* Queue number for CPU packets */
    166                 mtp_index:5,    /* MTP index */
    167     :           3;              /* Reserved */
    168 
    169     /* T21.7 */
    170                 uint32_t:2,     /* Reserved */
    171                 pkt_len:14,     /* Packet length */
    172                 reason_hi:16;   /* CPU opcode (high bits) */
    173 
    174     /* T21.8 */
    175     uint32_t    reason;         /* CPU opcode (low bits) */
    176 
    177     /* T21.9 */
    178     uint32_t    outer_pri:3,    /* Outer priority */
    179                 outer_cfi:1,    /* Outer Canoncial Format Indicator */
    180                 outer_vid:12,   /* Outer VLAN ID */
    181     :           2,              /* Reserved */
    182                 regen_crc:1,    /* Packet modified and needs new CRC */
    183                 decap_tunnel_type:4,    /* Tunnel type that was decapsulated */
    184                 chg_tos:1,      /* DSCP has been changed by HW */
    185     :           2,              /* Reserved */
    186                 dscp:6;         /* New DSCP */
    187 
    188     /* T21.10 */
    189     uint32_t    timestamp;      /* Timestamp */
    190 
    191     /* T21.11 */
    192     uint32_t    vntag_action:2, /* VN tag action */
    193                 dvp_nhi_sel:1,  /* DVP overlay indicator */
    194                 vfi_valid:1,    /* Validates VFI field */
    195                 vfi:12,         /* Internal VFI value */
    196                 mcq:1,          /* Multicast queue indicator */
    197                 chg_ecn:1,      /* ECN changed */
    198                 ecn:2,          /* New ECN value */
    199     :           12,             /* Reserved */
    200       /* T21.12 */
    201                 uint32_t:5,     /* Reserved */
    202                 bpdu:1,         /* BPDU Packet */
    203                 do_not_change_ttl:1,    /* Do not change TTL */
    204     :           2,              /* Reserved */
    205                 replicated:1,   /* Replicated copy */
    206                 l3only:1,       /* L3 only IPMC packet */
    207                 l3routed:1,     /* Any IP routed packet */
    208                 src_hg:1,       /* Source is Higig */
    209                 hg_type:1,      /* 0: Higig+, 1: Higig2 */
    210                 switch_pkt:1,   /* Switched packet */
    211                 service_tag:1,  /* SD tag present */
    212                 itag_action:2,  /* Ingress Inner tag action */
    213                 otag_action:2,  /* Ingress Outer tag action */
    214                 itag_status:2,  /* Ingress Inner tag status */
    215                 hgi:2,          /* Higig Interface Format Indicator */
    216                 srcport:8;      /* Source port number */
    217 
    218     /* T21.13 */
    219     uint32_t    hg2_ext_hdr:1,  /* Extended Higig2 header valid */
    220                 eh_queue_tag:16,/* Extended Higig queue tag */
    221                 eh_tm:1,        /* Extended Higig traffic mgr ctrl */
    222                 eh_tag_type:2,  /* Extended Higig tag type */
    223     :           2,              /* Reserved */
    224                 oam_pkt:1,      /* OAM packet */
    225                 next_pass_cp:2, /* Next pass code point */
    226                 eh_seg_sel:3,   /* Extended Higig Seg Sel */
    227                 uc_cos:4;       /* COS value for unicast packet */
    228 
    229     /* T21.14 */
    230     uint32_t    mc_cos1:4,      /* COS1 value for multicast packets */
    231                 mc_cos2:4,      /* COS2 value for multicast packets */
    232                 match_rule:8,   /* Matched FP rule */
    233     :           2,              /* Reserved */
    234                 l3_intf:14;     /* L3 Intf num / Next hop idx */
    235 
    236     /* T21.15: DMA Status 0 */
    237     uint32_t    done:1,     /* Descriptor Done */
    238     :           12,         /* Reserved */
    239                 error:1,    /* Cell Error (RX) */
    240                 start:1,    /* Start bit (RX) */
    241                 end:1,      /* End bit (RX) */
    242                 count:16;   /* Transferred byte count */
    243 #endif
    244 };
    245 
    246 static void
    247 unpackL2header(unsigned char const *const pkt, struct L2header *header)
    248 {
    249     unsigned char const *vbuf;
    250     int         ix;
    251 
    252     vbuf = &pkt[0];
    253     for (ix = 0; ix < 6; ix++) {
    254         header->dest_mac[ix] = vbuf[ix];
    255     }
    256     vbuf = &pkt[6];
    257     for (ix = 0; ix < 6; ix++) {
    258         header->src_mac[ix] = vbuf[ix];
    259     }
    260     vbuf = &pkt[12];
    261     header->tag = (vbuf[0] << 24) | (vbuf[1] << 16) | (vbuf[2] << 8) | vbuf[3];
    262     vbuf = &pkt[16];
    263     header->ether_type = (vbuf[0] << 8) | vbuf[1];
    264 }
    265 
    266 static void
    267 printL2header(unsigned char const *const pkt)
    268 {
    269     struct L2header header;
    270 
    271     unpackL2header(pkt, &header);
    272     printf("\nL2 header:\n");
    273     printf("  Dst MAC:   %02x:%02x:%02x:%02x:%02x:%02x\n",
    274            header.dest_mac[0], header.dest_mac[1], header.dest_mac[2],
    275            header.dest_mac[3], header.dest_mac[4], header.dest_mac[5]);
    276     printf("  Src MAC:   %02x:%02x:%02x:%02x:%02x:%02x\n", header.src_mac[0],
    277            header.src_mac[1], header.src_mac[2], header.src_mac[3], header.src_mac[4],
    278            header.src_mac[5]);
    279     printf("  Tag:       0x%08x\n", header.tag);
    280     printf("  EtherType: 0x%04x\n", header.ether_type);
    281 }
    282 
    283 static void
    284 unpackRCPUheader(unsigned char const *const pkt, struct RCPUheader *header)
    285 {
    286     unsigned char const *vbuf;
    287 
    288     vbuf = &pkt[18];
    289 
    290     header->signature = (vbuf[0] << 8) | vbuf[1];
    291     header->opcode = vbuf[2];
    292     header->flags = vbuf[3];
    293     header->trans_id = (vbuf[4] << 8) | vbuf[5];
    294     header->data_len = (vbuf[6] << 8) | vbuf[7];
    295     header->reply_len = (vbuf[8] << 8) | vbuf[9];
    296     header->reserved = (vbuf[10] << 24) | (vbuf[11] << 16) | (vbuf[12] << 8) | vbuf[13];
    297 }
    298 
    299 static void
    300 printRCPUheader(unsigned char const *const pkt)
    301 {
    302     struct RCPUheader header;
    303 
    304     unpackRCPUheader(pkt, &header);
    305 
    306     printf("\nRCPU Header:\n");
    307     printf("  Signature: 0x%04x; %s\n", header.signature,
    308            (header.signature == RCPU_SIGNATURE) ? "OK" : "INVALID");
    309     printf("  Opcode:    0x%02x\n", header.opcode);
    310     printf("  Flags:     0x%02x\n", header.flags);
    311     printf("  Trans ID:  0x%04x\n", header.trans_id);
    312     printf("  Data len:  %d\n", header.data_len);
    313     printf("  Reply len: %d\n", header.reply_len);
    314     printf("  Reserved:  0x%08x\n", header.reserved);
    315 }
    316 
    317 static void
    318 printMetaData(unsigned char *pkt)
    319 {
    320     uint32_t   *wbuf;
    321     int         ix;
    322     struct dcb21_s *dcbHack;
    323 
    324     /*
    325      * The Rx meta data is essentially the architecture specific DCB.
    326      * We skip the first 8 bytes since that information isn't very useful.
    327      * This means the metadata for may differ from one device type to another.
    328      */
    329 
    330     printf("\nRCPU Meta Data:\n");
    331     wbuf = (uint32_t *) & pkt[0];
    332 #if 0
    333     dcbHack = (struct dcb21_s *) &pkt[32];
    334     printf("DCB: Packet Len: %d;\n", dcbHack->pkt_len);
    335     printf("DCB: Reason Hi: %X; Low: %X\n", dcbHack->reason_hi, dcbHack->reason);
    336     printf("DCB: Outer VLAN: %d; Outer CFI: %d; Outer Priority: %d\n",
    337            dcbHack->outer_vid, dcbHack->outer_cfi, dcbHack->outer_pri);
    338     printf("DCB: BPDU Packet: %d\n", dcbHack->bpdu);
    339     printf("DCB: Do not change TTL: %d\n", dcbHack->do_not_change_ttl);
    340     printf("DCB: Replicated copy: %d\n", dcbHack->replicated);
    341     printf("DCB: L3 only IPMC packet: %d\n", dcbHack->l3only);
    342     printf("DCB: Any IP routed packet: %d\n", dcbHack->l3routed);
    343     printf("DCB: Source is Higig: %d\n", dcbHack->src_hg);
    344     printf("DCB: 0: Higig+, 1: Higig2: %d\n", dcbHack->hg_type);
    345     printf("DCB: Switched packet: %d\n", dcbHack->switch_pkt);
    346     printf("DCB: SD tag present: %d\n", dcbHack->service_tag);
    347     printf("DCB: Ingress Inner tag action: %d\n", dcbHack->itag_action);
    348     printf("DCB: Ingress Outer tag action: %d\n", dcbHack->otag_action);
    349     printf("DCB: Ingress Inner tag status: %d\n", dcbHack->itag_status);
    350     printf("DCB: Higig Interface Format Indicator: %d\n", dcbHack->hgi);
    351     printf("DCB: Source port number: %d\n", dcbHack->srcport);
    352 #endif
    353 
    354     for (ix = 0; ix < 16; ix++) {
    355         if ((ix & 1) == 0) {
    356             printf("  Word %2d: 0x%08X", ix, wbuf[ix]);
    357         } else {
    358             printf("; 0x%08X\n", wbuf[ix]);
    359         }
    360     }
    361 }
    362 
    363 static void
    364 dump_raw(uint8_t * rx_packet, int rx_len)
    365 {
    366     int         ix;
    367 
    368     printf("\nRaw Packet Dump (%d bytes):\n", rx_len);
    369     for (ix = 0; ix < rx_len; ix++) {
    370         if ((ix & 0xf) == 0) {
    371             printf("0x%04x:", ix);
    372         } else if ((ix & 0xf) == 8) {
    373             printf(" -");
    374         }
    375         printf(" 0x%02x", rx_packet[ix]);
    376         if ((ix & 0xf) == 0xf) {
    377             printf("\n");
    378         }
    379     }
    380     if ((ix & 0xf) != 0) {
    381         printf("\n");
    382     }
    383 }
    384 
    385 static int
    386 create_raw_socket(int protocol_to_sniff)
    387 {
    388     int         rawsock;
    389 
    390     if ((rawsock = socket(PF_PACKET, SOCK_RAW, htons(protocol_to_sniff))) < 0) {
    391         perror("Error creating raw socket: ");
    392         return rawsock;
    393     }
    394 
    395     return rawsock;
    396 }
    397 
    398 static int
    399 bind_raw_socket(char *device, int rawsock, int protocol)
    400 {
    401 
    402     struct sockaddr_ll sll;
    403     struct ifreq ifr;
    404 
    405     bzero(&sll, sizeof(sll));
    406     bzero(&ifr, sizeof(ifr));
    407 
    408     /* First Get the Interface Index  */
    409     strncpy((char *) ifr.ifr_name, device, IFNAMSIZ);
    410     if ((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1) {
    411         printf("Error getting interface index for %s\n", device);
    412         return -1;
    413     }
    414 
    415     /* Bind our raw socket to this interface */
    416     sll.sll_family = AF_PACKET;
    417     sll.sll_ifindex = ifr.ifr_ifindex;
    418     sll.sll_protocol = htons(protocol);
    419 
    420     if ((bind(rawsock, (struct sockaddr *) &sll, sizeof(sll))) == -1) {
    421         perror("Error binding raw socket to interface\n");
    422         return -1;
    423     }
    424 
    425     return 0;
    426 }
    427 
    428 void
    429 dump_rcpu_encap(unsigned char *pkt)
    430 {
    431     printL2header(pkt);
    432     printRCPUheader(pkt);
    433     printMetaData(pkt);
    434 }
    435 
    436 static int  rawsock = -1;
    437 static int  rx_packets = 0;
    438 static char *ifname = NULL;
    439 
    440 static void
    441 sigint(int signum)
    442 {
    443     /*Clean up....... */
    444 
    445     struct ifreq ifr;
    446 
    447     if ((rawsock == -1) || (ifname == NULL)) {
    448         return;
    449     }
    450 
    451     strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    452     ioctl(rawsock, SIOCGIFFLAGS, &ifr);
    453     ifr.ifr_flags &= ~IFF_PROMISC;
    454     ioctl(rawsock, SIOCSIFFLAGS, &ifr);
    455     close(rawsock);
    456 
    457     printf("RX terminating ...\n");
    458 
    459     printf("Total packets received: %d\n", rx_packets);
    460     exit(0);
    461 }
    462 
    463 static void
    464 usage(const char *const prog)
    465 {
    466     printf("Usage %s [-v] [-vv] interface [maxRxPackets]\n", prog);
    467     printf("-r            ; RCPU mode\n");
    468     printf("-v            ; Be verbose\n");
    469     printf("-vv           ; Be very verbose\n");
    470     printf("interface     ; ethernet interface (eth5)\n");
    471     printf("maxRxPackets  ; Exit after receiving this many packets\n");
    472 }
    473 
    474 int
    475 main(int argc, char **argv)
    476 {
    477     int         rcpu = 0;
    478     int         ax;
    479     int         max_packets = -1;
    480     int         rx_len;
    481     int         verbose = 0;
    482     int         vverbose = 0;
    483     socklen_t   len;
    484     struct sockaddr_ll skaddr;
    485     uint8_t     rx_packet[RX_MAX];
    486 
    487     for (ax = 1; ax < argc; ax++) {
    488         if (argv[ax][0] == '-') {
    489             char       *flag = &argv[ax][1];
    490 
    491             if (strcmp(flag, "v") == 0) {
    492                 verbose = 1;
    493             } else if (strcmp(flag, "vv") == 0) {
    494                 verbose = 1;
    495                 vverbose = 1;
    496             } else if (strcmp(flag, "r") == 0) {
    497                 rcpu = 1;
    498             } else {
    499                 fprintf(stderr, "ERROR: unknown switch %s\n", argv[ax]);
    500                 usage(argv[0]);
    501                 return -2;
    502             }
    503         } else {
    504             if (ifname == NULL) {
    505                 ifname = argv[ax];
    506             } else if (max_packets < 0) {
    507                 max_packets = atoi(argv[ax]);
    508                 if (max_packets == 0) {
    509                     printf("Bogus packet count\n");
    510                     return -2;
    511                 }
    512             } else {
    513                 fprintf(stderr, "ERROR: unknown argument %s\n", argv[ax]);
    514                 usage(argv[0]);
    515                 return -2;
    516             }
    517         }
    518     }
    519 
    520     if (ifname == NULL) {
    521         usage(argv[0]);
    522         return -1;
    523     }
    524 
    525     /*establish signal handler */
    526     if (SIG_ERR == signal(SIGINT, sigint)) {
    527         return 2;
    528     }
    529 
    530     if (max_packets <= 0) {
    531         max_packets = 1000000;
    532     }
    533 
    534     /* Create the raw socket */
    535     rawsock = create_raw_socket(ETH_P_ALL);
    536 
    537     if (rawsock < 0) {
    538         return 1;
    539     }
    540 
    541     /* Bind raw socket to interface */
    542     if (bind_raw_socket(ifname, rawsock, ETH_P_ALL) < 0) {
    543         return 2;
    544     }
    545 
    546     rx_packets = 0;
    547     while (rx_packets < max_packets) {
    548 
    549         if (vverbose) {
    550             printf("\nWaiting on packet %d\n", rx_packets + 1);
    551         }
    552 
    553         memset(&skaddr, 0, sizeof(skaddr));
    554         skaddr.sll_protocol = htons(ETH_P_ALL);
    555         len = sizeof(struct sockaddr);
    556 
    557         if ((rx_len = recvfrom(rawsock, rx_packet, RX_MAX, 0,
    558                                (struct sockaddr *) &skaddr, &len)) > 0) {
    559             int         packet_type = ntohs(skaddr.sll_pkttype);
    560 
    561             if (skaddr.sll_pkttype == PACKET_OUTGOING) {
    562                 if (vverbose) {
    563                     printf("Skipping %d byte outgoing packet;\n", rx_len);
    564                 }
    565                 continue;
    566             }
    567             rx_packets++;
    568             if (verbose) {
    569                 printf
    570                   ("\n--------------------------------------------------------------------------------\n");
    571             }
    572             if (verbose) {
    573                 printf("Received packet %d (%d bytes)\n", rx_packets, rx_len);
    574                 #if 0
    575                 if (vverbose) {
    576                     static const char *packet_types[] =
    577                       { "HOST", "BROADCAST", "MULTICAST", "OTHERHOST", "OUTGOING",
    578                         "LOOPBACK", "FASTROUTE"
    579                     };
    580                     printf("    Interface Index = %d; Packet Type = %s\n",
    581                            skaddr.sll_ifindex, packet_types[packet_type]);
    582                 }
    583 		#endif
    584 		if (rcpu) {
    585                     dump_rcpu_encap(rx_packet);
    586                 } else {
    587                     printf("Dump L2 Header\n");
    588                     printL2header(rx_packet);
    589                 }
    590                 if (vverbose) {
    591                     printf("Dump Raw Packet\n");
    592                     dump_raw(rx_packet, rx_len);
    593                 }
    594             } else {
    595                 if ((rx_packets & 0x1FFF) == 0) {
    596                     printf("Rx Packet Count: %8d\n", rx_packets);
    597                 }
    598             }
    599         }
    600         if (rx_len < 0) {
    601             perror("recvfrom()");
    602         }
    603     }
    604     printf("Received %d packets, DONE\n", max_packets);
    605 
    606     close(rawsock);
    607 
    608     return 0;
    609 }
    610