⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osip_message_parse.c

📁 SIP协议栈实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	      if (i == -1)		return -1;	      return 0;	    }	}    }  return -1;			/* if comma is NULL, we should have already return 0 */}/* set all headers */intmsg_headers_parse (osip_message_t * sip, const char *start_of_header,		   const char **body){  const char *colon_index;		/* index of ':' */  char *hname;  char *hvalue;  const char *end_of_header;  int i;  for (;;)    {      i = __osip_find_next_crlf (start_of_header, &end_of_header);      if (i == -1)	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "End of header Not found\n"));	  return -1;		/* this is an error case!     */	}      if (end_of_header[0] == '\0')	{			/* final CRLF is missing */	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "SIP message does not end with CRLFCRLF\n"));	  return -1;	}      /* find the header name */      colon_index = strchr (start_of_header, ':');      if (colon_index == NULL)	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "End of header Not found\n"));	  return -1;		/* this is also an error case */	}      if (colon_index - start_of_header + 1 < 2)	return -1;      if (end_of_header <= colon_index)	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "Malformed message\n"));	  return -1;	}      hname = (char *) osip_malloc (colon_index - start_of_header + 1);      osip_strncpy (hname, start_of_header, colon_index - start_of_header);      osip_clrspace (hname);      {	const char *end;	/* END of header is (end_of_header-2) if header separation is CRLF */	/* END of header is (end_of_header-1) if header separation is CR or LF */	if ((end_of_header[-2] == '\r') || (end_of_header[-2] == '\n'))	  end = end_of_header - 2;	else	  end = end_of_header - 1;	if ((end) - colon_index < 2)	  hvalue = NULL;	/* some headers (subject) can be empty */	else	  {	    hvalue = (char *) osip_malloc ((end) - colon_index);	    osip_strncpy (hvalue, colon_index + 1, (end) - colon_index - 1);	    osip_clrspace (hvalue);	  }      }      /* hvalue MAY contains multiple value. In this case, they   */      /* are separated by commas. But, a comma may be part of a   */      /* quoted-string ("here, and there" is an example where the */      /* comma is not a separator!) */      i = msg_handle_multiple_values (sip, hname, hvalue);      osip_free (hname);      osip_free (hvalue);      if (i == -1)	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "End of header Not found\n"));	  return -1;	}      /* the list of headers MUST always end with  */      /* CRLFCRLF (also CRCR and LFLF are allowed) */      if ((end_of_header[0] == '\r') || (end_of_header[0] == '\n'))	{	  *body = end_of_header;	  return 0;		/* end of header found        */	}      /* continue on the next header */      start_of_header = end_of_header;    }/* Unreachable code OSIP_TRACE (osip_trace	      (__FILE__, __LINE__, OSIP_BUG, NULL,	       "This code cannot be reached\n")); */  return -1;}/* internal method to parse the body */intmsg_osip_body_parse (osip_message_t * sip, const char *start_of_buf,		const char **next_body){  const char *start_of_body;  const char *end_of_body;  char *tmp;  int i;  char *sep_boundary;  osip_generic_param_t *ct_param;  /* if MIME-Version: does not exist we just have */  /* to deal with one body and no header... */  if (sip->mime_version == NULL)    {				/* Mime-Version header does NOT exist */      if (sip->content_type == NULL)	return 0;		/* no body is attached */      else	{	  size_t osip_body_len;	  if (start_of_buf[0] == '\0')	    return -1;		/* final CRLF is missing */	  /* get rid of the first CRLF */	  if ('\r' == start_of_buf[0])	    {	      if ('\n' == start_of_buf[1])		start_of_body = start_of_buf + 2;	      else		start_of_body = start_of_buf + 1;	    }	  else if ('\n' == start_of_buf[0])	    start_of_body = start_of_buf + 1;	  else	    return -1;		/* message does not end with CRLFCRLF, CRCR or LFLF */	  if (sip->content_length != NULL)	    osip_body_len = osip_atoi (sip->content_length->value);	  else	    {			/* if content_length does not exist, set it. */	      char *tmp = osip_malloc (8);	      if (tmp == NULL)		return -1;	      osip_body_len = strlen (start_of_body);	      sprintf (tmp, "%i", osip_body_len);	      i = osip_message_set_content_length (sip, tmp);	      osip_free (tmp);	      if (i != 0)		return -1;	    }	  if (osip_body_len > strlen (start_of_body))	/* we do not receive the */	    return -1;		/* complete message      */	  /* end_of_body = start_of_body + strlen(start_of_body); */	  end_of_body = start_of_body + osip_body_len;	  tmp = osip_malloc (end_of_body - start_of_body + 2);	  if (tmp == NULL)	    return -1;	  osip_strncpy (tmp, start_of_body, end_of_body - start_of_body);	  i = osip_message_set_body (sip, tmp);	  osip_free (tmp);	  if (i != 0)	    return -1;	  return 0;	}    }  if (sip->content_type==NULL)    return -1;      /* find the boundary */  i = osip_generic_param_get_byname (sip->content_type->gen_params,			       "boundary", &ct_param);  if (i != 0)    return -1;  if (ct_param == NULL)    return -1;  if (ct_param->gvalue == NULL)    return -1;			/* No boundary but multiple headers??? */  sep_boundary = (char *) osip_malloc (strlen (ct_param->gvalue) + 3);  sprintf (sep_boundary, "--%s", ct_param->gvalue);  *next_body = NULL;  start_of_body = start_of_buf;  for (;;)    {      i = __osip_find_next_occurence (sep_boundary, start_of_body, &start_of_body);      if (i == -1)	{	  osip_free (sep_boundary);	  return -1;	}      i =	__osip_find_next_occurence (sep_boundary,			     start_of_body + strlen (sep_boundary),			     &end_of_body);      if (i == -1)	{	  osip_free (sep_boundary);	  return -1;	}      /* this is the real beginning of body */      start_of_body = start_of_body + strlen (sep_boundary) + 2;      tmp = osip_malloc (end_of_body - start_of_body + 1);      osip_strncpy (tmp, start_of_body, end_of_body - start_of_body);      i = osip_message_set_body_mime (sip, tmp);      osip_free (tmp);      if (i == -1)	{	  osip_free (sep_boundary);	  return -1;	}      if (strncmp (end_of_body + strlen (sep_boundary), "--", 2) == 0)	{			/* end of all bodies */	  *next_body = end_of_body;	  osip_free (sep_boundary);	  return 0;	}      /* continue on the next body */      start_of_body = end_of_body;    }  /* Unreachable code */  /* osip_free (sep_boundary); */  return -1;}/* osip_message_t *sip is filled while analysing buf */intosip_message_parse (osip_message_t * sip, const char *buf){  int i;  const char *next_header_index;  char *tmp;#ifdef WIN32  tmp = _alloca (strlen(buf)+2);#else  tmp = alloca (strlen(buf)+2);#endif  osip_strncpy(tmp, buf, strlen(buf));  osip_util_replace_all_lws(tmp);  /* parse request or status line */  i = __osip_message_startline_parse (sip, tmp, &next_header_index);  if (i == -1)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "Could not parse start line of message.\n"));      return -1;    }  tmp = (char *) next_header_index;  /* parse headers */  i = msg_headers_parse (sip, tmp, &next_header_index);  if (i == -1)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "error in msg_headers_parse()\n"));      return -1;    }  tmp = (char *) next_header_index;  /* this is a *very* simple test... (which handle most cases...) */  if (strlen (tmp) < 3)    {      /* this is mantory in the oSIP stack */      if (sip->content_length == NULL)	osip_message_set_content_length (sip, "0");      return 0;			/* no body found */    }  i = msg_osip_body_parse (sip, tmp, &next_header_index);  if (i == -1)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "error in msg_osip_body_parse()\n"));      return -1;    }  tmp = (char *) next_header_index;  /* this is mandatory in the oSIP stack */  if (sip->content_length == NULL)    osip_message_set_content_length (sip, "0");  return 0;}/* This method just add a received parameter in the Via   as requested by rfc3261 */intosip_message_fix_last_via_header (osip_message_t * request, const char *ip_addr, int port){  osip_generic_param_t *rport;  osip_via_t *via;  /* get Top most Via header: */  if (request == NULL)    return -1;  if (MSG_IS_RESPONSE (request))    return 0;			/* Don't fix Via header */  via = osip_list_get (request->vias, 0);  if (via == NULL || via->host == NULL)    /* Hey, we could build it? */    return -1;  osip_via_param_get_byname (via, "rport", &rport);  if (rport != NULL)    {      if (rport->gvalue == NULL)	{	  rport->gvalue = (char *) osip_malloc (9);#if (defined WIN32 || defined _WIN32_WCE)	  _snprintf (rport->gvalue, 8, "%i", port);#else	  snprintf (rport->gvalue, 8, "%i", port);#endif	}			/* else bug? */    }  /* only add the received parameter if the 'sent-by' value does not contains     this ip address */  if (0 == strcmp (via->host, ip_addr))	/* don't need the received parameter */    return 0;  osip_via_set_received (via, osip_strdup (ip_addr));  return 0;}const char *osip_message_get_reason (int replycode){  struct code_to_reason {    int code;    const char *reason;  };    static const struct code_to_reason reasons1xx[] = {    { 100, "Trying" },    { 180, "Ringing" },    { 181, "Call Is Being Forwarded" },    { 182, "Queued" },    { 183, "Session Progress" },  };  static const struct code_to_reason reasons2xx[] = {    { 200, "OK" },  };  static const struct code_to_reason reasons3xx[] = {    { 300, "Multiple Choices" },    { 301, "Moved Permanently" },    { 302, "Moved Temporarily" },    { 305, "Use Proxy" },    { 380, "Alternative Service" },  };  static const struct code_to_reason reasons4xx[] = {    { 400, "Bad Request" },    { 401, "Unauthorized" },    { 402, "Payment Required" },    { 403, "Forbidden" },    { 404, "Not Found" },    { 405, "Method Not Allowed" },    { 406, "Not Acceptable" },    { 407, "Proxy Authentication Required" },    { 408, "Request Timeout" },    { 409, "Conflict" },    { 410, "Gone" },    { 411, "Length Required" },    { 413, "Request Entity Too Large" },    { 414, "Request-URI Too Large" },    { 415, "Unsupported Media Type" },    { 416, "Unsupported Uri Scheme" },    { 420, "Bad Extension" },    { 423, "Interval Too Short" },    { 480, "Temporarily not available" },    { 481, "Call Leg/Transaction Does Not Exist" },    { 482, "Loop Detected" },    { 483, "Too Many Hops" },    { 484, "Address Incomplete" },    { 485, "Ambiguous" },    { 486, "Busy Here" },    { 487, "Request Cancelled" },    { 488, "Not Acceptable Here" },    { 489, "Bad Event" },  };  static const struct code_to_reason reasons5xx[] = {    { 500, "Internal Server Error" },    { 501, "Not Implemented" },    { 502, "Bad Gateway" },    { 503, "Service Unavailable" },    { 504, "Gateway Time-out" },    { 505, "SIP Version not supported" },  };  static const struct code_to_reason reasons6xx[] = {    { 600, "Busy Everywhere" },    { 603, "Decline" },    { 604, "Does not exist anywhere" },    { 606, "Not Acceptable" }  };  const struct code_to_reason *reasons;  int len, i;  switch (replycode / 100) {  case 1:    reasons = reasons1xx;    len = sizeof(reasons1xx) / sizeof(*reasons);    break;  case 2:    reasons = reasons2xx;    len = sizeof(reasons2xx) / sizeof(*reasons);    break;  case 3:    reasons = reasons3xx;    len = sizeof(reasons3xx) / sizeof(*reasons);    break;  case 4:    reasons = reasons4xx;    len = sizeof(reasons4xx) / sizeof(*reasons);    break;  case 5:    reasons = reasons5xx;    len = sizeof(reasons5xx) / sizeof(*reasons);    break;  case 6:    reasons = reasons6xx;    len = sizeof(reasons6xx) / sizeof(*reasons);    break;  default:    return NULL;  }    for (i = 0; i < len; i++)    if (reasons[i].code == replycode)      return reasons[i].reason;    /* Not found. */  return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -