]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Merge branch 'master' of git.sangoma.com:smg_freeswitch
authorDavid Yat Sin <dyatsin@sangoma.com>
Tue, 9 Nov 2010 21:54:24 +0000 (16:54 -0500)
committerDavid Yat Sin <dyatsin@sangoma.com>
Tue, 9 Nov 2010 21:54:24 +0000 (16:54 -0500)
1  2 
libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c
libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c

index d64e711e73e22d584efbc442f4fdc234c6f57699,2b34552950fcdaada2ec8e00b6b51c449a8dbcd6..23e67426ca1a1115b608505acd2c366ace2e9b41
  #include <sys/time.h>
  #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 (<helmut.kuper@ewetel.de>) implementation,
+  *          but using a different approach (needs a recent libpcap + wireshark)
+  *****************************************************************************************/
+ #ifdef HAVE_PCAP
+ #include <arpa/inet.h>                /* htons() */
  #include <pcap.h>
- #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;
  }