📄 extcmd_funcs.c
字号:
/* * $Id: extcmd_funcs.c,v 1.15 2004/08/24 08:58:29 janakj Exp $ * * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * ser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * History: * -------- * 2003-01-23: switched from t_uac to t_uac_dlg, adapted to new way of * parsing for Content-Type (bogdan) * 2003-08-05: adapted to the new parse_content_type_hdr function (bogdan) * 2003-09-11: updated to new build_lump_rpl() interface (bogdan) * 2003-11-11: build_lump_rpl() removed, add_lump_rpl() has flags (bogdan) */#include <string.h>#include <errno.h>#include <signal.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/socket.h>#include "extcmd_funcs.h"#include "clients.h"#include "../../error.h"#include "../../str.h"#include "../../ip_addr.h"#include "../../data_lump_rpl.h"#include "../../mem/shm_mem.h"#include "../../parser/parse_content.h"#include "../../parser/parse_from.h"#include "../tm/tm_load.h"#define NO_CMD 0#define MSG_CMD 1#define RPL_CMD 2#define BYE_CMD 3#define FTH_CMD 4#define VOID_CMD 5#define INV_CMD 6#define ACK_CMD 7#define BUFFER_SIZE 2048#define HEADER_SIZE 5#define TYPE_LEN 1#define LEN_LEN 4#define append_str(_p,_s,_l) \ {memcpy((_p),(_s),(_l));\ (_p) += (_l);}typedef struct anchor_struct{ int fd; str cmd;} anchor_t;/* global variable */struct tm_binds tmb;int rpl_pipe[2];int req_pipe[2];inline int get_int_n2h( char *b, int l){ int n,i; for(i=0,n=0;i<l;i++) n = (n<<8) + (unsigned char)b[i]; return n;}inline void put_int_h2n( int x, char *b, int l){ int i; for(i=0;i<l;i++) b[i] = (unsigned char) ((x>>((l-i-1)*8)) & 0x000000FF);}#if 0inline int extcmd_add_contact(struct sip_msg* msg , str* to_uri){ struct lump_rpl *lump; char *buf, *p; int len; len = 9 /*"Contact: "*/ + to_uri->len + 2/*"<>"*/ + CRLF_LEN; buf = pkg_malloc( len ); if(!buf) { LOG(L_ERR,"ERROR:extcmd_add_contact: out of memory! \n"); return -1; } p = buf; append_str( p, "Contact: " , 9); *(p++) = '<'; append_str( p, to_uri->s, to_uri->len); *(p++) = '>'; append_str( p, CRLF, CRLF_LEN); lump = build_lump_rpl( buf , len , LUMP_RPL_HDR); if(!lump) { LOG(L_ERR,"ERROR:extcmd_add_contact: unable to build lump_rpl! \n"); pkg_free( buf ); return -1; } add_lump_rpl( msg , lump ); pkg_free(buf); return 1;}#endifint dump_request(struct sip_msg *msg, char *para1, char *para2){ anchor_t anchor; str body; struct to_body *from; char *cmd; int cmd_len; char *p; int mime; /* get the message's body * anyhow we have to call this function, so let's do it at the beginning * to force the parsing of all the headers - like this we avoid separate * calls of parse_headers function for FROM, CONTENT_LENGTH, TO hdrs */ body.s = get_body( msg ); if (body.s==0) { LOG(L_ERR,"ERROR:extcmd:dump_msg: cannot extract body from msg!\n"); goto error; } /* content-length (if present) must be already parsed */ if (!msg->content_length) { LOG(L_ERR,"ERROR:extcmd:dump_msg: no Content-Length header found!\n"); goto error; } body.len = get_content_length( msg ); /* look for TO header */ if (!msg->to) { LOG(L_ERR,"ERROR:extcmd:dump_msg: no TO header found!\n"); goto error; } /* parse the content-type header */ if ((mime=parse_content_type_hdr(msg))<1 ) { LOG(L_ERR,"ERROR:extcmd:dump_msg:cannot parse Content-Type header\n"); goto error; } /* check the content-type value */ if ( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM ) { LOG(L_ERR,"ERROR:extcmd:dump_msg: invalid content-type for a " "message request! type found=%d\n",mime); goto error; } if ( parse_from_header(msg)==-1 ) { LOG(L_ERR,"ERROR:extcmd:dump_msg: cannot parse FROM header!\n"); goto error; } from = (struct to_body*)msg->from->parsed;#if 0 /* adds contact header into reply */ if (extcmd_add_contact(msg,&(get_to(msg)->uri))==-1) { LOG(L_ERR,"ERROR:extcmd:dump_msg: can't build contact for reply\n"); goto error; }#endif /*-------------BUILD AND FILL THE COMMAND --------------------*/ /* computes the amount of memory needed */ cmd_len = HEADER_SIZE + /* commnad header */ + 4 + body.len /*body + size */ + 4 + from->uri.len /* from + size */ + 4 + get_to(msg)->uri.len /* to + size */ + 4 + 0; /* extra_headers + size */ /* allocs a chunk of shm memory */ cmd = (char*)shm_malloc( cmd_len ); if (!cmd) { LOG(L_ERR,"ERROR:extcmd:dump_msg: cannot get shm memory!\n"); goto error; } /* start filling the commnad (in revert order, from end)*/ p = cmd + cmd_len; /* copy body's body */ p = p - body.len; memcpy( p, body.s, body.len); /* put body's lengh */ p = p-4; put_int_h2n( body.len, p, 4); /* copy hdr's body - nothing for the moment*/ /* put hdr's lengh */ p = p-4; put_int_h2n( 0, p, 4); /* copy to's body */ p = p - get_to(msg)->uri.len; memcpy( p, get_to(msg)->uri.s, get_to(msg)->uri.len); /* put to's lengh */ p = p-4; put_int_h2n( get_to(msg)->uri.len, p, 4); /* copy from's body */ p = p - from->uri.len; memcpy( p, from->uri.s, from->uri.len); /* put from's lengh */ p = p-4; put_int_h2n( from->uri.len, p, 4); /* add the cmd size */ p = p-4; put_int_h2n( cmd_len-HEADER_SIZE, p, 4); /* add the cmd type */ p = p-1; put_int_h2n( MSG_CMD, p, 1); /* fill in the anchor */ anchor.fd = 0; anchor.cmd.s = cmd; anchor.cmd.len = cmd_len; /* send the anchor through pipe to the extcmd server process */ DBG("DEBUG:extcmd:dump_msg: posting request in pipe!\n"); if (write( req_pipe[1], &anchor, sizeof(anchor))!=sizeof(anchor) ) { LOG(L_ERR,"ERROR:extcmd:dump_msg: cannot write to request pipe" " : %s\n",strerror(errno) ); goto error; } return 1;error: return -1;}static int push_reply_to_client(int code, char* reason_s, int reason_l, int client_fd){ anchor_t anchor; str reply; char *p; /* compose the reply commnad that will be sent back to the client */ reply.len = 1/*type*/+4/*cmd_size*/+4/*rpl_code*/+4/*rpl_reason_size*/+ reason_l/*rpl_reason_string*/; reply.s = (char*) shm_malloc( reply.len ); if (reply.s==0) { LOG(L_ERR,"ERROR::extcmd:tuac_callback: no more shm_mem free!\n"); return -1; } /* fill up the rpl_cmd - in revert order (from end)*/ p = reply.s + reply.len; /* add reason string */ p = p-reason_l; memcpy( p, reason_s, reason_l); /* add reason string len */ p = p-4; put_int_h2n( reason_l, p, 4); /* add the rpl code */ p = p-4; put_int_h2n( code, p, 4); /* add the cmd size */ p = p-4; put_int_h2n( 4+4+reason_l, p, 4); /* add the cmd type */ p = p-1; put_int_h2n( RPL_CMD, p, 1); /* push reply on rpl_pipe */ anchor.fd = client_fd; anchor.cmd.s = reply.s; anchor.cmd.len = reply.len; if (write( rpl_pipe[1] , &anchor, sizeof(anchor) )!=sizeof(anchor)) { LOG(L_ERR,"ERROR::extcmd:push_reply_to_client: cannot write " "to rpl_pipe : Reason: %s !\n",strerror(errno) ); return -1; } return 1;}void tuac_callback( struct cell *t, struct sip_msg *msg, int code, void *param){ str reason; DBG("DEBUG:extcmd:tuac_callback: reply status=%d\n", code); if(!t->cbp) { LOG(L_ERR,"ERROR:extcmd:tuac_callback: parameter not received\n"); return; } /* get the status text for this reply code */ get_reply_status( &reason, msg, code); push_reply_to_client( code, reason.s, reason.len, *((int*)t->cbp)); if (reason.s) pkg_free(reason.s);}int send_sip_req(str* msg_type, str *msg, int client_fd){ char err_buf[256]; str to; str from; str hdrs; str body; int *pcbp; char *p; char *end; int len; int ret; int err_ret; int sip_error; /* split the msg into from, to hdrs, body */ end = msg->s + msg->len; p = msg->s; /* get from len */ len = get_int_n2h( p, 4); p = p + 4; if ( p+len>end) { LOG(L_ERR,"ERROR:extcmd:send_sip_req: FROM size to big (%d)\n",len); push_reply_to_client(400,"extcmd: invalid FROM header",27,client_fd); goto error; } /* get from body */ from.s = p; from.len = len; p += len; DBG("DEBUG:extcmd:send_sip_req: from=%d<%.*s>\n",from.len,from.len,from.s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -