]>
The Tcpdump Group git mirrors - libpcap/blob - pcap-septel.c
2 * pcap-septel.c: Packet capture interface for Intel/Septel card.
4 * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
12 #include <sys/param.h>
20 #include <netinet/in.h>
22 #include <sys/socket.h>
23 #include <sys/types.h>
32 #include "pcap-septel.h"
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
);
39 * Private data for capturing on Septel devices.
42 struct pcap_stat stat
;
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.
50 static int septel_read(pcap_t
*p
, int cnt
, pcap_handler callback
, u_char
*user
) {
52 struct pcap_septel
*ps
= p
->priv
;
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;
64 /* process the packets */
67 unsigned short packet_len
= 0;
70 struct pcap_pkthdr pcap_header
;
74 * Has "pcap_breakloop()" been called?
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.
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 */
91 /* receive packet in non-blocking mode
92 * GCT_grab is defined in the septel library software */
96 /* a counter is added here to avoid an infinite loop
97 * that will cause our capture program GUI to freeze while waiting
102 while ((m
== NULL
)&& (counter
< 100)) ;
108 /* catch only messages with type = 0xcf00 or 0x8f01 corresponding to ss7 messages*/
109 /* XXX = why not use API_MSG_TX_REQ for 0xcf00 and API_MSG_RX_IND
111 if ((t
!= 0xcf00) && (t
!= 0x8f01)) {
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) */
119 caplen
= p
->snapshot
;
122 if (caplen
> packet_len
) {
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
)) {
130 /* get a time stamp , consisting of :
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)
137 * pcap_header.ts.tv_usec :
138 * ------------------------
139 * the number of microseconds since that second
140 * when the packet was captured
143 (void)gettimeofday(&pcap_header
.ts
, NULL
);
145 /* Fill in our own header data */
146 pcap_header
.caplen
= caplen
;
147 pcap_header
.len
= packet_len
;
149 /* Count the packet. */
152 /* Call the user supplied callback function */
153 callback(user
, &pcap_header
, dp
);
158 /* after being processed the packet must be
159 *released in order to receive another one */
165 while (processed
< cnt
) ;
172 septel_inject(pcap_t
*handle
, const void *buf _U_
, int size _U_
)
174 pcap_strlcpy(handle
->errbuf
, "Sending packets isn't supported on Septel cards",
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.
186 static pcap_t
*septel_activate(pcap_t
* handle
) {
187 /* Initialize some components of the pcap structure. */
188 handle
->linktype
= DLT_MTP2
;
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.
195 * If some application really *needs* a bigger snapshot
196 * length, we should just increase MAXIMUM_SNAPLEN.
198 if (handle
->snapshot
<= 0 || handle
->snapshot
> MAXIMUM_SNAPLEN
)
199 handle
->snapshot
= MAXIMUM_SNAPLEN
;
204 * "select()" and "poll()" don't work on Septel queues
206 handle
->selectable_fd
= -1;
208 handle
->read_op
= septel_read
;
209 handle
->inject_op
= septel_inject
;
210 handle
->setfilter_op
= pcap_install_bpf_program
;
211 handle
->set_datalink_op
= NULL
; /* can't change data link type */
212 handle
->getnonblock_op
= septel_getnonblock
;
213 handle
->setnonblock_op
= septel_setnonblock
;
214 handle
->stats_op
= septel_stats
;
219 pcap_t
*septel_create(const char *device
, char *ebuf
, int *is_ours
) {
223 /* Does this look like the Septel device? */
224 cp
= strrchr(device
, '/');
227 if (strcmp(cp
, "septel") != 0) {
228 /* Nope, it's not "septel" */
233 /* OK, it's probably ours. */
236 p
= PCAP_CREATE_COMMON(ebuf
, struct pcap_septel
);
240 p
->activate_op
= septel_activate
;
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
248 p
->getnonblock_op
= septel_getnonblock
;
249 p
->setnonblock_op
= septel_setnonblock
;
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;*/
265 septel_findalldevs(pcap_if_list_t
*devlistp
, char *errbuf
)
268 * XXX - do the notions of "up", "running", or "connected" apply here?
270 if (pcap_add_dev(devlistp
,"septel",0,"Intel/Septel device",errbuf
) == NULL
)
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
283 septel_getnonblock(pcap_t
*p
)
285 fprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "Non-blocking mode not supported on Septel devices");
290 septel_setnonblock(pcap_t
*p
, int nonblock _U_
)
292 fprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "Non-blocking mode not supported on Septel devices");
298 * This libpcap build supports only Septel cards, not regular network
303 * There are no regular interfaces, just Septel interfaces.
306 pcap_platform_finddevs(pcap_if_list_t
*devlistp
, char *errbuf
)
312 * Attempts to open a regular interface fail.
315 pcap_create_interface(const char *device
, char *errbuf
)
317 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
318 "This version of libpcap only supports Septel cards");
323 * Libpcap version string.
326 pcap_lib_version(void)
328 return (PCAP_VERSION_STRING
" (Septel-only)");