📄 parse_hname.c
字号:
/* * $Id: parse_hname.c,v 1.3 2004/08/24 09:01:29 janakj Exp $ * * header name parsing automaton: * parsing: compact form: * Via: v: * From: f: * To: t: * Cseq: n/a * Call-ID: i: * Contact: m: * Max-Forwards: n/a * Route: n/a * Record-Route: n/a * * 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 */#include "msg_parser.h"#include "../dprint.h"enum { INITIAL=0, VIA1, VIA2, FROM1, FROM2, FROM3, TO1, C_START, CSEQ2, CSEQ3, CALLID2, CALLID3, CALLID4, CALLID5, CALLID6, CONTACT2, CONTACT3, CONTACT4, CONTACT5, CONTACT6, M_FOUND, MAXFORWARDS2, MAXFORWARDS3, MAXFORWARDS4, MAXFORWARDS5, MAXFORWARDS6, MAXFORWARDS7, MAXFORWARDS8, MAXFORWARDS9, MAXFORWARDS10, MAXFORWARDS11, ROUTE1, ROUTE2, ROUTE3, ROUTE4, RECROUTE1, RECROUTE2, RECROUTE3, RECROUTE4, RECROUTE5, RECROUTE6, RECROUTE7, RECROUTE8, RECROUTE9, RECROUTE10, /* final states*/ F_VIA=1000, F_FROM, F_TO, F_CSEQ, F_CALLID, F_CONTACT, F_MAXFORWARDS, F_ROUTE, F_RECROUTE, I_START, UNKNOWN_HEADER=200, BODY=220, LF=25000 };/* returns end or pointer to next elem*/char* parse_hname1(char* p, char* end, struct hdr_field* hdr){ char* t; register int state; int err; err=0; state=INITIAL; for(t=p;t<end;t++){ switch(*t){ case 'V': case 'v': switch(state){ case INITIAL: state=VIA1; hdr->name.s=t; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'I': case 'i': switch(state){ case VIA1: state=VIA2; break; case CALLID5: state=CALLID6; break; case INITIAL: state=I_START; hdr->name.s=t; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'A': case 'a': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case VIA2: state=F_VIA; break; case C_START: /*CALLID1*/ state=CALLID2; break; case CONTACT4: state=CONTACT5; break; case M_FOUND: state=MAXFORWARDS2; break; case MAXFORWARDS8: state=MAXFORWARDS9; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'F': case 'f': switch(state){ case INITIAL: state=FROM1; hdr->name.s=t; break; case MAXFORWARDS4: state=MAXFORWARDS5; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'R': case 'r': switch(state){ case INITIAL: state=ROUTE1; hdr->name.s=t; break; case FROM1: state=FROM2; break; case MAXFORWARDS6: state=MAXFORWARDS7; break; case MAXFORWARDS9: state=MAXFORWARDS10; break; case RECROUTE3: state=RECROUTE4; break; case RECROUTE6: state=RECROUTE7; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'O': case 'o': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case FROM2: state=FROM3; break; case TO1: state=F_TO; break; case C_START: /*CONTACT1 */ state=CONTACT2; break; case ROUTE1: state=ROUTE2; break; case MAXFORWARDS5: state=MAXFORWARDS6; break; case RECROUTE2: state=RECROUTE3; break; case RECROUTE7: state=RECROUTE8; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'M': case 'm': switch(state){ case INITIAL: state=M_FOUND; hdr->name.s=t; break; case FROM3: state=F_FROM; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'T': case 't': switch(state){ case INITIAL: state=TO1; hdr->name.s=t; break; case CONTACT3: state=CONTACT4; break; case CONTACT6: state=F_CONTACT; break; case ROUTE3: state=ROUTE4; break; case RECROUTE9: state=RECROUTE10; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'C': case 'c': switch(state){ case INITIAL: state=C_START; hdr->name.s=t; break; case CONTACT5: state=CONTACT6; break; case RECROUTE1: state=RECROUTE2; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'S': case 's': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case C_START: state=CSEQ2; break; case MAXFORWARDS11: state=F_MAXFORWARDS; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'E': case 'e': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case CSEQ2: state=CSEQ3; break; case ROUTE4: state=F_ROUTE; break; case ROUTE1: state=RECROUTE1; break; case RECROUTE10: state=F_RECROUTE; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'Q': case 'q': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case CSEQ3: state=F_CSEQ; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'L': case 'l': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case CALLID2: state=CALLID3; break; case CALLID3: state=CALLID4; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'D': case 'd': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case CALLID6: state=F_CALLID; break; case MAXFORWARDS10: state=MAXFORWARDS11; break; case RECROUTE4: state=RECROUTE5; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'N': case 'n': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case CONTACT2: state=CONTACT3; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'X': case 'x': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case MAXFORWARDS2: state=MAXFORWARDS3; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case '-': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case CALLID4: state=CALLID5; break; case MAXFORWARDS3: state=MAXFORWARDS4; break; case RECROUTE5: state=RECROUTE6; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'W': case 'w': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case MAXFORWARDS7: state=MAXFORWARDS8; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case 'U': case 'u': switch(state){ case INITIAL: state=UNKNOWN_HEADER; hdr->name.s=t; break; case ROUTE2: state=ROUTE3; break; case RECROUTE8: state=RECROUTE9; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case ' ': switch(state){ case INITIAL: break; /*eat space */ case F_VIA: case F_FROM: case F_TO: case F_CSEQ: case F_CALLID: case F_CONTACT: case F_MAXFORWARDS: case F_ROUTE: case F_RECROUTE: break; /* eat trailing space*/ case VIA1: /*compact form: v: */ state=F_VIA; break; case FROM1: /*compact form f:*/ state=F_FROM; break; case TO1: /*compact form t:*/ state=F_TO; break; case I_START: /*compact form i: (Call-ID)*/ state=F_CALLID; break; case M_FOUND: /*compact form m: (Contact)*/ state=F_CONTACT; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } break; case ':': switch(state){ case F_VIA: case VIA1: /* compact form*/ *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_VIA; goto skip; case F_FROM: case FROM1: /*compact form*/ *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_FROM; goto skip; case F_TO: case TO1: /*compact form*/ *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_TO; goto skip; case F_CSEQ: *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_CSEQ; goto skip; case F_CALLID: case I_START: /*compact form*/ *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_CALLID; goto skip; case F_CONTACT: case M_FOUND: /*compact form*/ *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_CONTACT; goto skip; case F_MAXFORWARDS: *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_MAXFORWARDS; goto skip; case F_ROUTE: *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_ROUTE; goto skip; case F_RECROUTE: *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_RECORDROUTE; goto skip; case UNKNOWN_HEADER: *t=0; hdr->name.len=t-hdr->name.s; hdr->type=HDR_OTHER; goto skip; default: /* unknown header, e.g: "c:"*/ *t=0; DBG("unknown header found, prev. state=%d\n", state); state=UNKNOWN_HEADER; hdr->name.len=t-hdr->name.s; hdr->type=HDR_OTHER; goto skip; } break; case '\n': case '\r': /*not allowed in hname*/ goto error; default: switch(state){ case INITIAL: hdr->name.s=t; state=UNKNOWN_HEADER; break; case UNKNOWN_HEADER: break; default: state=UNKNOWN_HEADER; } } }/* if we are here => we didn't find ':' => error*/ error: hdr->type=HDR_ERROR; return t;skip: DBG("end of header name found, state=%d\n", state); t++; return t;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -