📄 sipb_bnftools.cpp
字号:
}// void sipb_bnftools::check_statuscode(bnf_parsval*pv_recv,string expect_sc, sipb_errwarn& ew){ string stc; if (!pv_recv->get_one("Status-Code",stc)) ew.add_error("Can't find Status-Code in responce"); if (stc!=expect_sc) ew.add_error("We wait "+expect_sc+" Status-Code but recive "+stc);}// bool sipb_bnftools::check_statuscode(bnf_parsval*pv_recv,string expect_sc){ string stc; if (!pv_recv->get_one("Status-Code",stc)) return false; if (stc!=expect_sc) return false; return true;}// void sipb_bnftools::check_base_req(bnf_parsval*pv_recv, bnf_parsval*pv_send, sipb_errwarn&ew,sipb_errwarn&ew_gen){ bnf_parsval *ps,*pr; //0. Read Status-Code (we need read status, for To-tag check) int status_code=0; string status_code_str; if (!pv_recv->get_one("Status-Code",status_code_str)) ew.add_error("Can't find Status-Code"); status_code=atoi(status_code_str.c_str()); if (status_code==0) //bad status code ew.add_error("Bad Status-Code="+status_code_str); //1. Check SIP-Version if ( !pv_recv->get_one("SIP-Version",pr) ) ew.add_error("Can't find SIP-Version in Response"); else if ( !casecmp(pr->get_data(),"sip/2.0") ) ew.add_error("SIP-Version not sip/2.0"); //2. Check From if ( !pv_send->get_one("From",ps) ) { ew_gen.add_error("Can't find From in send packet, or multi From "); if (pv_send->is_present("From")) ew_gen.add_error("BUT PRESENT"); } else if ( !pv_recv->get_one("From",pr) ) ew.add_error("Can't find From in response packet, or multi From (probably bad grammar)"); else if ( !cmp_from(ps,pr) ) ew.add_error("From in response not equivalent From in request but MUST be (rfc3261 8.2.6.2)"); //3. Check Call-ID if ( !pv_send->get_one("Call-ID",ps) ) ew_gen.add_error("Can't find Call-ID in send packet, or multi Call-ID"); else if ( !pv_recv->get_one("Call-ID",pr) ) ew.add_error("Can't find Call-ID in response packet, or multi Call-ID (probably bad grammar)"); else if ( !cmp_values(ps,pr,"callid")) ew.add_error("Call-ID in response not equivalent Call-ID in request but MUST be (rfc3261 8.2.6.2)"); //4. Check CSeq if ( !pv_send->get_one("CSeq",ps) ) ew_gen.add_error("Can't find CSeq in send packet, or multi CSeq"); else if ( !pv_recv->get_one("CSeq",pr) ) ew.add_error("Can't find CSeq in response packet, or multi CSeq (probably bad grammar)"); else if ( !cmp_cseq(ps,pr) ) ew.add_error("CSeq in response not equivalent CSeq in request but MUST be (rfc3261 8.2.6.2)"); //5. Check Via if ( !pv_send->get_one("via-parm",ps) ) ew_gen.add_error("Can't find Via in send packet, or multi Via"); //we check response! in responce must be single via else if ( !pv_recv->get_one("via-parm",pr) ) ew.add_error("Can't find Via in response packet, or multi Via"); else if ( !cmp_viaparm_notrecived(ps,pr) ) ew.add_error(string("Via in response not equivalent Via in request")+ " but MUST be (rfc3261 8.2.6.2), except recived) "); //6. Check To if ( !pv_send->get_one("To",ps) ) { ew_gen.add_error("Can't find To in send packet, or multi To"); if (pv_send->is_present("To")) ew_gen.add_error("BUT PRESENT"); } else if ( !pv_recv->get_one("To",pr) ) ew.add_error("Can't find To in response packet, or multi To (probably bad grammar)"); else if ( !cmp_to_nottag(ps,pr) ) ew.add_error("To in response not equivalent To in request but MUST be (rfc3261 8.2.6.2)"); //6.1 check add to-tag if ( !ps->is_present("tag-param") ) //not find To-tag in send(request) if (!pr->is_present("tag-param")) //not find To-tag in recv(responce) if ( status_code != 100 ) //for 100 Trying we only may add to-tag ew.add_error("In To-field tag-parameter not found. But UAS MUST " "add a tag parameter in request (rfc3261 8.2.6.2)"); //7 Check Content-length bnf_parsval* tmp_pv; int real_clen; if (!pr->get_one("message-body",tmp_pv)) real_clen=0; else real_clen=tmp_pv->get_data().size(); if (!pr->get_one("Content-Length",tmp_pv)) { if ( real_clen > 0 ) ew.add_error("Content is present but Content-length not present"); } else { int clen=atoi(tmp_pv->get_data().c_str()); if (clen!=real_clen) ew.add_error("Content-Length!=real content length"); }}// void sipb_bnftools::check_grammar(bnf_parser&fc,bnf_parser&fp,int n_rand,int n){ string rez; int len=0; vector<string> bad; map<string,bnf_rule*>::iterator it=fc.rules.begin(); for (;it!=fc.rules.end();it++) { if (fp.is_rule_exist(it->first)) { cout<<it->first<<endl; for (int j=0;j<n;j++) { fc.reparse(it->first,rez,n_rand); bnf_parsval val; if (!fp.try_parse(val,it->first,rez)) { cout<<it->first<<endl; cout<<"------"<<endl; cout<<rez<<endl; cout<<"------"<<endl; j=n; bad.push_back(it->first); } } } } cout<<endl<<"Bad!!!!!!"<<endl; for (unsigned int i=0;i<bad.size();i++) cout<<bad[i]<<endl;}// void sipb_bnftools::check_regcontact(bnf_parsval*pv_recv,bnf_parsval*pv_send, sipb_errwarn&ew){ vector<bnf_parsval*> pv_s; vector<bnf_parsval*> pv_r; pv_send->get("contact-param",pv_s); pv_recv->get("contact-param",pv_r); if (pv_s.size()==0) throw logic_error("Error in sipb_bnftools:::check_regcontact not find Contact in send packet"); //check expiration for (unsigned int i=0;i<pv_r.size();i++) if (pv_r[i]->get_quan("c-p-expires")!=1) ew.add_error("Can't find expires parameter in Contact, " "or multi expires, but registrar MUST add it " "(rfc3261 10.3 item 8)"); //get general Expires field string epar_gen; if (!pv_recv->get_one("expires-delta-seconds",epar_gen)) epar_gen="60"; //set by default for (unsigned int i=0;i<pv_s.size();i++) { //read expires parameter string epar; if (!pv_s[i]->get_one("c-p-expires-ds",epar)) epar=epar_gen; //find same Contact in responce bnf_parsval* tmp_s; bnf_parsval* tmp_r=0; if (!pv_s[i]->get_one("addr-spec",tmp_s)) throw logic_error("Error in sipb_bnftools:::check_regcontact"); for (unsigned int j=0;j<pv_r.size() && tmp_r==0 ;j++) { if (!pv_r[j]->get_one("addr-spec",tmp_r)) throw logic_error("Error in sipb_bnftools:::check_regcontact"); if (!cmp_addrspec(tmp_s,tmp_r)) tmp_r=0; } if (tmp_r==0) //not find { if (atoi(epar.c_str()) != 0) ew.add_error("In request, in Contact header \""+ pv_s[i]->get_data()+"\" expires parameter != 0 but in "+ " response we can't find this Contact header (rfc3261 10.3)"); } else { if (atoi(epar.c_str()) == 0) ew.add_error("In request , in Contact header \""+ pv_s[i]->get_data()+"\" expires parameter == 0 "+ "but in responce we find this Contact header (rfc3261 10.3)"); } }}// bool sipb_bnftools::cmp_addrspec_uh_port(bnf_parsval*as1,bnf_parsval*as2){ if (as1->name() != "addr-spec" || as2->name() != "addr-spec") throw logic_error("Error in sipb_bnftools::cmp_addrspec_cononic"); bnf_parsval *p1,*p2; if ( ( as1->get_one("SIP-URI",p1) && as2->get_one("SIP-URI",p2) ) || ( as1->get_one("SIPS-URI",p1) && as2->get_one("SIPS-URI",p2) )) { if (!cmp_values(p1,p2,"userinfo")) return false; if (!casecmp_values(p1,p2,"hostport")) //my be port by default { bnf_parsval *pp1,*pp2; if (!p1->get_one("hostport",pp1) || !p2->get_one("hostport",pp2)) throw logic_error("Error in sipb_bnftools::cmp_addrspec_cononic"); if (!casecmp_values(pp1,pp2,"host")) return false; string port; if ((!pp1->get_one("port",port)) && (!pp2->get_one("port",port))) throw logic_error("Error in sipb_bnftools::cmp_addrspec_cononic"); if (pp1->get_one("port",port)) if ( (pp2->get_quan("port") != 0 ) || port!="5060") return false; if (pp2->get_one("port",port)) if ((pp1->get_quan("port")!=0) || (port!="5060")) return false; } return true; } else throw logic_error("Error in sipb_bnftools::cmp_addrspec_cononic work only wirh SIP-URI or SIPS-URI");}// bool sipb_bnftools::find_contact_port(bnf_parsval*pv_recv, int port){ vector<bnf_parsval*> v; pv_recv->get("contact-param",v); for (unsigned int i=0;i<v.size();i++) { bnf_parsval*hp; if (!v[i]->get_one("hostport",hp)) throw logic_error("Error in sipb_bnftools::find_contact_port"); string p; if (hp->get_one("port",p) && (port == atoi(p.c_str())) ) return true; } return false;}// void sipb_bnftools::vec_add(string s,vector<string>& v,char sep){ string tmp; string::const_iterator it=s.begin(); while (it!=s.end() && *it==sep) it++; while (it!=s.end()) { if (*it==sep) { v.push_back(tmp); tmp=""; while (it!=s.end() && *it==sep) it++; } else tmp.push_back(*(it++)); } if (tmp!="") v.push_back(tmp);}// bool sipb_bnftools::casecmp(const string& s1,const string&s2){ string::const_iterator it1=s1.begin(); string::const_iterator it2=s2.begin(); while ( it1 != s1.end() && it2 != s2.end() ) { if (toupper( *it1 ) != toupper( *it2 ) ) return false; it1++; it2++; } return ( it1 == s1.end() ) && ( it2 == s2.end() );}// bool sipb_bnftools::cmp_values(bnf_parsval*v1,bnf_parsval*v2,string rule, bool case_sence){ vector<bnf_parsval*> pv1,pv2; v1->get(rule,pv1); v2->get(rule,pv2); if (pv1.size()!=pv2.size()) return false; for (unsigned int i=0;i<pv1.size();i++) { if (case_sence) { if (pv1[i]->get_data() != pv2[i]->get_data()) return false; } else { if ( !casecmp(pv1[i]->get_data(),pv2[i]->get_data()) ) return false; } } return true;}// bool sipb_bnftools::cmp_addrspec(bnf_parsval*v1,bnf_parsval*v2){ //v1 and v2 may be addr-spec or name-addr //1. compare display-name if present in name-addr //We must'nt compare display-name (20.20) //2. compare URI bnf_parsval *p1,*p2; if ( (v1->get_one("SIP-URI",p1) || v1->get_one("SIPS-URI",p1)) && (v2->get_one("SIP-URI",p2) || v2->get_one("SIPS-URI",p2))) { if (!cmp_uri(p1,p2)) return false; } else throw logic_error("Error in cmp_addrspec Not find SIP or SIPS URS in values"); return true;}// // bool sipb_bt_challenge::read(bnf_parsval* v,string& err){ vector<bnf_parsval*> cl; v->get("challenge",cl); if (cl.size()!=1) { err="Not one challenge"; return false; } if (!cl[0]->is_present("digest-cln")) { err="Not present any digest-cln"; return false; } if (!cl[0]->is_present("realm")) { err="Not present realm"; return false; } if (!cl[0]->is_present("nonce")) { err="Not present nonce"; return false; } if (!cl[0]->is_present("algorithm")) algo=MD5; //by default vector<bnf_parsval*> d; cl[0]->get("digest-cln",d); for (unsigned int i=0;i<d.size();i++) //over all digest-cln { if (d[i]->is_present("realm")) _realm=sipb_bnftools::read_qstr(d[i]); else if (d[i]->is_present("nonce")) _nonce=sipb_bnftools::read_qstr(d[i]); else if (d[i]->is_present("algorithm")) { if (d[i]->is_present("md5_str")) algo=MD5; else if (d[i]->is_present("md5_sess_str")) algo=MD5_session; else algo=other_algo; } } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -