RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src / router / udpxy / rparse.c
blob8162243c2fe8e74159c704263e8d02ecefb28ce7
1 /* @(#) parsing functions for udpxy
3 * Copyright 2008-2011 Pavel V. Cherenkov (pcherenkov@gmail.com)
5 * This file is part of udpxy.
7 * udpxy is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * udpxy is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with udpxy. If not, see <http://www.gnu.org/licenses/>.
21 #include <string.h>
22 #include <sys/types.h>
23 #include <stdlib.h>
24 #include <stdio.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
30 #include <assert.h>
32 #include "rparse.h"
33 #include "mtrace.h"
35 /* parse and copy parameters of HTTP GET request into
36 * request buffer
38 * @param src buffer with raw source data
39 * @param srclen length of raw data
40 * @param request destination buffer for the request
41 * @param rqlen length of request buffer on entry
42 * length of request on exit
44 * @return 0 if success: request buffer gets populated,
45 * non-zero if error
47 int
48 get_request( const char* src, size_t srclen,
49 char* request, size_t* rqlen )
51 const char HEAD[] = "GET /";
52 char* p = NULL;
53 const char* EOD = src + srclen - 1;
54 size_t n = 0;
55 const char SPACE[] = " ";
57 p = strstr( src, HEAD );
58 if( NULL == p ) return 1; /* no header */
60 p += (sizeof(HEAD) - 1);
61 if( p >= EOD) /* no request */
62 return 2;
64 n = strcspn( p, " " );
65 if( (SPACE[0] != p[n]) || ((p + n) > EOD) || (n >= *rqlen) ) /* overflow */
66 return 3;
68 (void) strncpy( request, p, n );
69 request[ n ] = '\0';
71 *rqlen = n;
73 return 0;
77 /* parse (GET) request into command and parameters (options)
78 * c-strings
80 * @param s source c-string
81 * @param cmd buffer for the parsed command c-string
82 * @param clen length of command buffer
83 * @param opt buffer for the parsed options c-string
84 * @param optlen length of options buffer
86 * @return 0 if success: cmd and opt get get populated
87 * non-zero if an error ocurred
89 int
90 parse_param( const char* s, size_t slen,
91 char* cmd, size_t clen,
92 char* opt, size_t optlen )
94 const char DLM = '/';
95 unsigned i, j;
97 assert( s && cmd && (clen > (size_t)0) && opt && (optlen > (size_t)0) );
99 *cmd = *opt = '\0';
100 if( (size_t)0 == slen ) return 0; /* empty source */
102 /* request ::= [DLM] cmd [DLM opt] */
104 /* skip leading delimiter */
105 i = ( DLM == s[0] ) ? 1 : 0;
107 /* copy into cmd until next delimiter or EOD */
108 for( j = 0; (i < slen) && (j < clen) && s[i] && (s[i] != DLM); ) {
109 cmd[j++] = s[i++];
111 if( j >= clen ) return 1;
112 cmd[ j ] = '\0';
114 /* skip dividing delimiter */
115 if( DLM == s[i] ) ++i;
117 /* copy the rest into opt */
118 if( i < slen ) {
119 (void) strncpy( opt, s + i, optlen );
120 opt[ optlen - 1 ] = '\0';
123 return 0;
128 /* parse options of upd-relay command into IP address
129 * and port
131 * @param opt options string
132 * @param addr destination for address string
133 * @param addrlen length of address string buffer
134 * @param port port to populate
136 * @return 0 if success: inaddr and port get populated
137 * non-zero if error
140 parse_udprelay( const char* opt, size_t optlen,
141 char* addr, size_t addrlen,
142 uint16_t* port )
144 int rc = 1;
145 size_t n;
146 int pval;
148 const char* SEP = ":%~+-^";
149 const int MAX_PORT = 65535;
151 #define MAX_OPTLEN 512
152 char s[ MAX_OPTLEN ];
154 assert( opt && addr && addrlen && port );
156 (void) strncpy( s, opt, MAX_OPTLEN );
157 s[ MAX_OPTLEN - 1 ] = '\0';
158 do {
159 n = strcspn( s, SEP );
160 if( !n || n >= optlen ) break;
161 s[n] = '\0';
163 strncpy( addr, s, addrlen );
164 addr[ addrlen - 1 ] ='\0';
166 ++n;
167 pval = atoi( s + n );
168 if( (pval > 0) && (pval < MAX_PORT) ) {
169 *port = (uint16_t)pval;
171 else {
172 rc = 3;
173 break;
176 rc = 0;
178 while(0);
180 return rc;
183 /* __EOF__ */