1 #include <stdio.h>
2 #include "parse_next_hop.h"
3 #include "parse_common.h"
4 #include "log.h"
5
parse_next_hop(const cstring & next_hop,list<sip_destination> & dest_list)6 int parse_next_hop(const cstring& next_hop,
7 list<sip_destination>& dest_list)
8 {
9 enum {
10 IPL_BEG=0,
11 IPL_HOST,
12 IPL_V6,
13 IPL_HOST_SEP,
14 IPL_PORT,
15 IPL_TRSP
16 };
17
18 int st = IPL_BEG;
19
20 const char* c = next_hop.s;
21 const char* end = c + next_hop.len;
22 const char* beg = NULL;
23
24 sip_destination dest;
25
26 for(;c<end; c++) {
27
28 switch(st){
29
30 case IPL_BEG:
31 switch(*c){
32 case SP:
33 case HTAB:
34 continue;
35 default:
36 beg = c;
37 st = IPL_HOST;
38 dest.host.clear();
39 dest.port = 0;
40 break;
41 }
42 // fall-through trap
43 case IPL_HOST:
44 switch(*c){
45 case '[':
46 st = IPL_V6;
47 beg = c+1;
48 break;
49 case ':':
50 st = IPL_PORT;
51 dest.host.set(beg,c-beg);
52 break;
53 case '/':
54 st = IPL_TRSP;
55 dest.host.set(beg,c-beg);
56 beg = c+1;
57 break;
58 case ',':
59 st = IPL_BEG;
60 dest.host.set(beg,c-beg);
61 dest_list.push_back(dest);
62 break;
63 case SP:
64 case HTAB:
65 st = IPL_HOST_SEP;
66 dest.host.set(beg,c-beg);
67 break;
68 default:
69 break;
70 }
71 break;
72
73 case IPL_V6:
74 switch(*c){
75 case ']':
76 st = IPL_HOST_SEP;
77 dest.host.set(beg,c-beg);
78 break;
79 default:
80 break;
81 }
82 break;
83
84 case IPL_HOST_SEP:
85 switch(*c){
86 case ':':
87 st = IPL_PORT;
88 break;
89 case ',':
90 st = IPL_BEG;
91 dest_list.push_back(dest);
92 break;
93 case '/':
94 st = IPL_TRSP;
95 beg = c+1;
96 break;
97 default:
98 // syntax error
99 DBG("error: unexpected character '%c' in IPL_HOST_SEP state.\n",*c);
100 return -1;
101 }
102 break;
103
104 case IPL_PORT:
105 switch(*c){
106 case '/':
107 st = IPL_TRSP;
108 beg = c+1;
109 break;
110 case ',':
111 st = IPL_BEG;
112 dest_list.push_back(dest);
113 break;
114 case SP:
115 case HTAB:
116 break;
117 default:
118 if(*c < '0' && *c > '9'){
119 DBG("error: unexpected character '%c' in IPL_PORT state.\n",*c);
120 return -1;
121 }
122 dest.port = dest.port*10 + (*c - '0');
123 break;
124 }
125 break;
126
127
128 case IPL_TRSP:
129 switch(*c){
130 case ',':
131 st = IPL_BEG;
132 dest.trsp.set(beg,c-beg);
133 dest_list.push_back(dest);
134 break;
135 default:
136 if( (*c >= 'a' && *c <= 'z') ||
137 (*c >= 'A' && *c <= 'Z') ) {
138 continue;
139 }
140 // syntax error
141 DBG("error: unexpected character '%c' in IPL_TRSP state.\n",*c);
142 return -1;
143 }
144 break;
145 }
146 }
147
148 switch(st){
149 case IPL_BEG:
150 // no host at all
151 // possibly, the string was empty
152 break;
153 case IPL_HOST:
154 dest.host.set(beg,c-beg);
155 dest_list.push_back(dest);
156 break;
157 case IPL_V6:
158 case IPL_HOST_SEP:
159 case IPL_PORT:
160 dest_list.push_back(dest);
161 break;
162 case IPL_TRSP:
163 dest.trsp.set(beg,c-beg);
164 dest_list.push_back(dest);
165 break;
166 }
167
168 return 0;
169 }
170