1147894Ssam/* 2147894Ssam * pcap-septel.c: Packet capture interface for Intel/Septel card. 3147894Ssam * 4147894Ssam * The functionality of this code attempts to mimic that of pcap-linux as much 5147894Ssam * as possible. This code is compiled in several different ways depending on 6147894Ssam * whether SEPTEL_ONLY and HAVE_SEPTEL_API are defined. If HAVE_SEPTEL_API is 7147894Ssam * not defined it should not get compiled in, otherwise if SEPTEL_ONLY is 8147894Ssam * defined then the 'septel_' function calls are renamed to 'pcap_' 9147894Ssam * equivalents. If SEPTEL_ONLY is not defined then nothing is altered - the 10147894Ssam * septel_ functions will be called as required from their 11147894Ssam * pcap-linux/equivalents. 12147894Ssam * 13147894Ssam * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY 14147894Ssam * (+961 3 485243) 15147894Ssam */ 16147894Ssam 17147894Ssam#ifndef lint 18147894Ssamstatic const char rcsid[] _U_ = 19214518Srpaulo "@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.4 2008-04-14 20:40:58 guy Exp $"; 20147894Ssam#endif 21147894Ssam 22147894Ssam#ifdef HAVE_CONFIG_H 23147894Ssam#include "config.h" 24147894Ssam#endif 25147894Ssam 26147894Ssam#include <sys/param.h> 27147894Ssam 28147894Ssam#include <stdlib.h> 29147894Ssam#include <string.h> 30147894Ssam#include <errno.h> 31147894Ssam 32147894Ssam#include "pcap-int.h" 33147894Ssam 34147894Ssam#include <ctype.h> 35147894Ssam#include <netinet/in.h> 36147894Ssam#include <sys/mman.h> 37147894Ssam#include <sys/socket.h> 38147894Ssam#include <sys/types.h> 39147894Ssam#include <unistd.h> 40147894Ssam 41147894Ssam#include <msg.h> 42147894Ssam#include <ss7_inc.h> 43147894Ssam#include <sysgct.h> 44147894Ssam#include <pack.h> 45147894Ssam#include <system.h> 46147894Ssam 47147894Ssam#include "pcap-septel.h" 48147894Ssam 49147894Ssamstatic int septel_setfilter(pcap_t *p, struct bpf_program *fp); 50147894Ssamstatic int septel_stats(pcap_t *p, struct pcap_stat *ps); 51147894Ssamstatic int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf); 52147894Ssam 53147894Ssam/* 54147894Ssam * Read at most max_packets from the capture queue and call the callback 55147894Ssam * for each of them. Returns the number of packets handled, -1 if an 56147894Ssam * error occured, or -2 if we were told to break out of the loop. 57147894Ssam */ 58147894Ssamstatic int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { 59147894Ssam 60147894Ssam HDR *h; 61147894Ssam MSG *m; 62147894Ssam int processed = 0 ; 63147894Ssam int t = 0 ; 64147894Ssam 65147894Ssam /* identifier for the message queue of the module(upe) from which we are capturing 66147894Ssam * packets.These IDs are defined in system.txt . By default it is set to 0x2d 67147894Ssam * so change it to 0xdd for technical reason and therefore the module id for upe becomes: 68147894Ssam * LOCAL 0xdd * upe - Example user part task */ 69147894Ssam unsigned int id = 0xdd; 70147894Ssam 71147894Ssam /* process the packets */ 72147894Ssam do { 73147894Ssam 74147894Ssam unsigned short packet_len = 0; 75147894Ssam int caplen = 0; 76147894Ssam int counter = 0; 77147894Ssam struct pcap_pkthdr pcap_header; 78147894Ssam u_char *dp ; 79147894Ssam 80147894Ssam /* 81147894Ssam * Has "pcap_breakloop()" been called? 82147894Ssam */ 83147894Ssamloop: 84147894Ssam if (p->break_loop) { 85147894Ssam /* 86147894Ssam * Yes - clear the flag that indicates that 87147894Ssam * it has, and return -2 to indicate that 88147894Ssam * we were told to break out of the loop. 89147894Ssam */ 90147894Ssam p->break_loop = 0; 91147894Ssam return -2; 92147894Ssam } 93147894Ssam 94147894Ssam /*repeat until a packet is read 95147894Ssam *a NULL message means : 96147894Ssam * when no packet is in queue or all packets in queue already read */ 97147894Ssam do { 98147894Ssam /* receive packet in non-blocking mode 99147894Ssam * GCT_grab is defined in the septel library software */ 100147894Ssam h = GCT_grab(id); 101147894Ssam 102147894Ssam m = (MSG*)h; 103147894Ssam /* a couter is added here to avoid an infinite loop 104147894Ssam * that will cause our capture program GUI to freeze while waiting 105147894Ssam * for a packet*/ 106147894Ssam counter++ ; 107147894Ssam 108147894Ssam } 109147894Ssam while ((m == NULL)&& (counter< 100)) ; 110147894Ssam 111147894Ssam if (m != NULL) { 112147894Ssam 113147894Ssam t = h->type ; 114147894Ssam 115147894Ssam /* catch only messages with type = 0xcf00 or 0x8f01 corrsponding to ss7 messages*/ 116147894Ssam /* XXX = why not use API_MSG_TX_REQ for 0xcf00 and API_MSG_RX_IND 117147894Ssam * for 0x8f01? */ 118147894Ssam if ((t != 0xcf00) && (t != 0x8f01)) { 119147894Ssam relm(h); 120147894Ssam goto loop ; 121147894Ssam } 122147894Ssam 123147894Ssam /* XXX - is API_MSG_RX_IND for an MTP2 or MTP3 message? */ 124147894Ssam dp = get_param(m);/* get pointer to MSG parameter area (m->param) */ 125147894Ssam packet_len = m->len; 126147894Ssam caplen = p->snapshot ; 127147894Ssam 128147894Ssam 129147894Ssam if (caplen > packet_len) { 130147894Ssam 131147894Ssam caplen = packet_len; 132147894Ssam } 133147894Ssam /* Run the packet filter if there is one. */ 134147894Ssam if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { 135147894Ssam 136147894Ssam 137147894Ssam /* get a time stamp , consisting of : 138147894Ssam * 139147894Ssam * pcap_header.ts.tv_sec: 140147894Ssam * ---------------------- 141147894Ssam * a UNIX format time-in-seconds when he packet was captured, 142147894Ssam * i.e. the number of seconds since Epoch time (January 1,1970, 00:00:00 GMT) 143147894Ssam * 144147894Ssam * pcap_header.ts.tv_usec : 145147894Ssam * ------------------------ 146147894Ssam * the number of microseconds since that second 147147894Ssam * when the packet was captured 148147894Ssam */ 149147894Ssam 150147894Ssam (void)gettimeofday(&pcap_header.ts, NULL); 151147894Ssam 152147894Ssam /* Fill in our own header data */ 153147894Ssam pcap_header.caplen = caplen; 154147894Ssam pcap_header.len = packet_len; 155147894Ssam 156147894Ssam /* Count the packet. */ 157147894Ssam p->md.stat.ps_recv++; 158147894Ssam 159147894Ssam /* Call the user supplied callback function */ 160147894Ssam callback(user, &pcap_header, dp); 161147894Ssam 162147894Ssam processed++ ; 163147894Ssam 164147894Ssam } 165147894Ssam /* after being processed the packet must be 166147894Ssam *released in order to receive another one */ 167147894Ssam relm(h); 168147894Ssam }else 169147894Ssam processed++; 170147894Ssam 171147894Ssam } 172147894Ssam while (processed < cnt) ; 173147894Ssam 174147894Ssam return processed ; 175147894Ssam} 176147894Ssam 177147894Ssam 178147894Ssamstatic int 179147894Ssamseptel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_) 180147894Ssam{ 181147894Ssam strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards", 182147894Ssam PCAP_ERRBUF_SIZE); 183147894Ssam return (-1); 184147894Ssam} 185147894Ssam 186147894Ssam/* 187190225Srpaulo * Activate a handle for a live capture from the given Septel device. Always pass a NULL device 188147894Ssam * The promisc flag is ignored because Septel cards have built-in tracing. 189190225Srpaulo * The timeout is also ignored as it is not supported in hardware. 190147894Ssam * 191147894Ssam * See also pcap(3). 192147894Ssam */ 193190225Srpaulostatic pcap_t *septel_activate(pcap_t* handle) { 194190225Srpaulo /* Initialize some components of the pcap structure. */ 195147894Ssam handle->linktype = DLT_MTP2; 196147894Ssam 197147894Ssam handle->bufsize = 0; 198147894Ssam 199147894Ssam /* 200147894Ssam * "select()" and "poll()" don't work on Septel queues 201147894Ssam */ 202147894Ssam handle->selectable_fd = -1; 203147894Ssam 204147894Ssam handle->read_op = septel_read; 205147894Ssam handle->inject_op = septel_inject; 206147894Ssam handle->setfilter_op = septel_setfilter; 207147894Ssam handle->set_datalink_op = NULL; /* can't change data link type */ 208147894Ssam handle->getnonblock_op = pcap_getnonblock_fd; 209147894Ssam handle->setnonblock_op = septel_setnonblock; 210147894Ssam handle->stats_op = septel_stats; 211147894Ssam 212190225Srpaulo return 0; 213190225Srpaulo} 214147894Ssam 215251129Sdelphijpcap_t *septel_create(const char *device, char *ebuf, int *is_ours) { 216251129Sdelphij const char *cp; 217190225Srpaulo pcap_t *p; 218147894Ssam 219251129Sdelphij /* Does this look like the Septel device? */ 220251129Sdelphij cp = strrchr(device, '/'); 221251129Sdelphij if (cp == NULL) 222251129Sdelphij cp = device; 223251129Sdelphij if (strcmp(cp, "septel") != 0) { 224251129Sdelphij /* Nope, it's not "septel" */ 225251129Sdelphij *is_ours = 0; 226251129Sdelphij return NULL; 227251129Sdelphij } 228251129Sdelphij 229251129Sdelphij /* OK, it's probably ours. */ 230251129Sdelphij *is_ours = 1; 231251129Sdelphij 232190225Srpaulo p = pcap_create_common(device, ebuf); 233190225Srpaulo if (p == NULL) 234190225Srpaulo return NULL; 235190225Srpaulo 236190225Srpaulo p->activate_op = septel_activate; 237190225Srpaulo return p; 238147894Ssam} 239147894Ssam 240147894Ssamstatic int septel_stats(pcap_t *p, struct pcap_stat *ps) { 241147894Ssam /*p->md.stat.ps_recv = 0;*/ 242147894Ssam /*p->md.stat.ps_drop = 0;*/ 243147894Ssam 244147894Ssam *ps = p->md.stat; 245147894Ssam 246147894Ssam return 0; 247147894Ssam} 248147894Ssam 249147894Ssam 250147894Ssamint 251251129Sdelphijseptel_findalldevs(pcap_if_t **devlistp, char *errbuf) 252147894Ssam{ 253147894Ssamunsigned char *p; 254147894Ssam const char description[512]= "Intel/Septel device"; 255147894Ssam char name[512]="septel" ; 256147894Ssam int ret = 0; 257147894Ssam pcap_add_if(devlistp,name,0,description,errbuf); 258147894Ssam 259147894Ssam return (ret); 260147894Ssam} 261147894Ssam 262147894Ssam 263147894Ssam/* 264147894Ssam * Installs the given bpf filter program in the given pcap structure. There is 265147894Ssam * no attempt to store the filter in kernel memory as that is not supported 266147894Ssam * with Septel cards. 267147894Ssam */ 268147894Ssamstatic int septel_setfilter(pcap_t *p, struct bpf_program *fp) { 269147894Ssam if (!p) 270147894Ssam return -1; 271147894Ssam if (!fp) { 272147894Ssam strncpy(p->errbuf, "setfilter: No filter specified", 273147894Ssam sizeof(p->errbuf)); 274147894Ssam return -1; 275147894Ssam } 276147894Ssam 277147894Ssam /* Make our private copy of the filter */ 278147894Ssam 279147894Ssam if (install_bpf_program(p, fp) < 0) { 280147894Ssam snprintf(p->errbuf, sizeof(p->errbuf), 281147894Ssam "malloc: %s", pcap_strerror(errno)); 282147894Ssam return -1; 283147894Ssam } 284147894Ssam 285147894Ssam p->md.use_bpf = 0; 286147894Ssam 287147894Ssam return (0); 288147894Ssam} 289147894Ssam 290147894Ssam 291147894Ssamstatic int 292147894Ssamseptel_setnonblock(pcap_t *p, int nonblock, char *errbuf) 293147894Ssam{ 294147894Ssam return (0); 295147894Ssam} 296