Commit ac96c5eb authored by 's avatar
Browse files

Added applications, with test/example program mapidagdump for DAG cards.


git-svn-id: file:///home/svn/mapi/branches/mapi_light@1598 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 648dcdcd
SUBDIRS = mapidagdump
AM_CPPFLAGS = -I$(top_srcdir)/src/lib @DAGINC@
mapidagdump_LDADD = -L$(top_srcdir)/src/lib -lpthread -lmapi @DAGLIB@
bin_PROGRAMS = mapidagdump
mapidagdump_SOURCES = mapidagdump.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netdb.h>
#include "mapi.h"
#include "dagapi.h"
#include "dagerf.h"
static int fd;
inline void print_pkt(const char *pkt);
// Function that cleanly shuts down.
static void clean_shutdown()
{
mapi_close_flow(fd);
printf("Gracefully shutdown.\n");
exit(EXIT_SUCCESS);
}
// Handler function that parses packets in shared memory
static void packet_handler(const char *base_addr, int num_pkts)
{
dag_record_t *rec;
while (num_pkts--)
{
rec = (dag_record_t *) base_addr;
printf("-----------------------------\n");
printf("IFace: %d, Type: %s, TS: %llu\n", rec->flags.iface,
dagerf_type_to_string(rec->type, TT_ETH), rec->ts);
printf("rlen: %d, wlen: %d\n", ntohs(rec->rlen), ntohs(rec->wlen));
printf("ETH: offset: %d, pad: %d\n", rec->rec.eth.offset, rec->rec.eth.pad);
print_pkt((char *)&rec->rec.eth.dst);
base_addr += ntohs(rec->rlen);
}
}
int main(int argc, char *argv[])
{
const char *devtype = NULL;
// Catch signals and shutdown properly
signal(SIGTERM, clean_shutdown);
signal(SIGQUIT, clean_shutdown);
signal(SIGINT, clean_shutdown);
// Create flow
if ((fd = mapi_create_flow("/dev/dag0")) <= 0)
{
printf("invalid fd.\n");
exit(EXIT_FAILURE);
}
// Get device type
devtype = mapi_get_device_type(fd);
if (strncmp(devtype, "1.1.1", MAPI_STR_LENGTH) != 0)
{
printf("Unsupported device type: %s\n", devtype);
mapi_close_flow(fd);
exit(EXIT_FAILURE);
}
// Connect to flow
if (mapi_connect(fd) != 0)
{
printf("mapi_connect failed.\n");
mapi_close_flow(fd);
exit(EXIT_FAILURE);
}
// Start infinite loop
if (mapi_loop_shm(fd, 0, packet_handler) != 0)
{
perror("mapi_loop_shm failed\n");
}
// Clean up if loop terminates
clean_shutdown();
return 0;
}
// Function that prints packet information
// inlined to skip function overhead
inline void print_pkt(const char *pkt)
{
int j;
char ipaddr[INET6_ADDRSTRLEN];
struct ether_header *eth;
uint16_t ethertype;
struct iphdr *iph;
struct ip6_hdr *ip6h;
struct protoent *pt; //protocol name
// lay the Ethernet header struct over the packet data
eth = (struct ether_header *)pkt;
// Datalink layer
for(j=0; j<ETH_ALEN; j++) {
printf("%X", eth->ether_shost[j]);
if(j != 5) printf(":");
}
printf(" > ");
for(j=0; j<ETH_ALEN; j++){
printf("%X", eth->ether_dhost[j]);
if(j != 5) printf(":");
}
ethertype = ntohs(eth->ether_type);
printf(" type 0x%x ", ethertype);
switch (ethertype) {
case ETHERTYPE_IP: printf("IPv4\n"); break;
case ETHERTYPE_IPV6: printf("IPv6\n"); break;
case ETHERTYPE_ARP: printf("ARP\n"); break;
case ETHERTYPE_REVARP: printf("Reverse ARP\n"); break;
default: printf("\n"); break;
}
// now move on to payload
pkt += ETH_HLEN;
// IPv4
if (ethertype == ETHERTYPE_IP) {
// lay the IP header struct over the packet data
iph = (struct iphdr *)pkt;
// switch (iph->protocol) {
// case IPPROTO_UDP:
// case IPPROTO_TCP:
// case IPPROTO_ICMP:
// default:
printf("%s > ", inet_ntoa(*(struct in_addr *)&(iph->saddr)));
printf("%s", inet_ntoa(*(struct in_addr *)&(iph->daddr)));
pt = getprotobynumber(iph->protocol); // get protocol name
printf(" %s TTL:%d TOS:0x%X ID:%d IpLen:%d DgmLen:%d\n",
(pt == NULL) ? "???" : pt->p_name, iph->ttl, iph->tos,
ntohs(iph->id), iph->ihl << 2, ntohs(iph->tot_len));
// break;
}
//IPv6
else if (ethertype == ETHERTYPE_IPV6) {
// lay the IP header struct over the packet data
ip6h = (struct ip6_hdr *)pkt;
printf("%s > ", inet_ntop(AF_INET6, (struct in6_addr *)&(ip6h->ip6_src), ipaddr, sizeof(ipaddr)));
printf("%s", inet_ntop(AF_INET6, (struct in6_addr *)&(ip6h->ip6_dst), ipaddr, sizeof(ipaddr)));
pt = getprotobynumber(ip6h->ip6_nxt); // get protocol name
printf(" %s HopLim:%d TC:%d PayloadLen:%d\n",
pt->p_name, ip6h->ip6_hlim,
((ip6h->ip6_flow >> 20) & 0xFF), ntohs(ip6h->ip6_plen));
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment