char *parse_arglist(dbref player, dbref cause, char *dstr, char delim, dbref eval, char *fargs[], dbref nfargs, char *cargs[], dbref ncargs) { char *rstr, *tstr, *bp, *str; int arg, peval; for(arg = 0; arg < nfargs; arg++) fargs[arg] = NULL; if(dstr == NULL) return NULL; rstr = parse_to(&dstr, delim, 0); arg = 0; peval = (eval & ~EV_EVAL); while ((arg < nfargs) && rstr) { if(arg < (nfargs - 1)) tstr = parse_to(&rstr, ',', peval); else tstr = parse_to(&rstr, '\0', peval); if(eval & EV_EVAL) { bp = fargs[arg] = alloc_lbuf("parse_arglist"); str = tstr; exec(fargs[arg], &bp, 0, player, cause, eval | EV_FCHECK, &str, cargs, ncargs); *bp = '\0'; } else { fargs[arg] = alloc_lbuf("parse_arglist"); StringCopy(fargs[arg], tstr); } arg++; } return dstr; }
static int NAT_target_parse(char c,char *to_address,struct ipt_natinfo **target) { switch (c) { case 'S': *target = parse_to(to_address, *target); return 1; case 'Z': *target = parse_to(to_address, *target); return 1; default: return 0; } }
static void DNAT_parse(struct xt_option_call *cb) { const struct ipt_entry *entry = cb->xt_entry; struct ipt_natinfo *info = (void *)(*cb->target); int portok; if (entry->ip.proto == IPPROTO_TCP || entry->ip.proto == IPPROTO_UDP || entry->ip.proto == IPPROTO_SCTP || entry->ip.proto == IPPROTO_DCCP || entry->ip.proto == IPPROTO_ICMP) portok = 1; else portok = 0; xtables_option_parse(cb); switch (cb->entry->id) { case O_TO_DEST: if (cb->xflags & F_X_TO_DEST) { if (!kernel_version) get_kernel_version(); if (kernel_version > LINUX_VERSION(2, 6, 10)) xtables_error(PARAMETER_PROBLEM, "DNAT: Multiple --to-destination not supported"); } *cb->target = parse_to(cb->arg, portok, info); cb->xflags |= F_X_TO_DEST; break; case O_PERSISTENT: info->mr.range[0].flags |= NF_NAT_RANGE_PERSISTENT; break; } }
static inline str* extract_mangled_fromuri(str *mangled_from_hdr) { struct to_body from_b; struct hdr_field hdr; char *tmp,*end; if (mangled_from_hdr->len == 0 || mangled_from_hdr->s == NULL) return NULL; end = mangled_from_hdr->s+mangled_from_hdr->len; tmp=parse_hname2(mangled_from_hdr->s,end,&hdr); if (hdr.type==HDR_ERROR_T) { LM_ERR("bad from header\n"); return NULL; } tmp=eat_lws_end(tmp, end); if (tmp >= end) { LM_ERR("empty header\n"); return NULL; } parse_to(tmp,end,&from_b); if (from_b.error == PARSE_ERROR) { LM_ERR("bad from header [%.*s]\n",mangled_from_hdr->len,mangled_from_hdr->s); return NULL; } extracted_from_uri = from_b.uri; free_to_params(&from_b); LM_DBG("extracted from uri [%.*s]\n",extracted_from_uri.len,extracted_from_uri.s); return &extracted_from_uri; }
static void DNAT_parse(struct xt_option_call *cb) { const struct ip6t_entry *entry = cb->xt_entry; struct nf_nat_range *range = cb->data; int portok; if (entry->ipv6.proto == IPPROTO_TCP || entry->ipv6.proto == IPPROTO_UDP || entry->ipv6.proto == IPPROTO_SCTP || entry->ipv6.proto == IPPROTO_DCCP || entry->ipv6.proto == IPPROTO_ICMP) portok = 1; else portok = 0; xtables_option_parse(cb); switch (cb->entry->id) { case O_TO_DEST: if (cb->xflags & F_X_TO_DEST) { if (!kernel_version) get_kernel_version(); if (kernel_version > LINUX_VERSION(2, 6, 10)) xtables_error(PARAMETER_PROBLEM, "DNAT: Multiple --to-source not supported"); } parse_to(cb->arg, portok, range); break; case O_PERSISTENT: range->flags |= NF_NAT_RANGE_PERSISTENT; break; } }
/*! \brief * This method is used to parse DIVERSION header. * * params: msg : sip msg * returns 0 on success, * -1 on failure. */ int parse_diversion_header(struct sip_msg *msg) { struct to_body* diversion_b; if (!msg->diversion && (parse_headers(msg, HDR_DIVERSION_F, 0) == -1 || !msg->diversion)) { goto error; } /* maybe the header is already parsed! */ if (msg->diversion->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ diversion_b = pkg_malloc(sizeof(struct to_body)); if (diversion_b == 0) { LOG(L_ERR, "ERROR:parse_diversion_header: out of pkg_memory\n"); goto error; } /* now parse it!! */ memset(diversion_b, 0, sizeof(struct to_body)); parse_to(msg->diversion->body.s, msg->diversion->body.s + msg->diversion->body.len + 1, diversion_b); if (diversion_b->error == PARSE_ERROR) { LOG(L_ERR, "ERROR:parse_diversion_header: bad diversion header\n"); free_to(diversion_b); goto error; } msg->diversion->parsed = diversion_b; return 0; error: return -1; }
/** * Returns the Public Identity extracted from the From header * @param msg - the SIP message * @returns the str containing the public id, no mem dup */ str cscf_get_public_identity_from(struct sip_msg *msg) { str pu={0,0}; struct to_body *from; int i; if (parse_headers(msg,HDR_FROM_F,0)!=0) { return pu; } if ( get_from(msg) == NULL ) { from = (struct to_body*) pkg_malloc(sizeof(struct to_body)); parse_to( msg->from->body.s, msg->from->body.s + msg->from->body.len, from ); msg->from->parsed = from; } else from=(struct to_body *) msg->from->parsed; pu = from->uri; /* truncate to sip:username@host or tel:number */ for(i=4;i<pu.len;i++) if (pu.s[i]==';' || pu.s[i]=='?' ||pu.s[i]==':'){ pu.len = i; } return pu; }
/*! \brief * This method is used to parse RPID header. * * params: msg : sip msg * returns 0 on success, * -1 on failure. */ int parse_rpid_header( struct sip_msg *msg ) { struct to_body* rpid_b; if ( !msg->rpid && (parse_headers(msg, HDR_RPID_F, 0)==-1 || !msg->rpid)) { goto error; } /* maybe the header is already parsed! */ if (msg->rpid->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ rpid_b = pkg_malloc(sizeof(struct to_body)); if (rpid_b == 0) { LOG(L_ERR, "ERROR:parse_rpid_header: out of pkg_memory\n"); goto error; } /* now parse it!! */ memset(rpid_b, 0, sizeof(struct to_body)); parse_to(msg->rpid->body.s,msg->rpid->body.s+msg->rpid->body.len+1,rpid_b); if (rpid_b->error == PARSE_ERROR) { LOG(L_ERR, "ERROR:parse_rpid_header: bad rpid header\n"); free_to(rpid_b); goto error; } msg->rpid->parsed = rpid_b; return 0; error: return -1; }
struct to_body* get_appearance_name_addr(struct sip_msg* msg) { int len = 0; if(appearance_name_addr_spec_param.s) { memset(&appearance_name_addr_tok, 0, sizeof(pv_value_t)); if(pv_get_spec_value(msg, &appearance_name_addr_spec, &appearance_name_addr_tok) < 0) { LM_ERR("Failed to get appearance_name_addr value\n"); return NULL; } //LM_DBG("got appearance_name_addr_spec_param flags [%d]\n", appearance_name_addr_tok.flags); if(!(appearance_name_addr_tok.flags&PV_VAL_INT) && (appearance_name_addr_tok.flags&PV_VAL_STR)) { //LM_DBG("got PV_SPEC appearance_name_addr [%.*s]\n", // appearance_name_addr_tok.rs.len, appearance_name_addr_tok.rs.s); if(appearance_name_addr_tok.rs.len+CRLF_LEN > APPEARANCE_NAME_ADDR_BUF_LEN) { LM_ERR("Buffer overflow\n"); return NULL; } trim(&appearance_name_addr_tok.rs); memcpy(appearance_name_addr_buf, appearance_name_addr_tok.rs.s, appearance_name_addr_tok.rs.len); len = appearance_name_addr_tok.rs.len; if(strncmp(appearance_name_addr_tok.rs.s + len - CRLF_LEN, CRLF, CRLF_LEN)) { memcpy(appearance_name_addr_buf + len, CRLF, CRLF_LEN); len+= CRLF_LEN; } parse_to(appearance_name_addr_buf, appearance_name_addr_buf+len, &appearance_name_addr); if (appearance_name_addr.error != PARSE_OK) { LM_ERR("Failed to parse PV_SPEC appearance_name_addr [%.*s]\n", len, appearance_name_addr_buf); return NULL; } if (parse_uri(appearance_name_addr.uri.s, appearance_name_addr.uri.len, &appearance_name_addr.parsed_uri)<0) { LM_ERR("failed to parse PV_SPEC appearance_name_addr uri [%.*s]\n", appearance_name_addr.uri.len, appearance_name_addr.uri.s); return NULL; } return &appearance_name_addr; } } /* If the appearance_name_addr_spec_param is not set, use the From uri */ /* if (msg->from->parsed == NULL) { if (parse_from_header(msg)<0) { LM_ERR("cannot parse From header\n"); return NULL; } } */ return msg->from->parsed; }
int sca_get_msg_to_header( sip_msg_t *msg, struct to_body **to ) { struct to_body parsed_to; struct to_body *t = NULL; assert( msg != NULL ); assert( to != NULL ); if ( SCA_HEADER_EMPTY( msg->to )) { LM_ERR( "Empty To header" ); return( -1 ); } t = get_to( msg ); if ( t == NULL ) { parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len + 1, /* end of buffer */ &parsed_to ); if ( parsed_to.error != PARSE_OK ) { LM_ERR( "Bad To header" ); return( -1 ); } t = &parsed_to; } /* ensure the URI is parsed for future use */ if ( parse_uri( t->uri.s, t->uri.len, GET_TO_PURI( msg )) < 0 ) { LM_ERR( "Failed to parse To URI %.*s", STR_FMT( &t->uri )); return( -1 ); } *to = t; return( 0 ); }
struct to_body* get_b2bl_from(struct sip_msg* msg) { int len = 0; if(b2bl_from_spec_param.s) { memset(&b2bl_from_tok, 0, sizeof(pv_value_t)); if(pv_get_spec_value(msg, &b2bl_from_spec, &b2bl_from_tok) < 0) { LM_ERR("Failed to get b2bl_from value\n"); return NULL; } //LM_DBG("got b2bl_from_spec_param flags [%d]\n", b2bl_from_tok.flags); if(b2bl_from_tok.flags&PV_VAL_INT) { /* the PV might be empty */ return NULL; } if(b2bl_from_tok.flags&PV_VAL_STR) { //LM_DBG("got PV_SPEC b2bl_from [%.*s]\n", // b2bl_from_tok.rs.len, b2bl_from_tok.rs.s); if(b2bl_from_tok.rs.len+CRLF_LEN > B2BL_FROM_BUF_LEN) { LM_ERR("Buffer overflow\n"); return NULL; } trim(&b2bl_from_tok.rs); memcpy(b2bl_from_buf, b2bl_from_tok.rs.s, b2bl_from_tok.rs.len); len = b2bl_from_tok.rs.len; if(strncmp(b2bl_from_tok.rs.s + len - CRLF_LEN, CRLF, CRLF_LEN)) { memcpy(b2bl_from_buf + len, CRLF, CRLF_LEN); len+= CRLF_LEN; } parse_to(b2bl_from_buf, b2bl_from_buf+len, &b2bl_from); if (b2bl_from.error != PARSE_OK) { LM_ERR("Failed to parse PV_SPEC b2bl_from [%.*s]\n", len, b2bl_from_buf); return NULL; } if (parse_uri(b2bl_from.uri.s, b2bl_from.uri.len, &b2bl_from.parsed_uri)<0) { LM_ERR("failed to parse PV_SPEC b2bl_from uri [%.*s]\n", b2bl_from.uri.len, b2bl_from.uri.s); return NULL; } /* side effect of parsing - nobody should need them later on, * so free them right now */ free_to_params(&b2bl_from); return &b2bl_from; } } return NULL; }
/* * Get user part from P-Charge-Info header * param msg SIP message * param user User part of P-Charge-Info header * param bufsize Size of fromuser buffer * return 0 success, 1 without P-Charge-Info, -1 failure */ int ospGetPChargeInfoUserpart( struct sip_msg* msg, char* pciuser, int bufsize) { static const char* header = "P-Charge-Info"; struct to_body body; struct to_body* pci=NULL; struct hdr_field *hf; struct sip_uri uri; int result = -1; if ((pciuser != NULL) && (bufsize > 0)) { pciuser[0] = '\0'; if (parse_headers(msg, HDR_EOH_F, 0) < 0) { LM_ERR("failed to parse message\n"); return -1; } for (hf = msg->headers; hf; hf = hf->next) { if ((hf->type == HDR_OTHER_T) && (hf->name.len == strlen(header)) && (strncasecmp(hf->name.s, header, hf->name.len) == 0)) { if (!(pci = hf->parsed)) { pci = &body; parse_to(hf->body.s, hf->body.s + hf->body.len + 1, pci); } if (pci->error != PARSE_ERROR) { if (parse_uri(pci->uri.s, pci->uri.len, &uri) == 0) { ospCopyStrToBuffer(&uri.user, pciuser, bufsize); ospSkipUserParam(pciuser); result = 0; } else { LM_ERR("failed to parse P-Charge-Info uri\n"); } if (pci == &body) { free_to_params(pci); } } else { LM_ERR("bad P-Charge-Info header\n"); } break; } } if (!hf) { LM_DBG("without P-Charge-Info header\n"); result = 1; } } else { LM_ERR("bad parameters to parse user part from PAI\n"); } return result; }
static int SNAT_parse(int c, char **argv, int invert, unsigned int *flags, const void *e, struct xt_entry_target **target) { const struct ipt_entry *entry = e; struct ipt_natinfo *info = (void *)*target; int portok; if (entry->ip.proto == IPPROTO_TCP || entry->ip.proto == IPPROTO_UDP || entry->ip.proto == IPPROTO_SCTP || entry->ip.proto == IPPROTO_DCCP || entry->ip.proto == IPPROTO_ICMP) portok = 1; else portok = 0; switch (c) { case '1': if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-source"); if (*flags & IPT_SNAT_OPT_SOURCE) { if (!kernel_version) get_kernel_version(); if (kernel_version > LINUX_VERSION(2, 6, 10)) xtables_error(PARAMETER_PROBLEM, "Multiple --to-source not supported"); } *target = parse_to(optarg, portok, info); /* WTF do we need this for?? */ if (*flags & IPT_SNAT_OPT_RANDOM) info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_SNAT_OPT_SOURCE; return 1; case '2': if (*flags & IPT_SNAT_OPT_SOURCE) { info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_SNAT_OPT_RANDOM; } else *flags |= IPT_SNAT_OPT_RANDOM; return 1; case '3': info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT; return 1; default: return 0; } }
// --------------------------------------------------------------------------- // do_query: Command interface to sql_que // void do_query ( dbref executor, dbref caller, dbref enactor, int eval, int key, char *dbref_attr, char *dbname_query, char *cargs[], int ncargs ) { if (key & QUERY_SQL) { // SQL Query. // dbref thing; ATTR *pattr; if (!( parse_attrib(executor, dbref_attr, &thing, &pattr) && pattr)) { notify_quiet(executor, "No match."); return; } if (!Controls(executor, thing)) { notify_quiet(executor, NOPERM_MESSAGE); return; } char *pQuery = dbname_query; char *pDBName = parse_to(&pQuery, '/', 0); if (NULL == pQuery) { notify(executor, "QUERY: No Query."); return; } STARTLOG(LOG_ALWAYS, "CMD", "QUERY"); Log.tinyprintf("Thing=#%d, Attr=%s, dbname=%s, query=%s", thing, pattr->name, pDBName, pQuery); ENDLOG; } else { notify_quiet(executor, "At least one query option is required."); } }
/* Function which parses command options; returns true if it ate an option */ static int SAME_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ipt_same_info *mr = (struct ipt_same_info *)(*target)->data; unsigned int count; switch (c) { case '1': if (mr->rangesize == IPT_SAME_MAX_RANGE) exit_error(PARAMETER_PROBLEM, "Too many ranges specified, maximum " "is %i ranges.\n", IPT_SAME_MAX_RANGE); if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --to"); parse_to(optarg, &mr->range[mr->rangesize]); /* WTF do we need this for? */ if (*flags & IPT_SAME_OPT_RANDOM) mr->range[mr->rangesize].flags |= IP_NAT_RANGE_PROTO_RANDOM; mr->rangesize++; *flags |= IPT_SAME_OPT_TO; break; case '2': if (*flags & IPT_SAME_OPT_NODST) exit_error(PARAMETER_PROBLEM, "Can't specify --nodst twice"); mr->info |= IPT_SAME_NODST; *flags |= IPT_SAME_OPT_NODST; break; case '3': *flags |= IPT_SAME_OPT_RANDOM; for (count=0; count < mr->rangesize; count++) mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM; break; default: return 0; } return 1; }
/* * This method is used to parse the from header. It was decided not to parse * anything in core that is not *needed* so this method gets called by * rad_acc module and any other modules that needs the FROM header. * * params: msg : sip msg * returns =0 on success, * <0 on failure. */ int parse_from_header( struct sip_msg *msg) { struct to_body* from_b; if ( !msg->from && ( parse_headers(msg,HDR_FROM_F,0)==-1 || !msg->from)) { LM_ERR("bad msg or missing FROM header\n"); goto error; } /* maybe the header is already parsed! */ if (msg->from->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ from_b = pkg_malloc(sizeof(struct to_body)); if (from_b == 0) { LM_ERR("out of pkg_memory\n"); goto error; } /* now parse it!! */ memset(from_b, 0, sizeof(struct to_body)); parse_to(msg->from->body.s,msg->from->body.s+msg->from->body.len+1,from_b); if (from_b->error == PARSE_ERROR) { LM_ERR("bad from header\n"); pkg_free(from_b); /*TODO - error set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing From header"); set_err_reply(400, "bad header"); * */ goto error; } /* REGISTER doesn't have a from tag :( -bogdan if (from_b->tag_value.len==0 || from_b->tag_value.s==0) { LM_ERR("missing TAG value\n"); free_to(from_b); goto error; } */ msg->from->parsed = from_b; return 0; error: return -1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ipt_natinfo *info = (void *)*target; int portok; if (entry->ip.proto == IPPROTO_TCP || entry->ip.proto == IPPROTO_UDP || entry->ip.proto == IPPROTO_ICMP) portok = 1; else portok = 0; switch (c) { case '1': if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-destination"); if (*flags) { if (!kernel_version) get_kernel_version(); if (kernel_version > LINUX_VERSION(2, 6, 10)) exit_error(PARAMETER_PROBLEM, "Multiple --to-destination not supported"); } *target = parse_to(optarg, portok, info); /* WTF do we need this for?? */ if (*flags & IPT_DNAT_OPT_RANDOM) info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_DNAT_OPT_DEST; return 1; case '2': if (*flags & IPT_DNAT_OPT_DEST) { info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM; *flags |= IPT_DNAT_OPT_RANDOM; } else *flags |= IPT_DNAT_OPT_RANDOM; return 1; default: return 0; } }
/* * This method is used to parse P-Asserted-Identity header (RFC 3325). * * Currently only one name-addr / addr-spec is supported in the header * and it must contain a sip or sips URI. * * params: msg : sip msg * returns 0 on success, * -1 on failure. */ int parse_pai_header( struct sip_msg *msg ) { struct to_body* pai_b; if ( !msg->pai && (parse_headers(msg, HDR_PAI_F,0)==-1 || !msg->pai)) { goto error; } /* maybe the header is already parsed! */ if (msg->pai->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ pai_b = pkg_malloc(sizeof(struct to_body)); if (pai_b == 0) { LM_ERR("out of pkg_memory\n"); goto error; } /* now parse it!! */ memset(pai_b, 0, sizeof(struct to_body)); parse_to(msg->pai->body.s, msg->pai->body.s + msg->pai->body.len+1, pai_b); if (pai_b->error == PARSE_ERROR) { LM_ERR("bad P-Asserted-Identity header\n"); pkg_free(pai_b); /* TODO - error set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing PAI header"); set_err_reply(400, "bad header"); * */ goto error; } msg->pai->parsed = pai_b; return 0; error: return -1; }
static void SAME_parse(struct xt_option_call *cb) { struct ipt_same_info *mr = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { case O_TO_ADDR: if (mr->rangesize == IPT_SAME_MAX_RANGE) xtables_error(PARAMETER_PROBLEM, "Too many ranges specified, maximum " "is %i ranges.\n", IPT_SAME_MAX_RANGE); parse_to(cb->arg, &mr->range[mr->rangesize]); mr->rangesize++; break; case O_NODST: mr->info |= IPT_SAME_NODST; break; } }
static int NETMAP_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)(*target)->data; switch (c) { case '1': if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s", NETMAP_opts[0].name); parse_to(optarg, &mr->range[0]); *flags = 1; return 1; default: return 0; } }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ipt_same_info *mr = (struct ipt_same_info *)(*target)->data; switch (c) { case '1': if (mr->rangesize == IPT_SAME_MAX_RANGE) exit_error(PARAMETER_PROBLEM, "Too many ranges specified, maximum " "is %i ranges.\n", IPT_SAME_MAX_RANGE); if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --to"); parse_to(optarg, &mr->range[mr->rangesize]); mr->rangesize++; *flags |= IPT_SAME_OPT_TO; break; case '2': if (*flags & IPT_SAME_OPT_NODST) exit_error(PARAMETER_PROBLEM, "Can't specify --nodst twice"); mr->info |= IPT_SAME_NODST; *flags |= IPT_SAME_OPT_NODST; break; default: return 0; } return 1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ip_nat_multi_range *mr = (struct ip_nat_multi_range *)(*target)->data; switch (c) { case '1': if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s", opts[0].name); parse_to(optarg, &mr->range[0]); *flags = 1; return 1; default: return 0; } }
/* * This method is used to parse Refer-To header. * * params: msg : sip msg * returns 0 on success, * -1 on failure. */ int parse_refer_to_header( struct sip_msg *msg ) { struct to_body* refer_to_b; if ( !msg->refer_to && (parse_headers(msg, HDR_REFER_TO_F,0)==-1 || !msg->refer_to)) { goto error; } /* maybe the header is already parsed! */ if (msg->refer_to->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ refer_to_b = pkg_malloc(sizeof(struct to_body)); if (refer_to_b == 0) { LM_ERR("out of pkg_memory\n"); goto error; } /* now parse it!! */ parse_to(msg->refer_to->body.s, msg->refer_to->body.s + msg->refer_to->body.len+1, refer_to_b); if (refer_to_b->error == PARSE_ERROR) { LM_ERR("bad Refer-To header\n"); pkg_free(refer_to_b); set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing REFER-TO header"); set_err_reply(400, "bad headers"); goto error; } msg->refer_to->parsed = refer_to_b; return 0; error: return -1; }
/** * Returns the Public Identity extracted from the To header * @param msg - the SIP message * @returns the str containing the private id, no mem dup */ str cscf_get_public_identity(struct sip_msg *msg) { str pu={0,0}; struct to_body *to; if (parse_headers(msg,HDR_TO_F,0)!=0) { LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity: Error parsing until header To: \n"); return pu; } if ( get_to(msg) == NULL ) { to = (struct to_body*) pkg_malloc(sizeof(struct to_body)); parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len, to ); msg->to->parsed = to; } else to=(struct to_body *) msg->to->parsed; pu = to->uri; LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: <%.*s> \n", pu.len,pu.s); return pu; }
/*! * \brief This method is used to parse P-Preferred-Identity header (RFC 3325). * * Currently only one name-addr / addr-spec is supported in the header * and it must contain a sip or sips URI. * \param msg sip msg * \return 0 on success, -1 on failure. */ int parse_ppi_header( struct sip_msg *msg ) { struct to_body* ppi_b; if ( !msg->ppi && (parse_headers(msg, HDR_PPI_F,0)==-1 || !msg->ppi)) { goto error; } /* maybe the header is already parsed! */ if (msg->ppi->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ ppi_b = pkg_malloc(sizeof(struct to_body)); if (ppi_b == 0) { LM_ERR("out of pkg_memory\n"); goto error; } /* now parse it!! */ memset(ppi_b, 0, sizeof(struct to_body)); parse_to(msg->ppi->body.s, msg->ppi->body.s + msg->ppi->body.len+1, ppi_b); if (ppi_b->error == PARSE_ERROR) { LM_ERR("bad P-Preferred-Identity header\n"); pkg_free(ppi_b); goto error; } msg->ppi->parsed = ppi_b; return 0; error: return -1; }
/*! \brief * This method is used to parse the from header. * * \note It was decided not to parse * anything in core that is not *needed* so this method gets called by * rad_acc module and any other modules that needs the FROM header. * * params: msg : sip msg * returns 0 on success, * -1 on failure. */ int parse_from_header( struct sip_msg *msg) { struct to_body* from_b; if ( !msg->from && ( parse_headers(msg,HDR_FROM_F,0)==-1 || !msg->from)) { LOG(L_ERR,"ERROR:parse_from_header: bad msg or missing FROM header\n"); goto error; } /* maybe the header is already parsed! */ if (msg->from->parsed) return 0; /* bad luck! :-( - we have to parse it */ /* first, get some memory */ from_b = pkg_malloc(sizeof(struct to_body)); if (from_b == 0) { LOG(L_ERR, "ERROR:parse_from_header: out of pkg_memory\n"); goto error; } /* now parse it!! */ memset(from_b, 0, sizeof(struct to_body)); parse_to(msg->from->body.s,msg->from->body.s+msg->from->body.len+1,from_b); if (from_b->error == PARSE_ERROR) { LOG(L_ERR, "ERROR:parse_from_header: bad from header [%.*s]\n", msg->from->body.len, msg->from->body.s); free_to(from_b); goto error; } msg->from->parsed = from_b; return 0; error: return -1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ipt_natinfo *info = (void *)*target; int portok; if (entry->ip.proto == IPPROTO_TCP || entry->ip.proto == IPPROTO_UDP || entry->ip.proto == IPPROTO_ICMP) portok = 1; else portok = 0; switch (c) { case '1': if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-source"); if (*flags) { if (!kernel_version) get_kernel_version(); if (kernel_version > LINUX_VERSION(2, 6, 10)) exit_error(PARAMETER_PROBLEM, "Multiple --to-source not supported"); } *target = parse_to(optarg, portok, info); *flags = 1; return 1; default: return 0; } }
int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2) { struct to_body *pto, TO = {0}, *pfrom = NULL; str body= {0, 0}; ua_pres_t dialog; str* res_id= NULL; db_key_t query_cols[8]; db_val_t query_vals[8]; int n_query_cols= 0; str auth_state= {0, 0}; int found= 0; str reason = {0, 0}; int auth_flag; struct hdr_field* hdr= NULL; int expires= -1; str content_type= {0, 0}; int reply_code = 500; str reply_str = pu_500_rpl; LM_DBG("start\n"); /* extract the dialog information and check if an existing dialog*/ if( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } if((!msg->event ) ||(msg->event->body.len<=0)) { LM_ERR("Missing event header field value\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } if( msg->to==NULL || msg->to->body.s==NULL) { LM_ERR("cannot parse TO header\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; LM_DBG("'To' header ALREADY PARSED: <%.*s>\n", pto->uri.len, pto->uri.s ); } else { parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO); if(TO.uri.len <= 0) { LM_ERR(" 'To' header NOT parsed\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } pto = &TO; } memset(&dialog, 0, sizeof(ua_pres_t)); dialog.watcher_uri= &pto->uri; if (pto->tag_value.s==NULL || pto->tag_value.len==0 ) { LM_ERR("to tag value not parsed\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } dialog.from_tag= pto->tag_value; if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } dialog.call_id = msg->callid->body; if (!msg->from || !msg->from->body.s) { LM_ERR("cannot find 'from' header!\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } if (msg->from->parsed == NULL) { LM_DBG("'From' header not parsed\n"); /* parsing from header */ if ( parse_from_header( msg )<0 ) { LM_ERR("cannot parse From header\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } } pfrom = (struct to_body*)msg->from->parsed; dialog.pres_uri= &pfrom->uri; if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); reply_code = 400; reply_str = pu_400_rpl; goto error; } dialog.to_tag= pfrom->tag_value; dialog.flag|= RLS_SUBSCRIBE; dialog.event= get_event_flag(&msg->event->body); if(dialog.event< 0) { LM_ERR("unrecognized event package\n"); reply_code = 489; reply_str = pu_489_rpl; goto error; } /* extract the subscription state */ hdr = msg->headers; while (hdr!= NULL) { if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0) { found = 1; break; } hdr = hdr->next; } if(found==0 ) { LM_ERR("'Subscription-State' header not found\n"); goto error; } auth_state = hdr->body; /* extract state and reason */ auth_flag= parse_subs_state(auth_state, &reason, &expires); if(auth_flag< 0) { LM_ERR("while parsing 'Subscription-State' header\n"); goto error; } if(pua_get_record_id(&dialog, &res_id)< 0) /* verify if within a stored dialog */ { LM_ERR("occured when trying to get record id\n"); goto error; } if(res_id==0) { LM_DBG("presence dialog record not found\n"); /* if it is a NOTIFY for a terminated SUBSCRIBE dialog in RLS, then * the module might not have the dialog structure anymore * - just send 200ok, it is harmless */ if(auth_flag==TERMINATED_STATE) goto done; LM_INFO("no presence dialog record for non-TERMINATED state uri pres_uri = %.*s watcher_uri = %.*s\n", dialog.pres_uri->len, dialog.pres_uri->s, dialog.watcher_uri->len, dialog.watcher_uri->s); reply_code = 481; reply_str = pu_481_rpl; goto error; } if(msg->content_type== NULL || msg->content_type->body.s== NULL) { LM_DBG("cannot find content type header header\n"); } else content_type= msg->content_type->body; /*constructing the xml body*/ if(get_content_length(msg) == 0 ) { goto done; } else { if(content_type.s== 0) { LM_ERR("content length != 0 and no content type header found\n"); goto error; } body.s=get_body(msg); if (body.s== NULL) { LM_ERR("cannot extract body from msg\n"); goto error; } body.len = get_content_length( msg ); } /* update in rlpres_table where rlsusb_did= res_id and resource_uri= from_uri*/ LM_DBG("body= %.*s\n", body.len, body.s); query_cols[n_query_cols]= &str_rlsubs_did_col; query_vals[n_query_cols].type = DB1_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val= *res_id; n_query_cols++; query_cols[n_query_cols]= &str_resource_uri_col; query_vals[n_query_cols].type = DB1_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val= *dialog.pres_uri; n_query_cols++; query_cols[n_query_cols]= &str_updated_col; query_vals[n_query_cols].type = DB1_INT; query_vals[n_query_cols].nul = 0; if (dbmode == RLS_DB_ONLY) query_vals[n_query_cols].val.int_val= core_hash(res_id, NULL, 0) % (waitn_time * rls_notifier_poll_rate * rls_notifier_processes); else query_vals[n_query_cols].val.int_val = UPDATED_TYPE; n_query_cols++; query_cols[n_query_cols]= &str_auth_state_col; query_vals[n_query_cols].type = DB1_INT; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.int_val= auth_flag; n_query_cols++; query_cols[n_query_cols]= &str_reason_col; query_vals[n_query_cols].type = DB1_STR; query_vals[n_query_cols].nul = 0; if(reason.len > 0) { query_vals[n_query_cols].val.str_val.s= reason.s; query_vals[n_query_cols].val.str_val.len= reason.len; } else { query_vals[n_query_cols].val.str_val.s = ""; query_vals[n_query_cols].val.str_val.len = 0; } n_query_cols++; query_cols[n_query_cols]= &str_content_type_col; query_vals[n_query_cols].type = DB1_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val= content_type; n_query_cols++; query_cols[n_query_cols]= &str_presence_state_col; query_vals[n_query_cols].type = DB1_STR; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val= body; n_query_cols++; query_cols[n_query_cols]= &str_expires_col; query_vals[n_query_cols].type = DB1_INT; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.int_val= expires+ (int)time(NULL); n_query_cols++; if (rlpres_dbf.use_table(rlpres_db, &rlpres_table) < 0) { LM_ERR("in use_table\n"); goto error; } if (dbmode == RLS_DB_ONLY && rlpres_dbf.start_transaction) { if (rlpres_dbf.start_transaction(rlpres_db) < 0) { LM_ERR("in start_transaction\n"); goto error; } } if (rlpres_dbf.replace != NULL) { if(rlpres_dbf.replace(rlpres_db, query_cols, query_vals, n_query_cols, 2, 0)< 0) { LM_ERR("in sql replace\n"); goto error; } LM_DBG("Inserted/replace in database table new record\n"); } else { if(rlpres_dbf.update(rlpres_db, query_cols, 0, query_vals, query_cols+2, query_vals+2, 2, n_query_cols-2)< 0) { LM_ERR("in sql update\n"); goto error; } if (rlpres_dbf.affected_rows(rlpres_db) == 0) { if(rlpres_dbf.insert(rlpres_db, query_cols, query_vals, n_query_cols)< 0) { LM_ERR("in sql insert\n"); goto error; } LM_DBG("Inserted in database table new record\n"); } } if (dbmode == RLS_DB_ONLY && rlpres_dbf.end_transaction) { if (rlpres_dbf.end_transaction(rlpres_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } LM_DBG("Updated rlpres_table\n"); /* reply 200OK */ done: if(slb.freply(msg, 200, &su_200_rpl) < 0) { LM_ERR("while sending reply\n"); goto error; } if(res_id!=NULL) { pkg_free(res_id->s); pkg_free(res_id); } if (reason.s) pkg_free(reason.s); free_to_params(&TO); return 1; error: if(slb.freply(msg, reply_code, &reply_str) < 0) { LM_ERR("failed sending reply\n"); } if(res_id!=NULL) { pkg_free(res_id->s); pkg_free(res_id); } if (reason.s) pkg_free(reason.s); free_to_params(&TO); if (dbmode == RLS_DB_ONLY && rlpres_dbf.abort_transaction) { if (rlpres_dbf.abort_transaction(rlpres_db) < 0) LM_ERR("in abort_transaction\n"); } return -1; }
void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps) { struct sip_msg* msg= NULL; int lexpire= 0; unsigned int cseq; ua_pres_t* presentity= NULL, *hentity= NULL; struct to_body *pto = NULL, TO = {0}, *pfrom = NULL; int size= 0; unsigned int hash_code; int flag ; str record_route= {0, 0}; int rt; str contact; int initial_request = 0; int end_transaction = 1; if( ps->param== NULL || *ps->param== NULL ) { LM_ERR("null callback parameter\n"); return; } if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction) { if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0) { LM_ERR("in start_transaction\n"); goto error; } } LM_DBG("completed with status %d\n",ps->code) ; hentity= (ua_pres_t*)(*ps->param); hash_code= core_hash(hentity->pres_uri,hentity->watcher_uri, HASH_SIZE); flag= hentity->flag; if(hentity->flag & XMPP_INITIAL_SUBS) hentity->flag= XMPP_SUBSCRIBE; /* get dialog information from reply message: callid, to_tag, from_tag */ msg= ps->rpl; if(msg == NULL) { LM_ERR("no reply message found\n "); goto error; } if(msg== FAKED_REPLY) { struct hdr_field *callid = NULL, *from = NULL; struct to_body FROM = {0}; callid = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field)); if (callid == NULL) { LM_ERR("Out of memory\n"); goto faked_error; } memset(callid, 0, sizeof(struct hdr_field)); get_hdr_field(t->callid.s, t->callid.s + t->callid.len, callid); hentity->call_id = callid->body; from = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field)); if (from == NULL) { LM_ERR("Out of memory\n"); goto faked_error; } memset(from, 0, sizeof(struct hdr_field)); get_hdr_field(t->from.s, t->from.s + t->from.len, from); parse_to(from->body.s, from->body.s + from->body.len + 1, &FROM); if(FROM.uri.len <= 0) { LM_ERR("'From' header NOT parsed\n"); goto faked_error; } hentity->call_id = callid->body; hentity->from_tag = (&FROM)->tag_value; hentity->to_tag.s = NULL; hentity->to_tag.len = 0; find_and_delete_dialog(hentity, hash_code); faked_error: if (callid) pkg_free(callid); free_to_params(&FROM); if (from) pkg_free(from); goto done; } if ( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("when parsing headers\n"); goto error; } if(ps->rpl->expires && msg->expires->body.len > 0) { if (!msg->expires->parsed && (parse_expires(msg->expires) < 0)) { LM_ERR("cannot parse Expires header\n"); goto error; } lexpire = ((exp_body_t*)msg->expires->parsed)->val; LM_DBG("lexpire= %d\n", lexpire); } /*if initial request */ if(hentity->call_id.s== NULL) { initial_request = 1; if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); goto error; } if (!msg->from || !msg->from->body.s) { LM_ERR("cannot find 'from' header!\n"); goto error; } if (msg->from->parsed == NULL) { if ( parse_from_header( msg )<0 ) { LM_ERR("cannot parse From header\n"); goto error; } } pfrom = (struct to_body*)msg->from->parsed; if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); goto error; } hentity->call_id= msg->callid->body; hentity->from_tag= pfrom->tag_value; if(ps->code >= 300 || lexpire == 0) { hentity->to_tag.s = NULL; hentity->to_tag.len = 0; find_and_delete_dialog(hentity, hash_code); goto done; } if( msg->to==NULL || msg->to->body.s==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s); } else { parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO); if(TO.uri.len <= 0) { LM_ERR("'To' header NOT parsed\n"); goto error; } pto = &TO; } if( pto->tag_value.s ==NULL || pto->tag_value.len == 0) { LM_ERR("no to tag value present\n"); goto error; } hentity->to_tag= pto->tag_value; } if(ps->code >= 300 ) { /* if an error code and a stored dialog delete it and try to send a subscription with type= INSERT_TYPE, else return*/ subs_info_t subs; hentity->to_tag.s = NULL; hentity->to_tag.len = 0; find_and_delete_dialog(hentity, hash_code); if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction) { if (pua_dbf.end_transaction(pua_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } end_transaction = 0; /* Redirect if the response 3XX */ memset(&subs, 0, sizeof(subs_info_t)); subs.pres_uri= hentity->pres_uri; subs.watcher_uri= hentity->watcher_uri; subs.contact= &hentity->contact; if(hentity->remote_contact.s) subs.remote_target= &hentity->remote_contact; if(hentity->desired_expires== 0) subs.expires= -1; else if(hentity->desired_expires< (int)time(NULL)) subs.expires= 0; else subs.expires= hentity->desired_expires- (int)time(NULL)+ 3; subs.flag= INSERT_TYPE; subs.source_flag= flag; subs.event= hentity->event; subs.id= hentity->id; subs.outbound_proxy= hentity->outbound_proxy; subs.extra_headers= hentity->extra_headers; subs.cb_param= hentity->cb_param; if(send_subscribe(&subs)< 0) { LM_ERR("when trying to send SUBSCRIBE\n"); goto error; } goto done; } if(lexpire== 0 ) { LM_DBG("lexpire= 0 Delete from hash table"); find_and_delete_dialog(hentity, hash_code); goto done; } /* extract the contact */ if(msg->contact== NULL || msg->contact->body.s== NULL) { LM_ERR("no contact header found"); goto error; } if( parse_contact(msg->contact) <0 ) { LM_ERR(" cannot parse contact header\n"); goto error; } if(msg->contact->parsed == NULL) { LM_ERR("cannot parse contact header\n"); goto error; } contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri; if( msg->cseq==NULL || msg->cseq->body.s==NULL) { LM_ERR("cannot parse cseq header\n"); goto error; } if( str2int( &(get_cseq(msg)->number), &cseq)< 0) { LM_ERR("while converting str to int\n"); goto error; } if(initial_request == 0) { hentity->cseq = cseq; find_and_update_dialog(hentity, hash_code, lexpire, &contact); goto done; } /*process record route and add it to a string*/ if (msg->record_route!=NULL) { rt = print_rr_body(msg->record_route, &record_route, 1, 0); if(rt != 0) { LM_ERR("parsing record route [%d]\n", rt); record_route.s=NULL; record_route.len=0; } } size= sizeof(ua_pres_t)+ 2*sizeof(str)+( pto->uri.len+ pfrom->uri.len+ pto->tag_value.len+ pfrom->tag_value.len +msg->callid->body.len+ record_route.len+ hentity->contact.len+ hentity->id.len )*sizeof(char); if(hentity->extra_headers) size+= sizeof(str)+ hentity->extra_headers->len*sizeof(char); presentity= (ua_pres_t*)shm_malloc(size); if(presentity== NULL) { LM_ERR("no more share memory\n"); goto error; } memset(presentity, 0, size); size= sizeof(ua_pres_t); presentity->pres_uri= (str*)( (char*)presentity+ size); size+= sizeof(str); presentity->pres_uri->s= (char*)presentity+ size; memcpy(presentity->pres_uri->s, pto->uri.s, pto->uri.len); presentity->pres_uri->len= pto->uri.len; size+= pto->uri.len; presentity->watcher_uri= (str*)( (char*)presentity+ size); size+= sizeof(str); presentity->watcher_uri->s= (char*)presentity+ size; memcpy(presentity->watcher_uri->s, pfrom->uri.s, pfrom->uri.len); presentity->watcher_uri->len= pfrom->uri.len; size+= pfrom->uri.len; presentity->call_id.s= (char*)presentity + size; memcpy(presentity->call_id.s,msg->callid->body.s, msg->callid->body.len); presentity->call_id.len= msg->callid->body.len; size+= presentity->call_id.len; presentity->to_tag.s= (char*)presentity + size; memcpy(presentity->to_tag.s,pto->tag_value.s, pto->tag_value.len); presentity->to_tag.len= pto->tag_value.len; size+= pto->tag_value.len; presentity->from_tag.s= (char*)presentity + size; memcpy(presentity->from_tag.s,pfrom->tag_value.s, pfrom->tag_value.len); presentity->from_tag.len= pfrom->tag_value.len; size+= pfrom->tag_value.len; if(record_route.len && record_route.s) { presentity->record_route.s= (char*)presentity + size; memcpy(presentity->record_route.s, record_route.s, record_route.len); presentity->record_route.len= record_route.len; size+= record_route.len; pkg_free(record_route.s); record_route.s = NULL; } presentity->contact.s= (char*)presentity + size; memcpy(presentity->contact.s, hentity->contact.s, hentity->contact.len); presentity->contact.len= hentity->contact.len; size+= hentity->contact.len; if(hentity->id.s) { presentity->id.s=(char*)presentity+ size; memcpy(presentity->id.s, hentity->id.s, hentity->id.len); presentity->id.len= hentity->id.len; size+= presentity->id.len; } if(hentity->extra_headers) { presentity->extra_headers= (str*)((char*)presentity+ size); size+= sizeof(str); presentity->extra_headers->s=(char*)presentity+ size; memcpy(presentity->extra_headers->s, hentity->extra_headers->s, hentity->extra_headers->len); presentity->extra_headers->len= hentity->extra_headers->len; size+= hentity->extra_headers->len; } /* write the remote contact filed */ presentity->remote_contact.s= (char*)shm_malloc(contact.len* sizeof(char)); if(presentity->remote_contact.s==NULL) { ERR_MEM(SHARE_MEM); } memcpy(presentity->remote_contact.s, contact.s, contact.len); presentity->remote_contact.len= contact.len; presentity->event|= hentity->event; presentity->flag= hentity->flag; presentity->etag.s= NULL; presentity->cseq= cseq; presentity->desired_expires= hentity->desired_expires; presentity->expires= lexpire+ (int)time(NULL); if(BLA_SUBSCRIBE & presentity->flag) { LM_DBG("BLA_SUBSCRIBE FLAG inserted\n"); } LM_DBG("record for subscribe from %.*s to %.*s inserted in datatbase\n", presentity->watcher_uri->len, presentity->watcher_uri->s, presentity->pres_uri->len, presentity->pres_uri->s); if (dbmode==PUA_DB_ONLY) { if (pua_dbf.end_transaction) { if (pua_dbf.end_transaction(pua_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } if (pua_dbf.start_transaction) { if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0) { LM_ERR("in start_transaction\n"); goto error; } } if (convert_temporary_dialog_puadb(presentity) < 0) { LM_ERR("Could not convert temporary dialog into a dialog\n"); goto error; } } else { if (convert_temporary_dialog(presentity) < 0) { LM_ERR("Could not convert temporary dialog into a dialog\n"); goto error; } } done: if(hentity->ua_flag == REQ_OTHER) { hentity->flag= flag; run_pua_callbacks( hentity, msg); } if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction && end_transaction) { if (pua_dbf.end_transaction(pua_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } goto end; error: if (presentity) { if (presentity->remote_contact.s) shm_free(presentity->remote_contact.s); shm_free(presentity); } if(record_route.s) pkg_free(record_route.s); if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction) { if (pua_dbf.abort_transaction(pua_db) < 0) LM_ERR("in abort_transaction\n"); } end: if(hentity) { shm_free(hentity); hentity= NULL; } free_to_params(&TO); return; }
/* returns pointer to next header line, and fill hdr_f ; * if at end of header returns pointer to the last crlf (always buf)*/ char* get_hdr_field(char* const buf, char* const end, struct hdr_field* const hdr) { char *tmp = 0; char *match; struct via_body *vb; struct cseq_body* cseq_b; struct to_body* to_b; int integer, err; unsigned uval; if(!buf) { DBG("null buffer pointer\n"); goto error; } if ((*buf)=='\n' || (*buf)=='\r') { /* double crlf or lflf or crcr */ DBG("found end of header\n"); hdr->type=HDR_EOH_T; return buf; } tmp=parse_hname(buf, end, hdr); if (hdr->type==HDR_ERROR_T) { LOG(L_ERR, "ERROR: get_hdr_field: bad header\n"); goto error; } /* eliminate leading whitespace */ tmp=eat_lws_end(tmp, end); if (tmp>=end) { LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n"); goto error; } /* if header-field well-known, parse it, find its end otherwise ; * after leaving the hdr->type switch, tmp should be set to the * next header field */ switch(hdr->type) { case HDR_VIA_T: /* keep number of vias parsed -- we want to report it in replies for diagnostic purposes */ via_cnt++; vb=pkg_malloc(sizeof(struct via_body)); if (vb==0) { LOG(L_ERR, "get_hdr_field: out of memory\n"); goto error; } memset(vb,0,sizeof(struct via_body)); hdr->body.s=tmp; tmp=parse_via(tmp, end, vb); if (vb->error==PARSE_ERROR) { LOG(L_ERR, "ERROR: get_hdr_field: bad via\n"); free_via_list(vb); goto error; } hdr->parsed=vb; vb->hdr.s=hdr->name.s; vb->hdr.len=hdr->name.len; hdr->body.len=tmp-hdr->body.s; break; case HDR_CSEQ_T: cseq_b=pkg_malloc(sizeof(struct cseq_body)); if (cseq_b==0) { LOG(L_ERR, "get_hdr_field: out of memory\n"); goto error; } memset(cseq_b, 0, sizeof(struct cseq_body)); hdr->body.s=tmp; tmp=parse_cseq(tmp, end, cseq_b); if (cseq_b->error==PARSE_ERROR) { LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n"); free_cseq(cseq_b); goto error; } hdr->parsed=cseq_b; hdr->body.len=tmp-hdr->body.s; DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n", hdr->name.len, ZSW(hdr->name.s), cseq_b->number.len, ZSW(cseq_b->number.s), cseq_b->method.len, cseq_b->method.s); break; case HDR_TO_T: to_b=pkg_malloc(sizeof(struct to_body)); if (to_b==0) { LOG(L_ERR, "get_hdr_field: out of memory\n"); goto error; } memset(to_b, 0, sizeof(struct to_body)); hdr->body.s=tmp; tmp=parse_to(tmp, end,to_b); if (to_b->error==PARSE_ERROR) { LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n"); free_to(to_b); goto error; } hdr->parsed=to_b; hdr->body.len=tmp-hdr->body.s; DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n", hdr->name.len, ZSW(hdr->name.s), hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s)); DBG("DEBUG: to body [%.*s]\n",to_b->body.len, ZSW(to_b->body.s)); break; case HDR_CONTENTLENGTH_T: hdr->body.s=tmp; tmp=parse_content_length(tmp,end, &integer); if (tmp==0) { LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n"); goto error; } hdr->parsed=(void*)(long)integer; hdr->body.len=tmp-hdr->body.s; DBG("DEBUG: get_hdr_body : content_length=%d\n", (int)(long)hdr->parsed); break; case HDR_RETRY_AFTER_T: hdr->body.s=tmp; tmp=parse_retry_after(tmp,end, &uval, &err); if (err) { LOG(L_ERR, "ERROR:get_hdr_field: bad retry_after header\n"); goto error; } hdr->parsed=(void*)(unsigned long)uval; hdr->body.len=tmp-hdr->body.s; DBG("DEBUG: get_hdr_body : retry_after=%d\n", (unsigned)(long)hdr->parsed); break; case HDR_IDENTITY_T: case HDR_DATE_T: case HDR_IDENTITY_INFO_T: case HDR_SUPPORTED_T: case HDR_REQUIRE_T: case HDR_CONTENTTYPE_T: case HDR_FROM_T: case HDR_CALLID_T: case HDR_CONTACT_T: case HDR_ROUTE_T: case HDR_RECORDROUTE_T: case HDR_MAXFORWARDS_T: case HDR_AUTHORIZATION_T: case HDR_EXPIRES_T: case HDR_PROXYAUTH_T: case HDR_PROXYREQUIRE_T: case HDR_UNSUPPORTED_T: case HDR_ALLOW_T: case HDR_EVENT_T: case HDR_ACCEPT_T: case HDR_ACCEPTLANGUAGE_T: case HDR_ORGANIZATION_T: case HDR_PRIORITY_T: case HDR_SUBJECT_T: case HDR_USERAGENT_T: case HDR_SERVER_T: case HDR_CONTENTDISPOSITION_T: case HDR_DIVERSION_T: case HDR_RPID_T: case HDR_SIPIFMATCH_T: case HDR_REFER_TO_T: case HDR_SESSIONEXPIRES_T: case HDR_MIN_SE_T: case HDR_SUBSCRIPTION_STATE_T: case HDR_ACCEPTCONTACT_T: case HDR_ALLOWEVENTS_T: case HDR_CONTENTENCODING_T: case HDR_REFERREDBY_T: case HDR_REJECTCONTACT_T: case HDR_REQUESTDISPOSITION_T: case HDR_WWW_AUTHENTICATE_T: case HDR_PROXY_AUTHENTICATE_T: case HDR_PATH_T: case HDR_PRIVACY_T: case HDR_PAI_T: case HDR_PPI_T: case HDR_REASON_T: case HDR_OTHER_T: /* just skip over it */ hdr->body.s=tmp; /* find end of header */ /* find lf */ do { match=q_memchr(tmp, '\n', end-tmp); if (match) { match++; } else { LOG(L_ERR, "ERROR: get_hdr_field: bad body for <%s>(%d)\n", hdr->name.s, hdr->type); /* abort(); */ tmp=end; goto error; } tmp=match; } while( match<end &&( (*match==' ')||(*match=='\t') ) ); tmp=match; hdr->body.len=match-hdr->body.s; break; default: LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n", hdr->type); goto error; } /* jku: if \r covered by current length, shrink it */ trim_r( hdr->body ); hdr->len=tmp-hdr->name.s; return tmp; error: DBG("get_hdr_field: error exit\n"); STATS_BAD_MSG_HDR(); hdr->type=HDR_ERROR_T; hdr->len=tmp-hdr->name.s; return tmp; }