From: David Yat Sin Date: Tue, 9 Nov 2010 21:54:24 +0000 (-0500) Subject: Merge branch 'master' of git.sangoma.com:smg_freeswitch X-Git-Tag: v1.2-rc1~282^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9db28c25ff1d6d8e680b74ac6ddbc83eb029c9d;p=thirdparty%2Ffreeswitch.git Merge branch 'master' of git.sangoma.com:smg_freeswitch --- c9db28c25ff1d6d8e680b74ac6ddbc83eb029c9d diff --cc libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index d64e711e73,2b34552950..23e67426ca --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@@ -47,132 -43,126 +43,125 @@@ #include #endif - #include "ftdm_isdn.h" + #include "ftmod_isdn.h" #define LINE "--------------------------------------------------------------------------------" - //#define IODEBUG /* helper macros */ -#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP) #define FTDM_SPAN_IS_NT(x) (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT) + #define DEFAULT_NATIONAL_PREFIX "0" + #define DEFAULT_INTERNATIONAL_PREFIX "00" - #ifdef HAVE_LIBPCAP - /*-------------------------------------------------------------------------*/ - /*Q931ToPcap functions*/ + /***************************************************************************************** + * PCAP + * Based on Helmut Kuper's () implementation, + * but using a different approach (needs a recent libpcap + wireshark) + *****************************************************************************************/ + #ifdef HAVE_PCAP + #include /* htons() */ #include - #endif - #define SNAPLEN 1522 - #define MAX_ETHER_PAYLOAD_SIZE 1500 - #define MIN_ETHER_PAYLOAD_SIZE 42 - #define SIZE_ETHERNET 18 - #define VLANID_OFFSET 15 - #define SIZE_IP 20 - #define SIZE_TCP 20 - #define SIZE_TPKT 4 - #define SIZE_ETHERNET_CRC 4 - #define OVERHEAD SIZE_ETHERNET+SIZE_IP+SIZE_TCP+SIZE_TPKT - #define MAX_Q931_SIZE MAX_ETHER_PAYLOAD_SIZE-SIZE_IP-SIZE_TCP-SIZE_TPKT - #define TPKT_SIZE_OFFSET SIZE_ETHERNET+SIZE_IP+SIZE_TCP+2 - #define IP_SIZE_OFFSET SIZE_ETHERNET+2 - #define TCP_SEQ_OFFSET SIZE_ETHERNET+SIZE_IP+4 - - #ifdef HAVE_LIBPCAP - /*Some globals*/ - unsigned long pcapfilesize = 0; - unsigned long tcp_next_seq_no_send = 0; - unsigned long tcp_next_seq_no_rec = 0; - pcap_dumper_t *pcapfile = NULL; - struct pcap_pkthdr pcaphdr; - pcap_t *pcaphandle = NULL; - char *pcapfn = NULL; - int do_q931ToPcap= 0; - - /*Predefined Ethernet Frame with Q931-over-IP encapsulated - From remote TDM host to FreeSWITCH*/ - L3UCHAR recFrame[SNAPLEN]= { - /*IEEE 802.3 VLAN 802.1q Ethernet Frame Header*/ - 2,0,1,0xAA,0xAA,0xAA,2,0,1,0xBB,0xBB,0xBB,0x81,0,0xE0,0,0x08,0, - /*IPv4 Header (minimal size; no options)*/ - 0x45,0,0,44,0,0,0,0,64,6,0,0,2,2,2,2,1,1,1,1, - /*TCP-Header*/ - 0,0x66,0,0x66,0,0,0,0,0,0,0,0,0x50,0,0,1,0,0,0,0, - /*TPKT-Header RFC 1006*/ - 3,0,0,0 - }; - - /*Predefined Ethernet Frame with Q931-over-IP encapsulated - Frome FreeSWITCH to remote TDM host*/ - L3UCHAR sendFrame[SNAPLEN]= { - /*IEEE 802.3 VLAN 802.1q Ethernet Frame Header*/ - 2,0,1,0xBB,0xBB,0xBB,2,0,1,0xAA,0xAA,0xAA,0x81,0,0xE0,0,0x08,0, - /*IPv4 Header (minimal size; no options)*/ - 0x45,0,0,44,0,0,0,0,64,6,0,0,1,1,1,1,2,2,2,2, - /*TCP-Header*/ - 0,0x66,0,0x66,0,0,0,0,0,0,0,0,0x50,0,0,1,0,0,0,0, - /*TPKT-Header RFC 1006*/ - 3,0,0,0 - }; + #define PCAP_SNAPLEN 1500 - /** - * \brief Opens a pcap file for capture - * \return Success or failure - */ - static ftdm_status_t openPcapFile(void) + struct pcap_context { + pcap_dumper_t *dump; /*!< pcap file handle */ + pcap_t *handle; /*!< pcap lib context */ + char *filename; /*!< capture file name */ + }; + + static inline ftdm_status_t isdn_pcap_is_open(struct ftdm_isdn_data *isdn) { - if(!pcaphandle) - { - pcaphandle = pcap_open_dead(DLT_EN10MB, SNAPLEN); - if (!pcaphandle) - { - ftdm_log(FTDM_LOG_ERROR, "Can't open pcap session: (%s)\n", pcap_geterr(pcaphandle)); - return FTDM_FAIL; - } - } + return (isdn->pcap) ? 1 : 0; + } - if(!pcapfile){ - /* Open the dump file */ - if(!(pcapfile=pcap_dump_open(pcaphandle, pcapfn))){ - ftdm_log(FTDM_LOG_ERROR, "Error opening output file (%s)\n", pcap_geterr(pcaphandle)); - return FTDM_FAIL; - } - } - else{ - ftdm_log(FTDM_LOG_WARNING, "Pcap file is already open!\n"); - return FTDM_FAIL; - } + static inline ftdm_status_t isdn_pcap_capture_both(struct ftdm_isdn_data *isdn) + { + return ((isdn->flags & (FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY)) == FTDM_ISDN_CAPTURE) ? 1 : 0; + } - ftdm_log(FTDM_LOG_DEBUG, "Pcap file '%s' successfully opened!\n", pcapfn); + static inline ftdm_status_t isdn_pcap_capture_l3only(struct ftdm_isdn_data *isdn) + { + return ((isdn->flags & FTDM_ISDN_CAPTURE) && (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY)) ? 1 : 0; + } - pcaphdr.ts.tv_sec = 0; - pcaphdr.ts.tv_usec = 0; - pcapfilesize = 24; /*current pcap file header seems to be 24 bytes*/ - tcp_next_seq_no_send = 0; - tcp_next_seq_no_rec = 0; + static ftdm_status_t isdn_pcap_open(struct ftdm_isdn_data *isdn, char *filename) + { + struct pcap_context *pcap = NULL; - return FTDM_SUCCESS; + if (!isdn) { + return FTDM_FAIL; + } + + if (ftdm_strlen_zero(filename)) { + return FTDM_FAIL; + } + + pcap = malloc(sizeof(struct pcap_context)); + if (!pcap) { + ftdm_log(FTDM_LOG_ERROR, "Failed to allocate isdn pcap context\n"); + return FTDM_FAIL; + } + + memset(pcap, 0, sizeof(struct pcap_context)); + + pcap->filename = strdup(filename); + + pcap->handle = pcap_open_dead(DLT_LINUX_LAPD, PCAP_SNAPLEN); + if (!pcap->handle) { + ftdm_log(FTDM_LOG_ERROR, "Failed to open pcap handle\n"); + goto error; + } + + pcap->dump = pcap_dump_open(pcap->handle, pcap->filename); + if (!pcap->dump) { + ftdm_log(FTDM_LOG_ERROR, "Failed to open capture file: %s\n", pcap_geterr(pcap->handle)); + goto error; + } + + ftdm_log(FTDM_LOG_INFO, "Capture file \"%s\" opened\n", pcap->filename); + + isdn->pcap = pcap; + + return FTDM_SUCCESS; + + error: + if (pcap->handle) { + pcap_close(pcap->handle); + } + if (pcap->filename) { + free(pcap->filename); + } + + free(pcap); + + return FTDM_FAIL; } - /** - * \brief Closes a pcap file - * \return Success - */ - static ftdm_status_t closePcapFile(void) + static ftdm_status_t isdn_pcap_close(struct ftdm_isdn_data *isdn) { - if (pcapfile) { - pcap_dump_close(pcapfile); - if (pcaphandle) pcap_close(pcaphandle); - - ftdm_log(FTDM_LOG_DEBUG, "Pcap file closed! File size is %lu bytes.\n", pcapfilesize); + struct pcap_context *pcap = NULL; + long size; - pcaphdr.ts.tv_sec = 0; - pcaphdr.ts.tv_usec = 0; - pcapfile = NULL; - pcaphandle = NULL; - pcapfilesize = 0; - tcp_next_seq_no_send = 0; - tcp_next_seq_no_rec = 0; + if (!isdn || !isdn->pcap) { + return FTDM_FAIL; } + pcap = isdn->pcap; + + isdn->flags &= ~(FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY); + isdn->pcap = NULL; + + pcap_dump_flush(pcap->dump); + + size = pcap_dump_ftell(pcap->dump); + ftdm_log(FTDM_LOG_INFO, "File \"%s\" captured %ld bytes of data\n", pcap->filename, size); + + pcap_dump_close(pcap->dump); + pcap_close(pcap->handle); + + free(pcap->filename); + free(pcap); - /*We have allways success with this? I think so*/ return FTDM_SUCCESS; }