libpcap  1.10.1
About: libpcap is a packet filter library used by tools like tcpdump.
  Fossies Dox: libpcap-1.10.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

pcap-septel.c
Go to the documentation of this file.
1 /*
2  * pcap-septel.c: Packet capture interface for Intel/Septel card.
3  *
4  * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
5  * (+961 3 485243)
6  */
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <sys/param.h>
13 
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 
18 #include "pcap-int.h"
19 
20 #include <netinet/in.h>
21 #include <sys/mman.h>
22 #include <sys/socket.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include <msg.h>
27 #include <ss7_inc.h>
28 #include <sysgct.h>
29 #include <pack.h>
30 #include <system.h>
31 
32 #include "pcap-septel.h"
33 
34 static int septel_stats(pcap_t *p, struct pcap_stat *ps);
35 static int septel_getnonblock(pcap_t *p);
36 static int septel_setnonblock(pcap_t *p, int nonblock);
37 
38 /*
39  * Private data for capturing on Septel devices.
40  */
41 struct pcap_septel {
42  struct pcap_stat stat;
43 }
44 
45 /*
46  * Read at most max_packets from the capture queue and call the callback
47  * for each of them. Returns the number of packets handled, -1 if an
48  * error occurred, or -2 if we were told to break out of the loop.
49  */
50 static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
51 
52  struct pcap_septel *ps = p->priv;
53  HDR *h;
54  MSG *m;
55  int processed = 0 ;
56  int t = 0 ;
57 
58  /* identifier for the message queue of the module(upe) from which we are capturing
59  * packets.These IDs are defined in system.txt . By default it is set to 0x2d
60  * so change it to 0xdd for technical reason and therefore the module id for upe becomes:
61  * LOCAL 0xdd * upe - Example user part task */
62  unsigned int id = 0xdd;
63 
64  /* process the packets */
65  do {
66 
67  unsigned short packet_len = 0;
68  int caplen = 0;
69  int counter = 0;
70  struct pcap_pkthdr pcap_header;
71  u_char *dp ;
72 
73  /*
74  * Has "pcap_breakloop()" been called?
75  */
76 loop:
77  if (p->break_loop) {
78  /*
79  * Yes - clear the flag that indicates that
80  * it has, and return -2 to indicate that
81  * we were told to break out of the loop.
82  */
83  p->break_loop = 0;
84  return -2;
85  }
86 
87  /*repeat until a packet is read
88  *a NULL message means :
89  * when no packet is in queue or all packets in queue already read */
90  do {
91  /* receive packet in non-blocking mode
92  * GCT_grab is defined in the septel library software */
93  h = GCT_grab(id);
94 
95  m = (MSG*)h;
96  /* a couter is added here to avoid an infinite loop
97  * that will cause our capture program GUI to freeze while waiting
98  * for a packet*/
99  counter++ ;
100 
101  }
102  while ((m == NULL)&& (counter< 100)) ;
103 
104  if (m != NULL) {
105 
106  t = h->type ;
107 
108  /* catch only messages with type = 0xcf00 or 0x8f01 corrsponding to ss7 messages*/
109  /* XXX = why not use API_MSG_TX_REQ for 0xcf00 and API_MSG_RX_IND
110  * for 0x8f01? */
111  if ((t != 0xcf00) && (t != 0x8f01)) {
112  relm(h);
113  goto loop ;
114  }
115 
116  /* XXX - is API_MSG_RX_IND for an MTP2 or MTP3 message? */
117  dp = get_param(m);/* get pointer to MSG parameter area (m->param) */
118  packet_len = m->len;
119  caplen = p->snapshot ;
120 
121 
122  if (caplen > packet_len) {
123 
124  caplen = packet_len;
125  }
126  /* Run the packet filter if there is one. */
127  if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
128 
129 
130  /* get a time stamp , consisting of :
131  *
132  * pcap_header.ts.tv_sec:
133  * ----------------------
134  * a UNIX format time-in-seconds when he packet was captured,
135  * i.e. the number of seconds since Epoch time (January 1,1970, 00:00:00 GMT)
136  *
137  * pcap_header.ts.tv_usec :
138  * ------------------------
139  * the number of microseconds since that second
140  * when the packet was captured
141  */
142 
143  (void)gettimeofday(&pcap_header.ts, NULL);
144 
145  /* Fill in our own header data */
146  pcap_header.caplen = caplen;
147  pcap_header.len = packet_len;
148 
149  /* Count the packet. */
150  ps->stat.ps_recv++;
151 
152  /* Call the user supplied callback function */
153  callback(user, &pcap_header, dp);
154 
155  processed++ ;
156 
157  }
158  /* after being processed the packet must be
159  *released in order to receive another one */
160  relm(h);
161  }else
162  processed++;
163 
164  }
165  while (processed < cnt) ;
166 
167  return processed ;
168 }
169 
170 
171 static int
172 septel_inject(pcap_t *handle, const void *buf _U_, int size _U_)
173 {
174  pcap_strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
176  return (-1);
177 }
178 
179 /*
180  * Activate a handle for a live capture from the given Septel device. Always pass a NULL device
181  * The promisc flag is ignored because Septel cards have built-in tracing.
182  * The timeout is also ignored as it is not supported in hardware.
183  *
184  * See also pcap(3).
185  */
186 static pcap_t *septel_activate(pcap_t* handle) {
187  /* Initialize some components of the pcap structure. */
188  handle->linktype = DLT_MTP2;
189 
190  /*
191  * Turn a negative snapshot value (invalid), a snapshot value of
192  * 0 (unspecified), or a value bigger than the normal maximum
193  * value, into the maximum allowed value.
194  *
195  * If some application really *needs* a bigger snapshot
196  * length, we should just increase MAXIMUM_SNAPLEN.
197  */
198  if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
199  handle->snapshot = MAXIMUM_SNAPLEN;
200 
201  handle->bufsize = 0;
202 
203  /*
204  * "select()" and "poll()" don't work on Septel queues
205  */
206  handle->selectable_fd = -1;
207 
208  handle->read_op = septel_read;
209  handle->inject_op = septel_inject;
211  handle->set_datalink_op = NULL; /* can't change data link type */
214  handle->stats_op = septel_stats;
215 
216  return 0;
217 }
218 
219 pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
220  const char *cp;
221  pcap_t *p;
222 
223  /* Does this look like the Septel device? */
224  cp = strrchr(device, '/');
225  if (cp == NULL)
226  cp = device;
227  if (strcmp(cp, "septel") != 0) {
228  /* Nope, it's not "septel" */
229  *is_ours = 0;
230  return NULL;
231  }
232 
233  /* OK, it's probably ours. */
234  *is_ours = 1;
235 
236  p = PCAP_CREATE_COMMON(ebuf, struct pcap_septel);
237  if (p == NULL)
238  return NULL;
239 
241  /*
242  * Set these up front, so that, even if our client tries
243  * to set non-blocking mode before we're activated, or
244  * query the state of non-blocking mode, they get an error,
245  * rather than having the non-blocking mode option set
246  * for use later.
247  */
250  return p;
251 }
252 
253 static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
254  struct pcap_septel *handlep = p->priv;
255  /*handlep->stat.ps_recv = 0;*/
256  /*handlep->stat.ps_drop = 0;*/
257 
258  *ps = handlep->stat;
259 
260  return 0;
261 }
262 
263 
264 int
265 septel_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
266 {
267  /*
268  * XXX - do the notions of "up", "running", or "connected" apply here?
269  */
270  if (add_dev(devlistp,"septel",0,"Intel/Septel device",errbuf) == NULL)
271  return -1;
272  return 0;
273 }
274 
275 
276 /*
277  * We don't support non-blocking mode. I'm not sure what we'd
278  * do to support it and, given that we don't support select()/
279  * poll()/epoll_wait()/kevent() etc., it probably doesn't
280  * matter.
281  */
282 static int
284 {
285  fprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
286  return (-1);
287 }
288 
289 static int
290 septel_setnonblock(pcap_t *p, int nonblock _U_)
291 {
292  fprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
293  return (-1);
294 }
295 
296 #ifdef SEPTEL_ONLY
297 /*
298  * This libpcap build supports only Septel cards, not regular network
299  * interfaces.
300  */
301 
302 /*
303  * There are no regular interfaces, just Septel interfaces.
304  */
305 int
306 pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
307 {
308  return (0);
309 }
310 
311 /*
312  * Attempts to open a regular interface fail.
313  */
314 pcap_t *
315 pcap_create_interface(const char *device, char *errbuf)
316 {
317  snprintf(errbuf, PCAP_ERRBUF_SIZE,
318  "This version of libpcap only supports Septel cards");
319  return (NULL);
320 }
321 
322 /*
323  * Libpcap version string.
324  */
325 const char *
326 pcap_lib_version(void)
327 {
328  return (PCAP_VERSION_STRING " (Septel-only)");
329 }
330 #endif
u_int pcap_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, u_int buflen)
Definition: bpf_filter.c:391
#define DLT_MTP2
Definition: dlt.h:458
int install_bpf_program(pcap_t *p, struct bpf_program *fp)
Definition: optimize.c:2939
int snprintf(char *, size_t, const char *,...)
int gettimeofday(struct timeval *, struct timezone *)
const char * pcap_lib_version(void)
Definition: pcap-bpf.c:3590
int pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
Definition: pcap-bpf.c:2995
pcap_t * pcap_create_interface(const char *device, char *ebuf)
Definition: pcap-bpf.c:443
#define _U_
Definition: pcap-dos.h:93
#define MAXIMUM_SNAPLEN
Definition: pcap-int.h:131
pcap_if_t * add_dev(pcap_if_list_t *, const char *, bpf_u_int32, const char *, char *)
Definition: pcap.c:1308
#define PCAP_VERSION_STRING
Definition: pcap-int.h:59
#define PCAP_CREATE_COMMON(ebuf, type)
Definition: pcap-int.h:474
int septel_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
Definition: pcap-septel.c:265
static int septel_inject(pcap_t *handle, const void *buf, int size)
Definition: pcap-septel.c:172
static int septel_setnonblock(pcap_t *p, int nonblock)
Definition: pcap-septel.c:290
struct pcap_septel septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
Definition: pcap-septel.c:50
static pcap_t * septel_activate(pcap_t *handle)
Definition: pcap-septel.c:186
static int septel_stats(pcap_t *p, struct pcap_stat *ps)
Definition: pcap-septel.c:253
static int septel_getnonblock(pcap_t *p)
Definition: pcap-septel.c:283
pcap_t * septel_create(const char *device, char *ebuf, int *is_ours)
Definition: pcap-septel.c:219
void(* pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *)
Definition: pcap.h:330
#define PCAP_ERRBUF_SIZE
Definition: pcap.h:152
size_t pcap_strlcpy(char *restrict dst, const char *restrict src, size_t dsize)
Definition: strlcpy.c:34
struct bpf_insn * bf_insns
Definition: bpf.h:119
bpf_u_int32 caplen
Definition: pcap.h:247
struct pcap_stat stat
Definition: pcap-septel.c:42
u_int ps_recv
Definition: pcap.h:255
Definition: pcap-int.h:200
stats_op_t stats_op
Definition: pcap-int.h:320
activate_op_t activate_op
Definition: pcap-int.h:311
setnonblock_op_t setnonblock_op
Definition: pcap-int.h:319
setfilter_op_t setfilter_op
Definition: pcap-int.h:315
sig_atomic_t break_loop
Definition: pcap-int.h:225
u_int bufsize
Definition: pcap-int.h:220
void * priv
Definition: pcap-int.h:227
getnonblock_op_t getnonblock_op
Definition: pcap-int.h:318
read_op_t read_op
Definition: pcap-int.h:204
int snapshot
Definition: pcap-int.h:247
inject_op_t inject_op
Definition: pcap-int.h:313
struct bpf_program fcode
Definition: pcap-int.h:293
set_datalink_op_t set_datalink_op
Definition: pcap-int.h:317
char errbuf[256+1]
Definition: pcap-int.h:295
int linktype
Definition: pcap-int.h:248
int selectable_fd
Definition: pcap-int.h:274