LInux under the SIP protocol tracking

2011-01-10  来源:本站原创  分类:Internet  人气:116 

This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document,
Be used for any commercial purposes is strictly prohibited.
msn: [email protected]
Source: http://yfydz.cublog.cn

1.   Foreword  

SIP(Session Initiation Protocol)  Defined in RFC3261 for the text of an agreement to establish a session  ,  Used for VoIP and other
  Media applications, its format and  HTTP  Similarly, first  SIP  The first definition, then the specific data  .

  Currently linux2.6 kernel has been formally  SIP  Tracking and NAT processing into  ,  Shows that the module should be available over a sufficient test to prove a  .
  The following version of Linux kernel code  2.6.19.2.

2. SIP  Basic information format  

SIP  Application layer protocol itself defines only the data for the transport layer protocol is  TCP  There is no limit or UDP  ,  SIP only defines the service port is
5060.
  Provided the following uses RFC3665  SIP  SIP application example to describe the process of  ,  For the NAT device from which it can know what needs modification in
  Content information  .
2.1   Registration process
    Bob                        SIP Server
     |                               |
     |          REGISTER F1          |
     |------------------------------>|
     |      401 Unauthorized F2      |
     |<------------------------------|
     |          REGISTER F3          |
     |------------------------------>|
     |            200 OK F4          |
     |<------------------------------|
     |                               |
   Message Details
   F1 REGISTER Bob -> SIP Server
   REGISTER sips:ss2.biloxi.example.com SIP/2.0
   Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
   Max-Forwards: 70
   From: Bob <sips:[email protected]>;tag=a73kszlfl
   To: Bob <sips:[email protected]>
   Call-ID: [email protected]
   CSeq: 1 REGISTER
   Contact: <sips:[email protected]>
   Content-Length: 0

   F2 401 Unauthorized SIP Server -> Bob
   SIP/2.0 401 Unauthorized
   Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
    ;received=192.0.2.201
   From: Bob <sips:[email protected]>;tag=a73kszlfl
   To: Bob <sips:[email protected]>;tag=1410948204
   Call-ID: [email protected]
   CSeq: 1 REGISTER
   WWW-Authenticate: Digest realm="atlanta.example.com", qop="auth",
    nonce="ea9c8e88df84f1cec4341ae6cbe5a359",
    opaque="", stale=FALSE, algorithm=MD5
   Content-Length: 0

   F3 REGISTER Bob -> SIP Server
   REGISTER sips:ss2.biloxi.example.com SIP/2.0
   Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92
   Max-Forwards: 70
   From: Bob <sips:[email protected]>;tag=ja743ks76zlflH
   To: Bob <sips:[email protected]>
   Call-ID: [email protected]
   CSeq: 2 REGISTER
   Contact: <sips:[email protected]>
   Authorization: Digest username="bob", realm="atlanta.example.com"
    nonce="ea9c8e88df84f1cec4341ae6cbe5a359", opaque="",
    uri="sips:ss2.biloxi.example.com",
    response="dfe56131d1958046689d83306477ecc"
   Content-Length: 0

   F4 200 OK SIP Server -> Bob
   SIP/2.0 200 OK
   Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92
    ;received=192.0.2.201
   From: Bob <sips:[email protected]>;tag=ja743ks76zlflH
   To: Bob <sips:[email protected]>;tag=37GkEhwl6
   Call-ID: [email protected]
   CSeq: 2 REGISTER
   Contact: <sips:[email protected]>;expires=3600
   Content-Length: 0
  Thus, in  "Via:"."From:"."To:"."Call-ID:"."Contact:"  Address and other fields that have
  The ID, for most of the machines is not a domain name  ,  Only by the IP address that  ,  Therefore, the NAT device must be able to modify the values ​​of these fields  .

2.2 SIP  Data communication transmission  

SIP  Data transfer with the  SDP(Session Description Protocol, RFC4566)  Protocol to describe the data channel information  :

   Alice                     Bob
     |                        |
     |       INVITE F1        |
     |----------------------->|
     |    180 Ringing F2      |
     |<-----------------------|
     |                        |
     |       200 OK F3        |
     |<-----------------------|
     |         ACK F4         |
     |----------------------->|
     |   Both Way RTP Media   |
     |<======================>|
     |                        |
     |         BYE F5         |
     |<-----------------------|
     |       200 OK F6        |
     |----------------------->|
     |                        |
   F1 INVITE Alice -> Bob
   INVITE sip:[email protected] SIP/2.0
   Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
   Max-Forwards: 70
   From: Alice <sip:[email protected]>;tag=9fxced76sl
   To: Bob <sip:[email protected]>
   Call-ID: [email protected]
   CSeq: 1 INVITE
   Contact: <sip:[email protected];transport=tcp>
   Content-Type: application/sdp
   Content-Length: 151
   v=0
   o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com
   s=-
   c=IN IP4 192.0.2.101
   t=0 0
   m=audio 49172 RTP/AVP 0
   a=rtpmap:0 PCMU/8000

   F2 180 Ringing Bob -> Alice
   SIP/2.0 180 Ringing
   Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
    ;received=192.0.2.101
   From: Alice <sip:[email protected]>;tag=9fxced76sl
   To: Bob <sip:[email protected]>;tag=8321234356
   Call-ID: [email protected]
   CSeq: 1 INVITE
   Contact: <sip:[email protected];transport=tcp>
   Content-Length: 0

   F3 200 OK Bob -> Alice
   SIP/2.0 200 OK
   Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
    ;received=192.0.2.101
   From: Alice <sip:[email protected]>;tag=9fxced76sl
   To: Bob <sip:[email protected]>;tag=8321234356
   Call-ID: [email protected]
   CSeq: 1 INVITE
   Contact: <sip:[email protected];transport=tcp>
   Content-Type: application/sdp
   Content-Length: 147
   v=0
   o=bob 2890844527 2890844527 IN IP4 client.biloxi.example.com
   s=-
   c=IN IP4 192.0.2.201
   t=0 0
   m=audio 3456 RTP/AVP 0
   a=rtpmap:0 PCMU/8000
   F4 ACK Alice -> Bob
   ACK sip:[email protected] SIP/2.0
   Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bd5
   Max-Forwards: 70
   From: Alice <sip:[email protected]>;tag=9fxced76sl
   To: Bob <sip:[email protected]>;tag=8321234356
   Call-ID: [email protected]ple.com
   CSeq: 1 ACK
   Content-Length: 0
   /* RTP streams are established between Alice and Bob */
   /* Bob Hangs Up with Alice. Note that the CSeq is NOT 2, since
      Alice and Bob maintain their own independent CSeq counts.
      (The INVITE was request 1 generated by Alice, and the BYE is
      request 1 generated by Bob) */

   F5 BYE Bob -> Alice
   BYE sip:[email protected] SIP/2.0
   Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
   Max-Forwards: 70
   From: Bob <sip:[email protected]>;tag=8321234356
   To: Alice <sip:[email protected]>;tag=9fxced76sl
   Call-ID: [email protected]
   CSeq: 1 BYE
   Content-Length: 0

   F6 200 OK Alice -> Bob
   SIP/2.0 200 OK
   Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
    ;received=192.0.2.201
   From: Bob <sip:[email protected]>;tag=8321234356
   To: Alice <sip:[email protected]>;tag=9fxced76sl
   Call-ID: [email protected]
   CSeq: 1 BYE
   Content-Length: 0

  Seen in  SDP  Definition of the data, "o =". "C =" in the address information  ,"m="  In media communication with the port information, which
  Need to modify the NAT device  ,  If the modified SDP data length changes  ,  You should modify the SIP header  "Content-Length:"
  Field values  .

3. SIP  Track  

SIP  Track processing file net/ipv4/netfilter/ip_conntrack.sip.c, header files for the
include/linux/netfilter_ipv4/ip_conntrack_sip.h.

3.1   Initialization  

static int __init init(void)
{
 int i, ret;
 char *tmpname;
 if (ports_c == 0)
  ports[ports_c++] = SIP_PORT;
 for (i = 0; i < ports_c; i++) {
//   The following definition of the SIP  ip_conntrack_helper  Structural parameters
  /* Create helper structure */
  memset(&sip[i], 0, sizeof(struct ip_conntrack_helper));
//   Using the UDP protocol only deals  SIP
//   Simplified a lot using the UDP protocol processing  ,  Such as TCP sequence number tracking
  sip[i].tuple.dst.protonum = IPPROTO_UDP;
//   Trace port, the default  5060
  sip[i].tuple.src.u.udp.port = htons(ports[i]);
// tuple  Mask
  sip[i].mask.src.u.udp.port = htons(0xFFFF);
  sip[i].mask.dst.protonum = 0xFF;
//   Maximum number of concurrent connections to 2 children
  sip[i].max_expected = 2;
// 3  The sub-minute connection timeout
  sip[i].timeout = 3 * 60; /* 3 minutes */
  sip[i].me = THIS_MODULE;
//   Tracking help function
  sip[i].help = sip_help;
// helper  Name
  tmpname = &sip_names[i][0];
  if (ports[i] == SIP_PORT)
   sprintf(tmpname, "sip");
  else
   sprintf(tmpname, "sip-%d", i);
  sip[i].name = tmpname;
  DEBUGP("port #%d: %d\n", i, ports[i]);
//   Registration tracking function
  ret = ip_conntrack_helper_register(&sip[i]);
  if (ret) {
   printk("ERROR registering helper for port %d\n",
    ports[i]);
   fini();
   return ret;
  }
 }
 return 0;
}

3.2 sip_help

static int sip_help(struct sk_buff **pskb,
      struct ip_conntrack *ct,
      enum ip_conntrack_info ctinfo)
{
 unsigned int dataoff, datalen;
 const char *dptr;
 int ret = NF_ACCEPT;
 int matchoff, matchlen;
 __be32 ipaddr;
 u_int16_t port;
 /* No Data ? */
// dataoff  For the ip header plus  UDP  Head length
 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
 if (dataoff >= (*pskb)->len) {
// dataoff  Than or equal to the length of the entire IP packet data  ,   No application data
  DEBUGP("skb->len = %u\n", (*pskb)->len);
  return NF_ACCEPT;
        }
//   Update about the connection timeout, use the  sip  Specifically defined timeout value instead of the standard UDP timeout  (30  Second )
//   Default 3600 seconds
 ip_ct_refresh(ct, *pskb, sip_timeout * HZ);
//   If this package is non-linear, does not deal with  ,  Package deal only with linear
//   In fact, you can use to handle it can continue parsing skb_make_writable
 if (!skb_is_nonlinear(*pskb))
//   Begin parsing the data from the application layer
  dptr = (*pskb)->data + dataoff;
 else {
  DEBUGP("Copy of skbuff not supported yet.\n");
  goto out;
 }
 if (ip_nat_sip_hook) {
//   If you define a SIP NAT, change  SIP  Header information
  if (!ip_nat_sip_hook(pskb, ctinfo, ct, &dptr)) {
   ret = NF_DROP;
   goto out;
  }
 }
 /* After this point NAT, could have mangled skb, so
    we need to recalculate payload lenght. */
//   Data length
 datalen = (*pskb)->len - dataoff;
//   Check and modify the following key part of the SDP information
//   Legal minimum length check
 if (datalen < (sizeof("SIP/2.0 200") - 1))
  goto out;
 /* RTP info only in some SDP pkts */
// SDP  The definition of RTP information only in dealing with the initiator  INVITE  Package and the corresponding side of the 200 information
//   The other is not dealing with
 if (memcmp(dptr, "INVITE", sizeof("INVITE") - 1) != 0 &&
     memcmp(dptr, "SIP/2.0 200", sizeof("SIP/2.0 200") - 1) != 0) {
  goto out;
 }
 /* Get ip and port address from SDP packet. */
//   Find the SDP  "c="  Information, matchoff relative starting offset for the address
 if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
                     &ct_sip_hdrs[POS_CONNECTION]) > 0) {
  /* We'll drop only if there are parse problems. */
//   Resolution "c =" in the address information  ,   Failure loss
  if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr,
                   dptr + datalen) < 0) {
   ret = NF_DROP;
   goto out;
  }
//   Find the SDP  "m="  Information, matchoff relative starting offset for the port
  if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
                      &ct_sip_hdrs[POS_MEDIA]) > 0) {
//   Access to port
   port = simple_strtoul(dptr + matchoff, NULL, 10);
//   Port can not be privileged port, the port can only be general
   if (port < 1024) {
    ret = NF_DROP;
    goto out;
   }
//   Sub-connection information to establish expectations
   ret = set_expected_rtp(pskb, ct, ctinfo,
            ipaddr, port, dptr);
  }
 }
out:
 return ret;
}

3.3 ct_sip_get_info

  The function specified in the sip data to find patterns  ,  Acquisition mode the offset and length
/* Returns 0 if not found, -1 error parsing. */
// dptr  Starting point for the buffer, dlen for the buffer length
// matchoff  And matchlen as the return value of success  ,   Record is the length of the search pattern offset information
// hnfo  To find the model information for the pointer
int ct_sip_get_info(const char *dptr, size_t dlen,
      unsigned int *matchoff,
      unsigned int *matchlen,
      struct sip_header_nfo *hnfo)
{
 const char *limit, *aux, *k = dptr;
 int shift = 0;
//   Find the end point
 limit = dptr + (dlen - hnfo->lnlen);
 while (dptr <= limit) {
//   Find two linear mode  : lname  And sname, lname is the full name  , sname  Is the abbreviation of the name, both are legitimate
//   Note that using a case sensitive strncmp, seems to use  strnicmp  Better
  if ((strncmp(dptr, hnfo->lname, hnfo->lnlen) != 0) &&
      (strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) {
   dptr++;
   continue;
  }
//   Find mode
//   Find ln_str in the current line marking information  ,  As  "UDP", "sip:"  So, this is an ordinary string search function
  aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen,
                      ct_sip_lnlen(dptr, limit));
  if (!aux) {
//   No sign, error
   DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
          hnfo->lname);
   return -1;
  }
// aux  Skip logo Length
  aux += hnfo->ln_strlen;
//   Calculate the length of the pattern matching, shift from  aux  To the actual address offset mode
  *matchlen = hnfo->match_len(aux, limit, &shift);
//   If length is 0 for the match error
  if (!*matchlen)
   return -1;
//   Data offset relative to the first mode, skip the sign itself
  *matchoff = (aux - k) + shift;
  DEBUGP("%s match succeeded! - len: %u\n", hnfo->lname,
         *matchlen);
  return 1;
 }
 DEBUGP("%s header not found.\n", hnfo->lname);
 return 0;
}

  To find the data model defined as follows  :
//   SIP header used to find  "Via:"."Contact:"."Content-Length:"
// SDP  Head of the "m =". "V =". "O =". "C =", etc.
struct sip_header_nfo ct_sip_hdrs[] = {
 {  /* Via header */
  .lname  = "Via:",
  .lnlen  = sizeof("Via:") - 1,
  .sname  = "\r\nv:",
  .snlen  = sizeof("\r\nv:") - 1, /* rfc3261 "\r\n" */
  .ln_str  = "UDP ",
  .ln_strlen = sizeof("UDP ") - 1,
  .match_len = epaddr_len,
 },
 {  /* Contact header */
  .lname  = "Contact:",
  .lnlen  = sizeof("Contact:") - 1,
  .sname  = "\r\nm:",
  .snlen  = sizeof("\r\nm:") - 1,
  .ln_str  = "sip:",
  .ln_strlen = sizeof("sip:") - 1,
  .match_len = skp_epaddr_len
 },
 {  /* Content length header */
  .lname  = "Content-Length:",
  .lnlen  = sizeof("Content-Length:") - 1,
  .sname  = "\r\nl:",
  .snlen  = sizeof("\r\nl:") - 1,
  .ln_str  = ":",
  .ln_strlen = sizeof(":") - 1,
  .match_len = skp_digits_len
 },
 { /* SDP media info */
  .lname  = "\nm=",
  .lnlen  = sizeof("\nm=") - 1,
  .sname  = "\rm=",
  .snlen  = sizeof("\rm=") - 1,
  .ln_str  = "audio ",
  .ln_strlen = sizeof("audio ") - 1,
  .match_len = digits_len
 },
 {  /* SDP owner address*/
  .lname  = "\no=",
  .lnlen  = sizeof("\no=") - 1,
  .sname  = "\ro=",
  .snlen  = sizeof("\ro=") - 1,
  .ln_str  = "IN IP4 ",
  .ln_strlen = sizeof("IN IP4 ") - 1,
  .match_len = epaddr_len
 },
 {  /* SDP connection info */
  .lname  = "\nc=",
  .lnlen  = sizeof("\nc=") - 1,
  .sname  = "\rc=",
  .snlen  = sizeof("\rc=") - 1,
  .ln_str  = "IN IP4 ",
  .ln_strlen = sizeof("IN IP4 ") - 1,
  .match_len = epaddr_len
 },
 {  /* Requests headers */
  .lname  = "sip:",
  .lnlen  = sizeof("sip:") - 1,
  .sname  = "sip:",
  .snlen  = sizeof("sip:") - 1, /* yes, i know.. ;) */
  .ln_str  = "@",
  .ln_strlen = sizeof("@") - 1,
  .match_len = epaddr_len
 },
 {  /* SDP version header */
  .lname  = "\nv=",
  .lnlen  = sizeof("\nv=") - 1,
  .sname  = "\rv=",
  .snlen  = sizeof("\rv=") - 1,
  .ln_str  = "=",
  .ln_strlen = sizeof("=") - 1,
  .match_len = digits_len
 }
};

3.4   Connection information to establish expectations  

static int set_expected_rtp(struct sk_buff **pskb,
       struct ip_conntrack *ct,
       enum ip_conntrack_info ctinfo,
       __be32 ipaddr, u_int16_t port,
       const char *dptr)
{
 struct ip_conntrack_expect *exp;
 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 int ret;
//   Expect distribution space connection
 exp = ip_conntrack_expect_alloc(ct);
 if (exp == NULL)
  return NF_DROP;
//   Looking forward to the connection port address information, parse out the address of the port side for the purpose of
 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
 exp->tuple.src.u.udp.port = 0;
 exp->tuple.dst.ip = ipaddr;
 exp->tuple.dst.u.udp.port = htons(port);
 exp->tuple.dst.protonum = IPPROTO_UDP;
//   Part of the address mask
 exp->mask.src.ip = htonl(0xFFFFFFFF);
 exp->mask.src.u.udp.port = 0;
 exp->mask.dst.ip = htonl(0xFFFFFFFF);
 exp->mask.dst.u.udp.port = htons(0xFFFF);
 exp->mask.dst.protonum = 0xFF;
 exp->expectfn = NULL;
 exp->flags = 0;
 if (ip_nat_sdp_hook)
//   If the definition of the SDP's  NAT  Treatment, modified  SDP  Data information, and look forward to establish connection
  ret = ip_nat_sdp_hook(pskb, ctinfo, exp, dptr);
 else {
//   Looking forward to establish connection
  if (ip_conntrack_expect_related(exp) != 0)
   ret = NF_DROP;
  else
   ret = NF_ACCEPT;
 }
 ip_conntrack_expect_put(exp);
 return ret;
}

4. SIP  NAT handling
nat  Processing function net/ipv4/netfilter/ip_nat_sip.c, including the two functions  ,   SIP and dealt with separately  SDP  Data  

4.1 ip_nat_sip (ip_nat_sip_hook)
//   Only modify the data in the SIP header  ,   Do not expect to establish connection
//   Function returns 0 on failure  ,   Non-zero for success
//   Most cases, the information you need to modify two fields
static unsigned int ip_nat_sip(struct sk_buff **pskb,
          enum ip_conntrack_info ctinfo,
          struct ip_conntrack *ct,
          const char **dptr)
{
 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
 unsigned int bufflen, dataoff;
 __be32 ip;
 __be16 port;
//   Application layer data to recalculate the starting point
 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
//   After finding the NAT address and port data  ,   Is in the opposite direction of the destination port
 ip   = ct->tuplehash[!dir].tuple.dst.ip;
 port = ct->tuplehash[!dir].tuple.dst.u.udp.port;
 bufflen = sprintf(buffer, "%u.%u.%u.%u:%u", NIPQUAD(ip), ntohs(port));
 /* short packet ? */
//   Abnormal short packet, return
//   However, it should point operation in advance, so do not compute  ip, port  And bufflen the
 if (((*pskb)->len - dataoff) < (sizeof("SIP/2.0") - 1))
  return 0;
 /* Basic rules: requests and responses. */
 if (memcmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) == 0) {
//   Data to "SIP/2.0" at the beginning  ,   SIP response data is
  const char *aux;
//   Why not here to judge it dir  ?
  if ((ctinfo) < IP_CT_IS_REPLY) {
//   Positive direction of the data, the initiator  ->  Responder, to modify  "Contact: "  Port data address field, with  buffer  Data replacement
   mangle_sip_packet(pskb, ctinfo, ct, dptr,
                     (*pskb)->len - dataoff,
                     buffer, bufflen,
                     &ct_sip_hdrs[POS_CONTACT]);
   return 1;
  }
//   Data in the opposite direction, the response side  ->  Initiator
//   Modify  "Via: "  Port data address field, with  buffer  Data replacement
//   Returns 0 for false
  if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
           (*pskb)->len - dataoff,
                         buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
   return 0;
  /* This search should ignore case, but later.. */
//   Find  "CSeq:"  String position
  aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
                      (*pskb)->len - dataoff);
  if (!aux)
   return 0;
//   If  "CSeq:"  Field line does not  "REGISTER",
  if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"),
      ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff)))
   return 1;
//   Modify  "Contact: "  Port data address field, with  buffer  Data replacement
  return mangle_sip_packet(pskb, ctinfo, ct, dptr,
      (*pskb)->len - dataoff,
                           buffer, bufflen,
      &ct_sip_hdrs[POS_CONTACT]);
 }
//   Run to the data described here is not to "SIP/2.0" at the beginning of the  ,   SIP request is the data side
//   Why not here to judge it dir  ?
 if ((ctinfo) < IP_CT_IS_REPLY) {
//   Positive direction of the data, the initiator  ->  Responder, to modify  "Via: "  Port data address field, with  buffer  Data replacement
  if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
           (*pskb)->len - dataoff,
                         buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
   return 0;
  /* Mangle Contact if exists only. - watch udp_nat_mangle()! */
//   Modify  "Contact: "  Port data address field, with  buffer  Data replacement
  mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
                    buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
  return 1;
 }
//   Modify the data in the opposite direction
 /* This mangle requests headers. */
//   Modify  "sip:"  Data
 return mangle_sip_packet(pskb, ctinfo, ct, dptr,
                          ct_sip_lnlen(*dptr,
                  *dptr + (*pskb)->len - dataoff),
                          buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
}

//   Modify the SIP field
//   Find the definition of data from the hnfo  ,   Then replace the data in the buffer
static unsigned int mangle_sip_packet(struct sk_buff **pskb,
          enum ip_conntrack_info ctinfo,
          struct ip_conntrack *ct,
          const char **dptr, size_t dlen,
          char *buffer, int bufflen,
          struct sip_header_nfo *hnfo)
{
 unsigned int matchlen, matchoff;
//   Find hnfo defined data  ,   Get offset and length matchoff  matchlen
 if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0)
  return 0;
//   Modify data content, with  buffer  Alternative matchoff the data content
 if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
                               matchoff, matchlen, buffer, bufflen))
  return 0;
 /* We need to reload this. Thanks Patrick. */
//   Reposition the application layer data start address
 *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
 return 1;
}

4.2 ip_nat_sdp(ip_nat_sdp_hook)

  Modify the SDP data  ,   According to the SDP parameters and expect the child to establish connection parameters  ,  Function returns NF_ACCEPT or  NF_DROP
/* So, this packet has hit the connection tracking matching code.
   Mangle it, and change the expectation to match the new version. */
static unsigned int ip_nat_sdp(struct sk_buff **pskb,
          enum ip_conntrack_info ctinfo,
          struct ip_conntrack_expect *exp,
          const char *dptr)
{
 struct ip_conntrack *ct = exp->master;
 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 __be32 newip;
 u_int16_t port;
 DEBUGP("ip_nat_sdp():\n");
 /* Connection will come from reply */
// NAT  Modified address
 newip = ct->tuplehash[!dir].tuple.dst.ip;
//   Looking forward to the connection parameters
 exp->tuple.dst.ip = newip;
 exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
 exp->dir = !dir;
 /* When you see the packet, we need to NAT it the same as the
    this one. */
//   Expected handler for the establishment of sub-connection  nat  Information
 exp->expectfn = ip_nat_follow_master;
 /* Try to get same port: if not, try to change it. */
//   Find an available port free port to replace the original value
 for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) {
  exp->tuple.dst.u.udp.port = htons(port);
  if (ip_conntrack_expect_related(exp) == 0)
   break;
 }
//   Not available ports, and packet loss
 if (port == 0)
  return NF_DROP;
//   Modify the SDP data
 if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
  ip_conntrack_unexpect_related(exp);
  return NF_DROP;
 }
 return NF_ACCEPT;
}

//   Modify the SDP data
static unsigned int mangle_sdp(struct sk_buff **pskb,
          enum ip_conntrack_info ctinfo,
          struct ip_conntrack *ct,
//   New address, the port value
          __be32 newip, u_int16_t port,
          const char *dptr)
{
 char buffer[sizeof("nnn.nnn.nnn.nnn")];
 unsigned int dataoff, bufflen;
 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
 /* Mangle owner and contact info. */
//   New address string
 bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
//   Modify "o =" field address
 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
                        buffer, bufflen, &ct_sip_hdrs[POS_OWNER]))
  return 0;
//   Change "c =" field address information
 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
                        buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION]))
  return 0;
 /* Mangle media port. */
//   New port string
 bufflen = sprintf(buffer, "%u", port);
//   Modify "m =" field port information
 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
                        buffer, bufflen, &ct_sip_hdrs[POS_MEDIA]))
  return 0;
//   Last modified  "Content-Length: "  Contents of the field length value, because these changes  SDP  Data length
//   May change
 return mangle_content_len(pskb, ctinfo, ct, dptr);
}

//   Modify  "Content-Length: "  Contents of the field length
static int mangle_content_len(struct sk_buff **pskb,
         enum ip_conntrack_info ctinfo,
         struct ip_conntrack *ct,
         const char *dptr)
{
 unsigned int dataoff, matchoff, matchlen;
 char buffer[sizeof("65536")];
 int bufflen;
 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
 /* Get actual SDP lenght */
//   Find a "v =" string position  ,  This is the starting point of SDP data
 if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
                     &matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) {
  /* since ct_sip_get_info() give us a pointer passing 'v='
     we need to add 2 bytes in this count. */
//   The true length of the current SDP data  ,   Finally +2 is added back because  "v="  The two characters in length
  int c_len = (*pskb)->len - dataoff - matchoff + 2;
  /* Now, update SDP lenght */
//   Look for  "Content-Length: "  Field position, access to the data length
  if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
                      &matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) {
//   New length of string
   bufflen = sprintf(buffer, "%u", c_len);
//   Length of data update
   return ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
       matchoff, matchlen,
       buffer, bufflen);
  }
 }
 return 0;
}

5.   Conclusion  

Linux  Kernel tracking and SIP  NAT  A module is basically a fairly complete solution to the SIP processing  ,   But only for the UDP protocol  ,   If
  Is the TCP implementation  SIP  Is invalid in the programming  ,  Defines a struct sip_header_nfo structure to describe the various types of data you want to find information  ,  Implement object-oriented programming, but also make the program more concise  . However, the data should look for ways to support case-insensitive search data, the number of scan data is also more  ,  Will scan up to four times .
相关文章
  • LInux under the SIP protocol tracking 2011-01-10

    This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document, Be used for any commercial purposes is strictly prohibited. msn: [email protected] Source: http:

  • under the tomcat service linux start. Close and error tracking 2010-04-01

    under the tomcat service linux startup, shutdown and error tracking, remote connection to the server later, usually closed by the following ways start tomcat service: 1). Start the tomcat service Into the tomcat bin directory under your home director

  • sip protocol information in English 2010-07-19

    Network Working Group J. Rosenberg Request for Comments: 3261 dynamicsoft Obsoletes: 2543 H. Schulzrinne Category: Standards Track Columbia U. G. Camarillo Ericsson A. Johnston WorldCom J. Peterson Neustar R. Sparks dynamicsoft M. Handley ICIR E. Sch

  • SIP protocol in the application of 3G networks 2010-11-03

    Note: This article from: http://tech.c114.net/166/a544891.html . Session Initiation Protocol SIP is a 3G 's IP Multimedia Subsystem core technology to provide multimedia services. The article first introduces the basic working principle of SIP, then

  • SCTP protocol tracking 2011-01-10

    This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document, for any commercial purposes is strictly prohibited. msn: [email protected] Source: http://yfydz.

  • netfilter IP protocol in the implementation tracking and NAT 2011-01-10

    Copyleft this document owned by yfydz all, the use of GPL, free to copy, reprint, reproduced keep the documents for completeness, for any commercial purposes is strictly prohibited. msn: [email protected]tmail.com Source: http://yfydz.cublog.cn 1. Preface

  • 2.6.1 * Linux kernel TCP connection tracking 2011-01-10

    This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document, for any commercial purposes is strictly prohibited. msn: [email protected] Source: http://yfydz.

  • 转-Linux IPv4 protocol implementation 2012-03-07

    FROM: http://kernel.org/doc/man-pages/online/pages/man7/ip.7.html IP(7) Linux Programmer's Manual IP(7) NAME ip - Linux IPv4 protocol implementation SYNOPSIS #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> /* supe

  • oSIP protocol stack (and eXoSIP, Ortp, etc.) Getting Started (change) 2010-02-03

    No detailed studies have been empty oSIP, recently has come to see its version of the 3.x version, see the online help instruction manuals are too many old, and many suspected of document content a bit fraught ~ ~ Linux, compile oSIP use should be ve

  • Linux 2.6.19.x 内核编译配置选项简介 2012-11-24

    转载自:http://www.douban.com/group/topic/15706557/ Code maturity level options 代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完成的代码与驱动.除非你是测试人员或者开发者,否则请勿选择 General setup 常规设置 Local version - append to kernel release 在内核版本后面加上自定义

  • OSIP Stack Getting Started (continued from: pure logic of the protocol stack) (change) 2010-02-03

    Before long, simply looked rough under Osip, eXosip, ortp other and quickly "package" under a Windows MFC-based SIP soft VC6 the phone (all source code and the Lib library VC6 project files can be shared in this Blog folder found), due to time c

  • Linux TCP connections changes 2010-06-23

    1, the file limit changes (1) vi / etc / security / limits.conf * Soft nofile 10240 * Hard nofile 10240 (2) vi / etc / pam.d / login session required / lib / security / pam_limits.so Second, the network port limit changes (1) vi / etc / rc.d / rc.loc

  • Windows CE-based SIP phone software design and implementation 2010-11-03

    This article comes from: http://tech.c114.net/166/a493653.html Abstract: In this paper, based on SIP protocol softphone software architecture and design scheme. The program for the Windows CE embedded platforms, middleware, open source SIP stack by o

  • Modified Linux TCP connections 2010-11-27

    Modified Linux TCP connections First, limit the number of files modified (1) vi / etc / security / limits.conf * Soft nofile 10240 * Hard nofile 10240 (2) vi / etc / pam.d / login session required / lib / security / pam_limits.so Second, the network

  • Enhance the tcp limit linux 2011-05-17

    1, modify the user process can open files limit In the Linux platform, whether written or client server application, during processing of high concurrent TCP connections, the maximum number of concurrent users the system will be subject to a single p

  • phrack63 on through the loopholes in the Linux firewall solution 2011-01-10

    This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document, for any commercial purposes is strictly prohibited. msn: [email protected] Source: http://yfydz.

  • netfilter to track the IP protocol and NAT to achieve 2011-01-10

    This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document, for any commercial purposes is strictly prohibited. msn: [email protected] Source: http://yfydz.

  • FTP Linux kernel processing to track the serial number of vulnerabilities in 2011-01-10

    This document Copyleft owned yfydz all use under the GPL, can be freely copied, reproduced, reprinted, please maintain the integrity of the document, Be used for any commercial purposes is strictly prohibited. msn: [email protected] Source: http:

  • JAIN SIP vs SIP Servlet 2009-09-18

    JAIN SIP: Java API for Integrated Networks SIP, JSR32 defines its specification. PSTN, Wireless, Internet use is JSR32. (1) purposes: JAIN SIP can be used for the following aspects: ① for the J2SE platform, the development of an independent user agen

  • MSN Messenger protocol analysis - MSN Messenger Protocol Overview (change) 2010-03-29

    From: http://hi.baidu.com/kitandi/blog/item/31845c3a4b8525e215cecb3d.html/cmtid/3f98b6515fed5d501038c290 1. What is the MSNP (MSN Messenger Protocol)? MSN message protocol consists of a series in between the client and server commands sent the compos