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/>.
22 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
35 /* parse and copy parameters of HTTP GET request into
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,
48 get_request( const char* src
, size_t srclen
,
49 char* request
, size_t* rqlen
)
51 const char HEAD
[] = "GET /";
53 const char* EOD
= src
+ srclen
- 1;
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 */
64 n
= strcspn( p
, " " );
65 if( (SPACE
[0] != p
[n
]) || ((p
+ n
) > EOD
) || (n
>= *rqlen
) ) /* overflow */
68 (void) strncpy( request
, p
, n
);
77 /* parse (GET) request into command and parameters (options)
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
90 parse_param( const char* s
, size_t slen
,
91 char* cmd
, size_t clen
,
92 char* opt
, size_t optlen
)
97 assert( s
&& cmd
&& (clen
> (size_t)0) && opt
&& (optlen
> (size_t)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
); ) {
111 if( j
>= clen
) return 1;
114 /* skip dividing delimiter */
115 if( DLM
== s
[i
] ) ++i
;
117 /* copy the rest into opt */
119 (void) strncpy( opt
, s
+ i
, optlen
);
120 opt
[ optlen
- 1 ] = '\0';
128 /* parse options of upd-relay command into IP address
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
140 parse_udprelay( const char* opt
, size_t optlen
,
141 char* addr
, size_t addrlen
,
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';
159 n
= strcspn( s
, SEP
);
160 if( !n
|| n
>= optlen
) break;
163 strncpy( addr
, s
, addrlen
);
164 addr
[ addrlen
- 1 ] ='\0';
167 pval
= atoi( s
+ n
);
168 if( (pval
> 0) && (pval
< MAX_PORT
) ) {
169 *port
= (uint16_t)pval
;