1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2006, 2008, 2009,
3 * 2010, 2011, 2012, 2013, 2014, 2019
4 * Inferno Nettverk A/S, Norway. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. The above copyright notice, this list of conditions and the following
10 * disclaimer must appear in all copies of the software, derivative works
11 * or modified versions, and any portions thereof, aswell as in all
12 * supporting documentation.
13 * 2. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by
16 * Inferno Nettverk A/S, Norway.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Inferno Nettverk A/S requests users of this software to return to
32 *
33 * Software Distribution Coordinator or sdc@inet.no
34 * Inferno Nettverk A/S
35 * Oslo Research Park
36 * Gaustadall�en 21
37 * NO-0349 Oslo
38 * Norway
39 *
40 * any improvements or extensions that they make and grant Inferno Nettverk A/S
41 * the rights to redistribute these changes.
42 *
43 */
44
45 #include "common.h"
46 #include "config_parse.h"
47
48 static const char rcsid[] =
49 "$Id: tostring.c,v 1.225.4.9.6.2 2020/11/11 16:11:54 karls Exp $";
50
51 static const char *stripstring = ", \t\n";
52
53 char *
aihints2string(hints,buf,buflen)54 aihints2string(hints, buf, buflen)
55 const struct addrinfo *hints;
56 char *buf;
57 size_t buflen;
58 {
59 if (buf == NULL || buflen == 0) {
60 static char _buf[64];
61
62 buf = _buf;
63 buflen = sizeof(_buf);
64 }
65
66 *buf = NUL;
67
68 snprintf(buf, buflen,
69 "ai_flags: %d, ai_family: %d, ai_socktype: %d, ai_protocol: %d",
70 hints->ai_flags,
71 hints->ai_family,
72 hints->ai_socktype,
73 hints->ai_protocol);
74
75 return buf;
76 }
77
78 char *
fdset2string(nfds,set,docheck,buf,buflen)79 fdset2string(nfds, set, docheck, buf, buflen)
80 const int nfds;
81 const fd_set *set;
82 const int docheck;
83 char *buf;
84 size_t buflen;
85 {
86 size_t bufused;
87 int i, rc;
88
89 if (buf == NULL || buflen == 0) {
90 static char _buf[10240];
91
92 buf = _buf;
93 buflen = sizeof(_buf);
94 }
95
96 bufused = 0;
97 *buf = NUL;
98
99 if (set == NULL)
100 return buf;
101
102 for (i = 0; i < nfds; ++i) {
103 if (FD_ISSET(i, set)) {
104 rc = snprintf(&buf[bufused], buflen - bufused,
105 "%d%s, ",
106 i, docheck ? (fdisopen(i) ? "" : "-invalid") : "");
107 bufused += rc;
108 }
109 }
110
111 return buf;
112 }
113
114 int32_t
string2portnumber(string,emsg,emsglen)115 string2portnumber(string, emsg, emsglen)
116 const char *string;
117 char *emsg;
118 size_t emsglen;
119 {
120 char *endptr, visbuf[256];
121 long portnumber;
122
123 if (emsg == NULL || emsglen == 0) {
124 static char _emsg[256];
125
126 emsg = _emsg;
127 emsglen = sizeof(_emsg);
128 }
129
130 portnumber = strtol(string, &endptr, 10);
131
132 if (*endptr == NUL || *endptr == '/' || isspace(*endptr)) {
133 if (portnumber >= 0 && portnumber <= IP_MAXPORT)
134 return (int32_t)portnumber;
135 else {
136 snprintf(emsg, emsglen,
137 "portnumber given (%ld) is out of range. Must be in the "
138 "range 0 - %u",
139 portnumber, IP_MAXPORT);
140
141 return -1;
142 }
143 }
144
145 snprintf(emsg, emsglen,
146 "\"%s\" does not appear to be a valid portnumber in the range "
147 "0 - %u",
148 str2vis(string, strlen(string), visbuf, sizeof(visbuf)),
149 IP_MAXPORT);
150
151 return -1;
152 }
153
154 char *
proxyprotocols2string(proxyprotocols,str,strsize)155 proxyprotocols2string(proxyprotocols, str, strsize)
156 const proxyprotocol_t *proxyprotocols;
157 char *str;
158 size_t strsize;
159 {
160 size_t strused;
161
162 if (strsize == 0) {
163 static char buf[256];
164
165 str = buf;
166 strsize = sizeof(buf);
167 }
168
169 *str = NUL;
170 strused = 0;
171
172 if (proxyprotocols->socks_v4)
173 strused += snprintf(&str[strused], strsize - strused, "%s, ",
174 QUOTE(PROXY_SOCKS_V4s));
175
176 if (proxyprotocols->socks_v5)
177 strused += snprintf(&str[strused], strsize - strused, "%s, ",
178 QUOTE(PROXY_SOCKS_V5s));
179
180 if (proxyprotocols->http)
181 strused += snprintf(&str[strused], strsize - strused, "%s, ",
182 QUOTE("HTTP"));
183
184 if (proxyprotocols->upnp)
185 strused += snprintf(&str[strused], strsize - strused, "%s, ",
186 QUOTE(PROXY_UPNPs));
187
188 if (proxyprotocols->direct)
189 strused += snprintf(&str[strused], strsize - strused, "%s, ",
190 QUOTE(PROXY_DIRECTs));
191
192 STRIPTRAILING(str, strused, stripstring);
193 return str;
194 }
195
196 char *
protocols2string(protocols,str,strsize)197 protocols2string(protocols, str, strsize)
198 const protocol_t *protocols;
199 char *str;
200 size_t strsize;
201 {
202 size_t strused;
203
204 if (strsize == 0) {
205 static char buf[16];
206
207 str = buf;
208 strsize = sizeof(buf);
209 }
210
211 *str = NUL;
212 strused = 0;
213
214 if (protocols->tcp)
215 strused += snprintf(&str[strused], strsize - strused, "%s, ",
216 QUOTE(PROTOCOL_TCPs));
217
218 if (protocols->udp)
219 strused += snprintf(&str[strused], strsize - strused, "%s, ",
220 QUOTE(PROTOCOL_UDPs));
221
222 STRIPTRAILING(str, strused, stripstring);
223 return str;
224 }
225
226 const char *
socks_packet2string(packet,isrequest)227 socks_packet2string(packet, isrequest)
228 const void *packet;
229 int isrequest;
230 {
231 static char buf[1024];
232 char hstr[MAXSOCKSHOSTSTRING];
233 unsigned char version;
234 const request_t *request = NULL;
235 const response_t *response = NULL;
236
237 if (isrequest) {
238 request = (const request_t *)packet;
239 version = request->version;
240 }
241 else {
242 response = (const response_t *)packet;
243 version = response->version;
244 }
245
246 switch (version) {
247 case PROXY_SOCKS_V4:
248 case PROXY_SOCKS_V4REPLY_VERSION:
249 if (isrequest)
250 snprintf(buf, sizeof(buf),
251 "VER: %d CMD: %d address: %s",
252 request->version,
253 request->command,
254 sockshost2string(&request->host, hstr, sizeof(hstr)));
255 else
256 snprintf(buf, sizeof(buf),
257 "VER: %d REP: %d address: %s",
258 response->version,
259 response->reply.socks,
260 sockshost2string(&response->host, hstr, sizeof(hstr)));
261
262 break;
263
264 case PROXY_SOCKS_V5:
265 if (isrequest)
266 snprintf(buf, sizeof(buf),
267 "VER: %d CMD: %d FLAG: %d ATYP: %d address: %s",
268 request->version,
269 request->command,
270 request->flag,
271 request->host.atype,
272 sockshost2string(&request->host, hstr, sizeof(hstr)));
273 else
274 snprintf(buf, sizeof(buf),
275 "VER: %d REP: %d FLAG: %d ATYP: %d address: %s",
276 response->version,
277 response->reply.socks,
278 response->flag,
279 response->host.atype,
280 sockshost2string(&response->host, hstr, sizeof(hstr)));
281
282 break;
283
284 case PROXY_HTTP_10:
285 case PROXY_HTTP_11:
286 if (isrequest)
287 snprintf(buf, sizeof(buf),
288 "VER: %d CMD: %d ATYP: %d address: %s",
289 request->version,
290 request->command,
291 request->host.atype,
292 sockshost2string(&request->host, hstr, sizeof(hstr)));
293 else
294 snprintf(buf, sizeof(buf),
295 "VER: %d REP: %d ATYP: %d address: %s",
296 response->version,
297 response->reply.http,
298 response->host.atype,
299 sockshost2string(&response->host, hstr, sizeof(hstr)));
300
301 break;
302
303 default:
304 SERRX(version);
305 }
306
307 return buf;
308 }
309
310 enum operator_t
string2operator(string)311 string2operator(string)
312 const char *string;
313 {
314
315 if (strcmp(string, "eq") == 0 || strcmp(string, "=") == 0)
316 return eq;
317
318 if (strcmp(string, "ne") == 0 || strcmp(string, "!=") == 0)
319 return neq;
320
321 if (strcmp(string, "ge") == 0 || strcmp(string, ">=") == 0)
322 return ge;
323
324 if (strcmp(string, "le") == 0 || strcmp(string, "<=") == 0)
325 return le;
326
327 if (strcmp(string, "gt") == 0 || strcmp(string, ">") == 0)
328 return gt;
329
330 if (strcmp(string, "lt") == 0 || strcmp(string, "<") == 0)
331 return lt;
332
333 /* parser should make sure this never happens. */
334 SERRX(0);
335
336 /* NOTREACHED */
337 }
338
339 const char *
operator2string(operator)340 operator2string(operator)
341 enum operator_t operator;
342 {
343
344 switch (operator) {
345 case none:
346 return QUOTE("none");
347
348 case eq:
349 return QUOTE("eq");
350
351 case neq:
352 return QUOTE("neq");
353
354 case ge:
355 return QUOTE("ge");
356
357 case le:
358 return QUOTE("le");
359
360 case gt:
361 return QUOTE("gt");
362
363 case lt:
364 return QUOTE("lt");
365
366 case range:
367 return QUOTE("range");
368
369 default:
370 SERRX(operator);
371 }
372
373 /* NOTREACHED */
374 }
375
376 const char *
ruleaddr2string(address,includeinfo,string,len)377 ruleaddr2string(address, includeinfo, string, len)
378 const ruleaddr_t *address;
379 const size_t includeinfo;
380 char *string;
381 size_t len;
382 {
383 const char *function = "ruleaddr2string()";
384 ssize_t lenused;
385
386 if (string == NULL || len == 0) {
387 static char addrstring[MAXRULEADDRSTRING];
388
389 string = addrstring;
390 len = sizeof(addrstring);
391 }
392
393 lenused = 0;
394
395 if (includeinfo & ADDRINFO_ATYPE)
396 lenused += snprintf(string, len, "%s ", atype2string(address->atype));
397
398 switch (address->atype) {
399 case SOCKS_ADDR_IPV4: {
400 char ntop[MAXSOCKADDRSTRING];
401
402 if (inet_ntop(AF_INET, &address->addr.ipv4.ip, ntop, sizeof(ntop))
403 == NULL)
404 serr("%s: inet_ntop(3) failed on %s %x",
405 function,
406 atype2string(address->atype),
407 address->addr.ipv4.ip.s_addr);
408
409 lenused += snprintf(&string[lenused], len - lenused, "%s/%d",
410 ntop,
411 bitcount((unsigned long)
412 address->addr.ipv4.mask.s_addr));
413 break;
414 }
415
416 case SOCKS_ADDR_IPV6: {
417 char ntop[MAXSOCKADDRSTRING];
418
419 if (inet_ntop(AF_INET6, &address->addr.ipv6.ip, ntop, sizeof(ntop))
420 == NULL)
421 serr("%s: inet_ntop(3) failed on %s " IP6_FMTSTR,
422 function,
423 atype2string(address->atype),
424 IP6_ELEMENTS(&address->addr.ipv6.ip));
425
426 lenused += snprintf(&string[lenused], len - lenused, "%s/%u",
427 ntop, address->addr.ipv6.maskbits);
428 break;
429 }
430
431 case SOCKS_ADDR_IPVANY:
432 SASSERTX(address->addr.ipvany.ip.s_addr == htonl(0));
433 SASSERTX(address->addr.ipvany.mask.s_addr == htonl(0));
434
435 lenused += snprintf(&string[lenused], len - lenused, "%d/%d",
436 ntohl(address->addr.ipvany.ip.s_addr),
437 bitcount((unsigned long)
438 address->addr.ipvany.mask.s_addr));
439 break;
440
441 case SOCKS_ADDR_DOMAIN:
442 lenused += snprintf(&string[lenused], len - lenused,
443 "%s", address->addr.domain);
444 break;
445
446 case SOCKS_ADDR_IFNAME:
447 lenused += snprintf(&string[lenused], len - lenused,
448 "%s", address->addr.ifname);
449 break;
450
451 default:
452 SERRX(address->atype);
453 }
454
455 if (includeinfo & ADDRINFO_PORT) {
456 switch (address->operator) {
457 case none:
458 break;
459
460 case eq:
461 case neq:
462 case ge:
463 case le:
464 case gt:
465 case lt:
466 if (address->port.tcp == address->port.udp)
467 lenused += snprintf(&string[lenused], len - lenused,
468 " port %s %u",
469 operator2string(address->operator),
470 ntohs(address->port.tcp));
471 else
472 lenused += snprintf(&string[lenused], len - lenused,
473 " port %s %u (tcp) / %u (udp)",
474 operator2string(address->operator),
475 ntohs(address->port.tcp),
476 ntohs(address->port.udp));
477 break;
478
479 case range:
480 SASSERTX(address->port.tcp == address->port.udp);
481 lenused += snprintf(&string[lenused], len - lenused,
482 " port %s %u - %u",
483 operator2string(address->operator),
484 ntohs(address->port.tcp),
485 ntohs(address->portend));
486 break;
487
488 default:
489 SERRX(address->operator);
490 }
491 }
492
493 return string;
494 }
495
496 const char *
protocol2string(protocol)497 protocol2string(protocol)
498 int protocol;
499 {
500
501 switch (protocol) {
502 case SOCKS_TCP:
503 return QUOTE(PROTOCOL_TCPs);
504
505 case SOCKS_UDP:
506 return QUOTE(PROTOCOL_UDPs);
507
508 default:
509 SERRX(protocol);
510 }
511
512 /* NOTREACHED */
513 }
514
515 const char *
resolveprotocol2string(resolveprotocol)516 resolveprotocol2string(resolveprotocol)
517 int resolveprotocol;
518 {
519 switch (resolveprotocol) {
520 case RESOLVEPROTOCOL_TCP:
521 return QUOTE(PROTOCOL_TCPs);
522
523 case RESOLVEPROTOCOL_UDP:
524 return QUOTE(PROTOCOL_UDPs);
525
526 case RESOLVEPROTOCOL_FAKE:
527 return QUOTE("fake");
528
529 default:
530 SERRX(resolveprotocol);
531 }
532
533 /* NOTREACHED */
534 }
535
536 const char *
command2string(command)537 command2string(command)
538 int command;
539 {
540
541 switch (command) {
542 case SOCKS_BIND:
543 return QUOTE(SOCKS_BINDs);
544
545 case SOCKS_CONNECT:
546 return QUOTE(SOCKS_CONNECTs);
547
548 case SOCKS_UDPASSOCIATE:
549 return QUOTE(SOCKS_UDPASSOCIATEs);
550
551 /* pseudo commands. */
552 case SOCKS_ACCEPT:
553 return QUOTE(SOCKS_ACCEPTs);
554
555 case SOCKS_BINDREPLY:
556 return QUOTE(SOCKS_BINDREPLYs);
557
558 case SOCKS_UDPREPLY:
559 return QUOTE(SOCKS_UDPREPLYs);
560
561 case SOCKS_DISCONNECT:
562 return QUOTE(SOCKS_DISCONNECTs);
563
564 case SOCKS_BOUNCETO:
565 return QUOTE(SOCKS_BOUNCETOs);
566
567 case SOCKS_HOSTID:
568 return QUOTE(SOCKS_HOSTIDs);
569
570 case SOCKS_UNKNOWN:
571 return QUOTE(SOCKS_UNKNOWNs);
572
573 default:
574 SERRX(command);
575 }
576
577 /* NOTREACHED */
578 }
579
580 char *
commands2string(command,str,strsize)581 commands2string(command, str, strsize)
582 const command_t *command;
583 char *str;
584 size_t strsize;
585 {
586 size_t strused;
587
588 if (strsize == 0) {
589 static char buf[128];
590
591 str = buf;
592 strsize = sizeof(buf);
593 }
594
595 *str = NUL;
596 strused = 0;
597
598 if (command->bind)
599 strused += snprintf(&str[strused], strsize - strused, "%s, ",
600 command2string(SOCKS_BIND));
601
602 if (command->bindreply)
603 strused += snprintf(&str[strused], strsize - strused, "%s, ",
604 command2string(SOCKS_BINDREPLY));
605
606 if (command->connect)
607 strused += snprintf(&str[strused], strsize - strused, "%s, ",
608 command2string(SOCKS_CONNECT));
609
610 if (command->udpassociate)
611 strused += snprintf(&str[strused], strsize - strused, "%s, ",
612 command2string(SOCKS_UDPASSOCIATE));
613
614 if (command->udpreply)
615 strused += snprintf(&str[strused], strsize - strused, "%s, ",
616 command2string(SOCKS_UDPREPLY));
617
618 STRIPTRAILING(str, strused, stripstring);
619 return str;
620 }
621
622 const char *
method2string(method)623 method2string(method)
624 int method;
625 {
626
627 switch (method) {
628 case AUTHMETHOD_NOTSET:
629 return QUOTE(AUTHMETHOD_NOTSETs);
630
631 case AUTHMETHOD_NONE:
632 return QUOTE(AUTHMETHOD_NONEs);
633
634 case AUTHMETHOD_GSSAPI:
635 return QUOTE(AUTHMETHOD_GSSAPIs);
636
637 case AUTHMETHOD_UNAME:
638 return QUOTE(AUTHMETHOD_UNAMEs);
639
640 case AUTHMETHOD_NOACCEPT:
641 return QUOTE(AUTHMETHOD_NOACCEPTs);
642
643 case AUTHMETHOD_RFC931:
644 return QUOTE(AUTHMETHOD_RFC931s);
645
646 case AUTHMETHOD_PAM_ANY:
647 return QUOTE(AUTHMETHOD_PAM_ANYs);
648
649 case AUTHMETHOD_PAM_ADDRESS:
650 return QUOTE(AUTHMETHOD_PAM_ADDRESSs);
651
652 case AUTHMETHOD_PAM_USERNAME:
653 return QUOTE(AUTHMETHOD_PAM_USERNAMEs);
654
655 case AUTHMETHOD_BSDAUTH:
656 return QUOTE(AUTHMETHOD_BSDAUTHs);
657
658 case AUTHMETHOD_LDAPAUTH:
659 return QUOTE(AUTHMETHOD_LDAPAUTHs);
660
661 default:
662 return "<unknown>";
663 }
664
665 /* NOTREACHED */
666 }
667
668 const char *
proxyprotocol2string(version)669 proxyprotocol2string(version)
670 int version;
671 {
672
673 switch (version) {
674 case PROXY_SOCKS_V4:
675 return QUOTE(PROXY_SOCKS_V4s);
676
677 case PROXY_SOCKS_V5:
678 return QUOTE(PROXY_SOCKS_V5s);
679
680 case PROXY_HTTP_10:
681 return QUOTE(PROXY_HTTP_10s);
682
683 case PROXY_HTTP_11:
684 return QUOTE(PROXY_HTTP_11s);
685
686 case PROXY_UPNP:
687 return QUOTE(PROXY_UPNPs);
688
689 case PROXY_DIRECT:
690 return QUOTE(PROXY_DIRECTs);
691
692 default:
693 SERRX(version);
694 }
695
696 /* NOTREACHED */
697 }
698
699 char *
methods2string(methodc,methodv,str,strsize)700 methods2string(methodc, methodv, str, strsize)
701 size_t methodc;
702 const int methodv[];
703 char *str;
704 size_t strsize;
705 {
706 size_t strused;
707 size_t i;
708
709 if (strsize == 0) {
710 static char buf[512];
711
712 str = buf;
713 strsize = sizeof(buf);
714 }
715
716 *str = NUL;
717 strused = 0;
718
719 for (i = 0; i < methodc; ++i)
720 strused += snprintf(&str[strused], strsize - strused,
721 "%s, ", method2string(methodv[i]));
722
723 STRIPTRAILING(str, strused, stripstring);
724 return str;
725 }
726
727 int
string2method(methodname)728 string2method(methodname)
729 const char *methodname;
730 {
731 struct {
732 char *methodname;
733 int method;
734 } method[] = {
735 { AUTHMETHOD_NONEs, AUTHMETHOD_NONE },
736 { AUTHMETHOD_UNAMEs, AUTHMETHOD_UNAME },
737 { AUTHMETHOD_GSSAPIs, AUTHMETHOD_GSSAPI },
738 { AUTHMETHOD_RFC931s, AUTHMETHOD_RFC931 },
739 { AUTHMETHOD_PAM_ANYs, AUTHMETHOD_PAM_ANY },
740 { AUTHMETHOD_PAM_ADDRESSs, AUTHMETHOD_PAM_ADDRESS },
741 { AUTHMETHOD_PAM_USERNAMEs, AUTHMETHOD_PAM_USERNAME },
742 { AUTHMETHOD_BSDAUTHs, AUTHMETHOD_BSDAUTH },
743 { AUTHMETHOD_LDAPAUTHs, AUTHMETHOD_LDAPAUTH }
744 };
745 size_t i;
746
747 for (i = 0; i < ELEMENTS(method); ++i)
748 if (strcmp(method[i].methodname, methodname) == 0)
749 return method[i].method;
750
751 return -1;
752 }
753
754 char *
sockshost2string2(host,includeinfo,string,len)755 sockshost2string2(host, includeinfo, string, len)
756 const sockshost_t *host;
757 const size_t includeinfo;
758 char *string;
759 size_t len;
760 {
761 size_t lenused;
762 char visbuf[sizeof(*host) * 4];
763
764 if (string == NULL || len == 0) {
765 static char hstr[sizeof(visbuf)];
766
767 string = hstr;
768 len = sizeof(hstr);
769 }
770
771 lenused = 0;
772
773 if (includeinfo & ADDRINFO_ATYPE)
774 lenused += snprintf(&string[lenused], len - lenused, "%s ",
775 atype2string(host->atype));
776
777 switch (host->atype) {
778 case SOCKS_ADDR_IPV4: {
779 char b[MAX(INET_ADDRSTRLEN, 32)];
780
781 if (inet_ntop(AF_INET, &host->addr.ipv4, b, sizeof(b)) == NULL)
782 STRCPY_ASSERTSIZE(b, "<nonsense address>");
783
784 lenused += snprintf(&string[lenused], len - lenused, "%s", b);
785 break;
786 }
787
788 case SOCKS_ADDR_IPV6: {
789 char b[MAX(INET6_ADDRSTRLEN, 32)];
790
791 if (inet_ntop(AF_INET6, &host->addr.ipv6, b, sizeof(b)) == NULL)
792 STRCPY_ASSERTSIZE(b, "<nonsense address>");
793
794 lenused += snprintf(&string[lenused], len - lenused, "%s", b);
795 break;
796 }
797
798 case SOCKS_ADDR_DOMAIN:
799 lenused += snprintf(&string[lenused], len - lenused, "%s",
800 str2vis(host->addr.domain,
801 strlen(host->addr.domain),
802 visbuf,
803 sizeof(visbuf)));
804 break;
805
806 case SOCKS_ADDR_IFNAME:
807 lenused += snprintf(&string[lenused], len - lenused, "%s",
808 str2vis(host->addr.ifname,
809 strlen(host->addr.ifname),
810 visbuf,
811 sizeof(visbuf)));
812 break;
813
814 case SOCKS_ADDR_URL:
815 lenused += snprintf(&string[lenused], len - lenused, "%s",
816 str2vis(host->addr.urlname,
817 strlen(host->addr.urlname),
818 visbuf,
819 sizeof(visbuf)));
820 break;
821
822 default:
823 SERRX(host->atype);
824 }
825
826 if (includeinfo & ADDRINFO_PORT) {
827 switch (host->atype) {
828 case SOCKS_ADDR_IPV4:
829 case SOCKS_ADDR_IPV6:
830 case SOCKS_ADDR_DOMAIN:
831 lenused += snprintf(&string[lenused], len - lenused,
832 ".%d", ntohs(host->port));
833 break;
834 }
835 }
836
837 return string;
838 }
839
840 char *
sockshost2string(host,string,len)841 sockshost2string(host, string, len)
842 const sockshost_t *host;
843 char *string;
844 size_t len;
845 {
846
847 return sockshost2string2(host, ADDRINFO_PORT, string, len);
848 }
849
850 char *
sockaddr2string(addr,string,len)851 sockaddr2string(addr, string, len)
852 const struct sockaddr_storage *addr;
853 char *string;
854 size_t len;
855 {
856 if (string == NULL || len == 0) {
857 static char addrstring[MAXSOCKADDRSTRING];
858
859 string = addrstring;
860 len = sizeof(addrstring);
861 }
862
863
864 return sockaddr2string2(addr, ADDRINFO_PORT, string, len);
865 }
866
867
868 char *
sockaddr2string2(addr,includeinfo,string,len)869 sockaddr2string2(addr, includeinfo, string, len)
870 const struct sockaddr_storage *addr;
871 const size_t includeinfo;
872 char *string;
873 size_t len;
874 {
875 size_t lenused = 0;
876
877 if (string == NULL || len == 0) {
878 static char addrstring[MAX(MAXSOCKADDRSTRING, 256)];
879
880 string = addrstring;
881 len = sizeof(addrstring);
882 }
883
884 if (includeinfo & ADDRINFO_ATYPE)
885 lenused += snprintf(&string[lenused], len - lenused, "%s ",
886 safamily2string(addr->ss_family));
887
888 switch (addr->ss_family) {
889 case AF_INET:
890 case AF_INET6: {
891 if (inet_ntop(addr->ss_family,
892 GET_SOCKADDRADDR(addr),
893 &string[lenused],
894 len - lenused) != NULL) {
895 if (addr->ss_family == AF_INET6
896 && includeinfo & ADDRINFO_SCOPEID
897 && TOCIN6(addr)->sin6_scope_id != 0) {
898 lenused = strlen(string);
899
900 snprintf(&string[lenused], len - lenused,
901 "%u", (unsigned int)TOCIN6(addr)->sin6_scope_id);
902 }
903
904 if (includeinfo & ADDRINFO_PORT) {
905 lenused = strlen(string);
906
907 snprintf(&string[lenused], len - lenused,
908 ".%d", ntohs(GET_SOCKADDRPORT(addr)));
909 }
910 }
911 else {
912 char addrstr[MAXSOCKADDRSTRING];
913
914 switch (addr->ss_family) {
915 case AF_INET:
916 snprintf(addrstr, sizeof(addrstr),
917 "0x%x", TOCIN(addr)->sin_addr.s_addr);
918 break;
919
920 case AF_INET6:
921 snprintf(addrstr, sizeof(addrstr),
922 IP6_FMTSTR, IP6_ELEMENTS(&TOCIN6(addr)->sin6_addr));
923 break;
924
925 default:
926 SERRX(addr->ss_family);
927 }
928
929 snprintf(string, len,
930 "<inet_ntop(3) on af %d, addr %s, failed: %s>",
931 addr->ss_family,
932 strerror(errno),
933 addrstr);
934
935 errno = 0;
936 }
937
938 break;
939 }
940
941 default:
942 snprintf(string, len, "<undecoded af %d>", addr->ss_family);
943 }
944
945 return string;
946 }
947
948 char *
addr2hexstring(addr,safamily,string,len)949 addr2hexstring(addr, safamily, string, len)
950 const void *addr;
951 const sa_family_t safamily;
952 char *string;
953 size_t len;
954 {
955 if (string == NULL || len == 0) {
956 static char stringmem[sizeof(IP6_FMTSTR)];
957
958 string = stringmem;
959 len = sizeof(stringmem);
960 }
961
962 switch (safamily) {
963 case AF_INET:
964 snprintf(string, len, "0x%x", ((const struct in_addr *)addr)->s_addr);
965 break;
966
967 case AF_INET6:
968 snprintf(string, len,
969 IP6_FMTSTR,
970 IP6_ELEMENTS(((const struct in6_addr *)addr)));
971 break;
972
973 default:
974 SERRX(safamily);
975 }
976
977 return string;
978 }
979
980 udpheader_t *
string2udpheader(data,len,header)981 string2udpheader(data, len, header)
982 const char *data;
983 size_t len;
984 udpheader_t *header;
985 {
986
987 bzero(header, sizeof(*header));
988
989 if (len < MINSOCKSUDPHLEN)
990 return NULL;
991
992 if (len < sizeof(header->flag))
993 return NULL;
994
995 memcpy(&header->flag, data, sizeof(header->flag));
996 data += sizeof(header->flag);
997 len -= sizeof(header->flag);
998
999 if (len < sizeof(header->frag))
1000 return NULL;
1001
1002 memcpy(&header->frag, data, sizeof(header->frag));
1003 data += sizeof(header->frag);
1004 len -= sizeof(header->frag);
1005
1006 if (mem2sockshost(&header->host,
1007 (const unsigned char *)data,
1008 len,
1009 PROXY_SOCKS_V5) == NULL) {
1010 bzero(header, sizeof(*header));
1011 return NULL;
1012 }
1013
1014 return header;
1015 }
1016
1017 char *
extensions2string(extensions,str,strsize)1018 extensions2string(extensions, str, strsize)
1019 const extension_t *extensions;
1020 char *str;
1021 size_t strsize;
1022 {
1023 size_t strused;
1024
1025 if (strsize == 0) {
1026 static char buf[16];
1027
1028 str = buf;
1029 strsize = sizeof(buf);
1030 }
1031
1032 *str = NUL;
1033 strused = 0;
1034
1035 if (extensions->bind)
1036 strused += snprintf(&str[strused], strsize - strused, "%s, ",
1037 QUOTE("bind"));
1038
1039 STRIPTRAILING(str, strused, stripstring);
1040 return str;
1041 }
1042
1043 char *
str2upper(string)1044 str2upper(string)
1045 char *string;
1046 {
1047
1048 while (*string != NUL) {
1049 *string = (char)toupper(*string);
1050 ++string;
1051 }
1052
1053 return string;
1054 }
1055
1056 char *
sockname2string(s,buf,buflen)1057 sockname2string(s, buf, buflen)
1058 const int s;
1059 char *buf;
1060 size_t buflen;
1061 {
1062 const char *function = "sockname2string()";
1063 struct sockaddr_storage addr;
1064 socklen_t len;
1065
1066 if (s == -1)
1067 return NULL;
1068
1069 if (buflen == 0) {
1070 static char sbuf[256];
1071
1072 buf = sbuf;
1073 buflen = sizeof(sbuf);
1074 }
1075
1076 len = sizeof(addr);
1077 if (getsockname(s, TOSA(&addr), &len) == -1) {
1078 slog(LOG_DEBUG, "%s: getsockname(2) on fd %d failed: %s",
1079 function, s, strerror(errno));
1080
1081 return NULL;
1082 }
1083
1084 sockaddr2string(&addr, buf, buflen);
1085
1086 return buf;
1087 }
1088
1089 char *
peername2string(s,buf,buflen)1090 peername2string(s, buf, buflen)
1091 const int s;
1092 char *buf;
1093 size_t buflen;
1094 {
1095 const char *function = "peername2string()";
1096 struct sockaddr_storage addr;
1097 socklen_t len;
1098
1099 if (s == -1)
1100 return NULL;
1101
1102 if (buflen == 0) {
1103 static char sbuf[256];
1104
1105 buf = sbuf;
1106 buflen = sizeof(sbuf);
1107 }
1108
1109 len = sizeof(addr);
1110 if (getpeername(s, TOSA(&addr), &len) == -1) {
1111 slog(LOG_DEBUG, "%s: getpeername(2) on fd %d failed: %s",
1112 function, s, strerror(errno));
1113
1114 return NULL;
1115 }
1116
1117 sockaddr2string(&addr, buf, buflen);
1118
1119 return buf;
1120 }
1121
1122 char *
socket2string(s,buf,buflen)1123 socket2string(s, buf, buflen)
1124 const int s;
1125 char *buf;
1126 size_t buflen;
1127 {
1128 const char *function = "socket2string()";
1129 const int errno_s = errno;
1130 socklen_t len;
1131 char src[MAXSOCKADDRSTRING], dst[MAXSOCKADDRSTRING], *protocol;
1132 int val;
1133
1134 if (buflen == 0) {
1135 static char sbuf[256];
1136
1137 buf = sbuf;
1138 buflen = sizeof(sbuf);
1139 }
1140
1141 if (sockname2string(s, src, sizeof(src)) == NULL)
1142 *src = NUL;
1143
1144 if (peername2string(s, dst, sizeof(dst)) == NULL)
1145 *dst = NUL;
1146
1147 len = sizeof(val);
1148 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &val, &len) == -1)
1149 protocol = NULL;
1150 else
1151 switch (val) {
1152 case SOCK_DGRAM:
1153 protocol = PROTOCOL_UDPs;
1154 break;
1155
1156 case SOCK_STREAM:
1157 protocol = PROTOCOL_TCPs;
1158 break;
1159
1160 default:
1161 protocol = "unknown";
1162 }
1163
1164 snprintf(buf, buflen,
1165 "laddr: %s, raddr: %s, protocol: %s",
1166 *src == NUL ? "N/A" : src,
1167 *dst == NUL ? "N/A" : dst,
1168 protocol == NULL ? "N/A" : protocol);
1169
1170 errno = errno_s;
1171 return buf;
1172 }
1173
1174 const char *
atype2string(atype)1175 atype2string(atype)
1176 const unsigned int atype;
1177 {
1178
1179 switch (atype) {
1180 case SOCKS_ADDR_IPV4:
1181 return "IPv4 address";
1182
1183 case SOCKS_ADDR_IPV6:
1184 return "IPv6 address";
1185
1186 case SOCKS_ADDR_IPVANY:
1187 return "<IPvAny> address";
1188
1189 case SOCKS_ADDR_IFNAME:
1190 return "interfacename";
1191
1192 case SOCKS_ADDR_DOMAIN:
1193 return "host/domain-name";
1194
1195 case SOCKS_ADDR_URL:
1196 return "url";
1197
1198 default:
1199 SERRX(atype);
1200 }
1201
1202 /* NOTREACHED */
1203 }
1204
1205 const char *
safamily2string(af)1206 safamily2string(af)
1207 const sa_family_t af;
1208 {
1209
1210 switch (af) {
1211 case AF_INET:
1212 return atype2string(SOCKS_ADDR_IPV4);
1213
1214 case AF_INET6:
1215 return atype2string(SOCKS_ADDR_IPV6);
1216
1217 case AF_UNSPEC:
1218 return "AF_UNSPEC";
1219
1220 case AF_LOCAL:
1221 return "AF_LOCAL";
1222
1223 default: {
1224 static char buf[sizeof("unknown socket address family: 65535")];
1225
1226 snprintf(buf, sizeof(buf), "<unknown socket address family: %d>", af);
1227 return buf;
1228 }
1229 }
1230
1231 /* NOTREACHED */
1232 }
1233
1234 const char *
socktype2string(socktype)1235 socktype2string(socktype)
1236 const int socktype;
1237 {
1238
1239 switch (socktype) {
1240 case SOCK_STREAM:
1241 return "SOCK_STREAM";
1242
1243 case SOCK_DGRAM:
1244 return "SOCK_DGRAM";
1245
1246 default:
1247 return "<UNKNOWN>";
1248 }
1249
1250 /* NOTREACHED */
1251 }
1252
1253 char *
ltoa(l,buf,buflen)1254 ltoa(l, buf, buflen)
1255 long l;
1256 char *buf;
1257 size_t buflen;
1258 {
1259 char *p;
1260 size_t bufused;
1261 int add_minus;
1262
1263 if (buf == NULL || buflen == 0) {
1264 /* for a 64 bits integer. */
1265 static char bufmem[(sizeof("-") - 1) + sizeof("18446744073709551616")];
1266
1267 buf = bufmem;
1268 buflen = sizeof(bufmem);
1269 }
1270 else if (buflen == 1) {
1271 *buf = NUL;
1272 return buf;
1273 }
1274
1275 p = &buf[buflen - 1]; /* start at end and go backwards. */
1276 *p = NUL;
1277
1278 if (l < 0) {
1279 l = -l;
1280 add_minus = 1;
1281 }
1282 else
1283 add_minus = 0;
1284
1285 do {
1286 *(--p) = (char)((l % 10) + '0');
1287 l /= 10;
1288 } while (l != 0 && p > buf);
1289
1290 if (l != 0
1291 || (p == buf && add_minus)) { /* buf too small / number too large. */
1292 SASSERTX(p == buf);
1293
1294 errno = ERANGE;
1295 *buf = NUL;
1296
1297 return buf;
1298 }
1299
1300 if (add_minus)
1301 *(--p) = '-';
1302
1303 bufused = (&buf[buflen - 1] - p) + 1;
1304 SASSERTX(p + (bufused - 1) <= &buf[buflen - 1]);
1305
1306 memmove(buf, p, bufused);
1307 SASSERTX(buf[bufused - 1] == NUL);
1308
1309 return buf;
1310 }
1311
1312 #if HAVE_GSSAPI
1313 const char *
gssapiprotection2string(protection)1314 gssapiprotection2string(protection)
1315 const int protection;
1316 {
1317 switch (protection) {
1318 case SOCKS_GSSAPI_CLEAR:
1319 return "clear";
1320
1321 case SOCKS_GSSAPI_INTEGRITY:
1322 return "integrity";
1323
1324 case SOCKS_GSSAPI_CONFIDENTIALITY:
1325 return "confidentiality";
1326
1327 case SOCKS_GSSAPI_PERMESSAGE:
1328 return "per-message";
1329 }
1330
1331 return "unknown gssapi protection";
1332 }
1333 #endif /* HAVE_GSSAPI */
1334
1335 char *
routeoptions2string(options,str,strsize)1336 routeoptions2string(options, str, strsize)
1337 const routeoptions_t *options;
1338 char *str;
1339 size_t strsize;
1340 {
1341 size_t strused;
1342
1343 if (strsize == 0) {
1344 static char buf[512];
1345
1346 str = buf;
1347 strsize = sizeof(buf);
1348 }
1349
1350 *str = NUL;
1351 strused = 0;
1352
1353 strused += snprintf(&str[strused], strsize - strused,
1354 "\"badexpire: %lu\", ",
1355 (long)options->badexpire);
1356
1357 strused += snprintf(&str[strused], strsize - strused,
1358 "\"maxfail: %lu\"",
1359 (unsigned long)options->maxfail);
1360
1361 return str;
1362 }
1363
1364 char *
logtypes2string(logtypes,str,strsize)1365 logtypes2string(logtypes, str, strsize)
1366 const logtype_t *logtypes;
1367 char *str;
1368 size_t strsize;
1369 {
1370 size_t strused;
1371 size_t i;
1372
1373 if (strsize == 0) {
1374 static char buf[512];
1375
1376 str = buf;
1377 strsize = sizeof(buf);
1378 }
1379
1380 *str = NUL;
1381 strused = 0;
1382
1383 if (logtypes->type & LOGTYPE_SYSLOG)
1384 strused += snprintf(&str[strused], strsize - strused, "\"syslog.%s\", ",
1385 logtypes->facilityname);
1386
1387 if (logtypes->type & LOGTYPE_FILE)
1388 for (i = 0; i < logtypes->filenoc; ++i)
1389 strused += snprintf(&str[strused], strsize - strused, "\"%s\", ",
1390 logtypes->fnamev[i]);
1391
1392 STRIPTRAILING(str, strused, stripstring);
1393 return str;
1394 }
1395
1396 const char *
loglevel2string(loglevel)1397 loglevel2string(loglevel)
1398 const int loglevel;
1399 {
1400
1401 switch (loglevel) {
1402 case LOG_EMERG:
1403 return "emergency";
1404
1405 case LOG_ALERT:
1406 return "alert";
1407
1408 case LOG_CRIT:
1409 return "critical";
1410
1411 case LOG_ERR:
1412 return "error";
1413
1414 case LOG_WARNING:
1415 return "warning";
1416
1417 case LOG_NOTICE:
1418 return "notice";
1419
1420 case LOG_INFO:
1421 return "info";
1422
1423 case LOG_DEBUG:
1424 return "debug";
1425
1426 default:
1427 SWARNX(loglevel);
1428 return "unknown loglevel";
1429 }
1430 }
1431
1432 const char *
signal2string(sig)1433 signal2string(sig)
1434 const int sig;
1435 {
1436
1437 switch (sig) {
1438 #ifdef SIGABRT
1439 case SIGABRT:
1440 return "SIGABRT";
1441 #endif /* SIGABRT */
1442
1443 #ifdef SIGALRM
1444 case SIGALRM:
1445 return "SIGALRM";
1446 #endif /* SIGALRM */
1447
1448 #ifdef SIGBUS
1449 case SIGBUS:
1450 return "SIGBUS";
1451 #endif /* SIGBUS */
1452
1453 #ifdef SIGCANCEL
1454 case SIGCANCEL:
1455 return "SIGCANCEL";
1456 #endif /* SIGCANCEL */
1457
1458 #ifdef SIGCHLD
1459 case SIGCHLD:
1460 return "SIGCHLD";
1461 #endif /* SIGCHLD */
1462
1463 #if (defined SIGCLD) && SIGCLD != SIGCHLD
1464 case SIGCLD:
1465 return "SIGCLD";
1466 #endif /* SIGCLD */
1467
1468 #ifdef SIGCONT
1469 case SIGCONT:
1470 return "SIGCONT";
1471 #endif /* SIGCONT */
1472
1473 #ifdef SIGEMT
1474 case SIGEMT:
1475 return "SIGEMT";
1476 #endif /* SIGEMT */
1477
1478 #ifdef SIGFPE
1479 case SIGFPE:
1480 return "SIGFPE";
1481 #endif /* SIGFPE */
1482
1483 #ifdef SIGFREEZE
1484 case SIGFREEZE:
1485 return "SIGFREEZE";
1486 #endif /* SIGFREEZE */
1487
1488 #ifdef SIGHUP
1489 case SIGHUP:
1490 return "SIGHUP";
1491 #endif /* SIGHUP */
1492
1493 #ifdef SIGILL
1494 case SIGILL:
1495 return "SIGILL";
1496 #endif /* SIGILL */
1497
1498 #ifdef SIGINFO
1499 case SIGINFO:
1500 return "SIGINFO";
1501 #endif /* SIGINFO */
1502
1503 #ifdef SIGINT
1504 case SIGINT:
1505 return "SIGINT";
1506 #endif /* SIGINT */
1507
1508 #ifdef SIGIO
1509 case SIGIO:
1510 return "SIGIO";
1511 #endif /* SIGIO */
1512
1513 #if (defined SIGIOT) && SIGIOT != SIGABRT
1514 case SIGIOT:
1515 return "SIGIOT";
1516 #endif /* SIGIOT && SIGIOT != SIGABRT */
1517
1518 #ifdef SIGJVM1
1519 case SIGJVM1:
1520 return "SIGJVM1";
1521 #endif /* SIGJVM1 */
1522
1523 #ifdef SIGJVM2
1524 case SIGJVM2:
1525 return "SIGJVM2";
1526 #endif /* SIGJVM2 */
1527
1528 #ifdef SIGKILL
1529 case SIGKILL:
1530 return "SIGKILL";
1531 #endif /* SIGKILL */
1532
1533 #if (defined SIGLOST) && (!defined SIGABRT || SIGLOST != SIGABRT)
1534 case SIGLOST:
1535 return "SIGLOST";
1536 #endif /* SIGLOST */
1537
1538 #if (defined SIGLWP) && (!defined SIGTHR || SIGLWP != SIGTHR)
1539 case SIGLWP:
1540 return "SIGLWP";
1541 #endif /* SIGLWP */
1542
1543 #ifdef SIGPIPE
1544 case SIGPIPE:
1545 return "SIGPIPE";
1546 #endif /* SIGPIPE */
1547
1548 #if (defined SIGPOLL) && SIGPOLL != SIGIO
1549 case SIGPOLL:
1550 return "SIGPOLL";
1551 #endif /* SIGPOLL */
1552
1553 #ifdef SIGPROF
1554 case SIGPROF:
1555 return "SIGPROF";
1556 #endif /* SIGPROF */
1557
1558 #ifdef SIGPWR
1559 case SIGPWR:
1560 return "SIGPWR";
1561 #endif /* SIGPWR */
1562
1563 #ifdef SIGQUIT
1564 case SIGQUIT:
1565 return "SIGQUIT";
1566 #endif /* SIGQUIT */
1567
1568 #ifdef SIGSEGV
1569 case SIGSEGV:
1570 return "SIGSEGV";
1571 #endif /* SIGSEGV */
1572
1573 #ifdef SIGSTKFLT
1574 case SIGSTKFLT:
1575 return "SIGSTKFLT";
1576 #endif /* SIGSTKFLT */
1577
1578 #ifdef SIGSTOP
1579 case SIGSTOP:
1580 return "SIGSTOP";
1581 #endif /* SIGSTOP */
1582
1583 #ifdef SIGSYS
1584 case SIGSYS:
1585 return "SIGSYS";
1586 #endif /* SIGSYS */
1587
1588 #ifdef SIGTERM
1589 case SIGTERM:
1590 return "SIGTERM";
1591 #endif /* SIGTERM */
1592
1593 #ifdef SIGTHAW
1594 case SIGTHAW:
1595 return "SIGTHAW";
1596 #endif /* SIGTHAW */
1597
1598 #ifdef SIGTHR
1599 case SIGTHR:
1600 return "SIGTHR";
1601 #endif /* SIGTHR */
1602
1603 #ifdef SIGTRAP
1604 case SIGTRAP:
1605 return "SIGTRAP";
1606 #endif /* SIGTRAP */
1607
1608 #ifdef SIGTSTP
1609 case SIGTSTP:
1610 return "SIGTSTP";
1611 #endif /* SIGTSTP */
1612
1613 #ifdef SIGTTIN
1614 case SIGTTIN:
1615 return "SIGTTIN";
1616 #endif /* SIGTTIN */
1617
1618 #ifdef SIGTTOU
1619 case SIGTTOU:
1620 return "SIGTTOU";
1621 #endif /* SIGTTOU */
1622
1623 #ifdef SIGURG
1624 case SIGURG:
1625 return "SIGURG";
1626 #endif /* SIGURG */
1627
1628 #ifdef SIGUSR1
1629 case SIGUSR1:
1630 return "SIGUSR1";
1631 #endif /* SIGUSR1 */
1632
1633 #ifdef SIGUSR2
1634 case SIGUSR2:
1635 return "SIGUSR2";
1636 #endif /* SIGUSR2 */
1637
1638 #ifdef SIGVTALRM
1639 case SIGVTALRM:
1640 return "SIGVTALRM";
1641 #endif /* SIGVTALRM */
1642
1643 #ifdef SIGWAITING
1644 case SIGWAITING:
1645 return "SIGWAITING";
1646 #endif /* SIGWAITING */
1647
1648 #ifdef SIGWINCH
1649 case SIGWINCH:
1650 return "SIGWINCH";
1651 #endif /* SIGWINCH */
1652
1653 #ifdef SIGXCPU
1654 case SIGXCPU:
1655 return "SIGXCPU";
1656 #endif /* SIGXCPU */
1657
1658 #ifdef SIGXFSZ
1659 case SIGXFSZ:
1660 return "SIGXFSZ";
1661 #endif /* SIGXFSZ */
1662
1663 #ifdef SIGXRES
1664 case SIGXRES:
1665 return "SIGXRES";
1666 #endif /* SIGXRES */
1667 }
1668
1669 return "<unknown signal>";
1670 }
1671
1672
1673 #undef strerror
1674 const char *
socks_strerror(err)1675 socks_strerror(err)
1676 const int err;
1677 {
1678 const int errno_s = errno;
1679 char *errstr;
1680
1681 if (sockscf.state.insignal)
1682 return "<cannot retrieve errno string while in signalhandler>";
1683
1684 if (err == 0)
1685 return "no system error";
1686
1687 errstr = strerror(err);
1688
1689 if (errno != errno_s
1690 && errno != EINVAL)
1691 /*
1692 * don't expect strerror(3) to change errno normally, but on
1693 * OpenBSD it for some reason can. :-(
1694 */
1695 errno = errno_s;
1696
1697 return errstr;
1698 }
1699
1700 const char *
sockoptval2string(value,type,str,strsize)1701 sockoptval2string(value, type, str, strsize)
1702 socketoptvalue_t value;
1703 socketoptvalue_type_t type;
1704 char *str;
1705 size_t strsize;
1706 {
1707 size_t strused;
1708
1709 if (strsize == 0) {
1710 static char buf[100];
1711
1712 str = buf;
1713 strsize = sizeof(buf);
1714 }
1715
1716 *str = NUL;
1717 strused = 0;
1718
1719 switch (type) {
1720 case int_val:
1721 strused += snprintf(&str[strused], strsize - strused, "%d",
1722 value.int_val);
1723 break;
1724
1725 case uchar_val:
1726 strused += snprintf(&str[strused], strsize - strused, "%u",
1727 (unsigned)value.uchar_val);
1728 break;
1729
1730 case linger_val:
1731 case timeval_val:
1732 case in_addr_val:
1733 case sockaddr_val:
1734 case ipoption_val:
1735 #if HAVE_TCP_IPA
1736 case option28_val:
1737 #endif /* HAVE_TCP_IPA */
1738
1739 strused += snprintf(&str[strused], strsize - strused,
1740 "<value-decoding unimplemented>");
1741 break;
1742
1743 default:
1744 SERRX(type);
1745 }
1746
1747 STRIPTRAILING(str, strused, stripstring);
1748 return str;
1749 }
1750
1751 const char *
sockoptlevel2string(level)1752 sockoptlevel2string(level)
1753 int level;
1754 {
1755
1756 switch (level) {
1757 #ifdef SOL_SOCKET
1758 case SOL_SOCKET:
1759 return "socket";
1760 #endif /* SOL_SOCKET */
1761
1762 #ifdef IPPROTO_TCP
1763 case IPPROTO_TCP:
1764 return "tcp";
1765 #endif /* IPPROTO_TCP */
1766
1767 #ifdef IPPROTO_UDP
1768 case IPPROTO_UDP:
1769 return "udp";
1770 #endif /* IPPROTO_UDP */
1771
1772 #ifdef IPPROTO_IP
1773 case IPPROTO_IP:
1774 return "ip";
1775 #endif /* IPPROTO_IP */
1776
1777 default:
1778 SERRX(level);
1779 }
1780
1781 /* NOTREACHED */
1782 }
1783
1784 const char *
sockoptvaltype2string(type)1785 sockoptvaltype2string(type)
1786 socketoptvalue_type_t type;
1787 {
1788
1789 switch (type) {
1790 case int_val:
1791 return "int_val";
1792
1793 case linger_val:
1794 return "linger_val";
1795
1796 case timeval_val:
1797 return "timeval_val";
1798
1799 case in_addr_val:
1800 return "in_addr_val";
1801
1802 case uchar_val:
1803 return "uchar_val";
1804
1805 case sockaddr_val:
1806 return "sockaddr_val";
1807
1808 case ipoption_val:
1809 return "ipoption_val";
1810 #if HAVE_TCP_IPA
1811 case option28_val:
1812 return "option28_val";
1813 #endif /* HAVE_TCP_IPA */
1814
1815 default:
1816 SERRX(type);
1817 }
1818
1819 /* NOTREACHED */
1820 }
1821
1822 const char *
sockopt2string(opt,str,strsize)1823 sockopt2string(opt, str, strsize)
1824 const socketoption_t *opt;
1825 char *str;
1826 size_t strsize;
1827 {
1828 size_t strused;
1829
1830 if (strsize == 0) {
1831 static char buf[100];
1832
1833 str = buf;
1834 strsize = sizeof(buf);
1835 }
1836
1837 strused = snprintf(str, strsize,
1838 "%s (%d), level %s (%d), calltype %d, %s-side",
1839 opt->info == NULL ? "<unknown>" : opt->info->name,
1840 opt->optname,
1841 sockoptlevel2string(opt->info == NULL ?
1842 opt->level : opt->info->level),
1843 opt->info == NULL ? opt->level : opt->info->level,
1844 opt->info == NULL ? -1 : (int)opt->info->calltype,
1845 opt->info == NULL ?
1846 "<unknown>" : opt->isinternalside ?
1847 "internal" : "external");
1848
1849 #if 1
1850 strused += snprintf(&str[strused], strsize - strused,
1851 " value: %s (%s)",
1852 sockoptval2string(opt->optval, opt->opttype, NULL, 0),
1853 sockoptvaltype2string(opt->opttype));
1854 #endif
1855
1856 STRIPTRAILING(str, strused, stripstring);
1857 return str;
1858 }
1859
1860
1861 const char *
socketsettime2string(whichtime)1862 socketsettime2string(whichtime)
1863 const int whichtime;
1864 {
1865 const char *function = "socketsettime2string()";
1866
1867 switch (whichtime) {
1868 case SOCKETOPT_PRE:
1869 return "pre-establishment time";
1870
1871 case SOCKETOPT_POST:
1872 return "post-establishment time";
1873
1874 case SOCKETOPT_ANYTIME:
1875 return "any time";
1876 }
1877
1878 if (whichtime == (SOCKETOPT_PRE | SOCKETOPT_POST))
1879 return "pre/post-establishment time";
1880
1881 if (whichtime == (SOCKETOPT_PRE | SOCKETOPT_ANYTIME))
1882 return "pre-establishment or any time";
1883
1884 if (whichtime == (SOCKETOPT_POST | SOCKETOPT_ANYTIME))
1885 return "post-establishment or any time";
1886
1887 swarnx("%s: unknown value: %d", function, whichtime);
1888 return "<unknown value>";
1889 }
1890
1891 #if !SOCKS_CLIENT
1892
1893 const char *
interfaceside2string(side)1894 interfaceside2string(side)
1895 const interfaceside_t side;
1896 {
1897
1898 switch (side) {
1899 case INTERNALIF:
1900 return "internal/client";
1901
1902 case EXTERNALIF:
1903 return "external/target";
1904
1905 default:
1906 SERRX(side);
1907 /* NOTREACHED */
1908 }
1909
1910 }
1911
1912 char *
interfaceprotocol2string(ifproto,str,strsize)1913 interfaceprotocol2string(ifproto, str, strsize)
1914 const interfaceprotocol_t *ifproto;
1915 char *str;
1916 size_t strsize;
1917 {
1918
1919 if (strsize == 0) {
1920 static char buf[1024];
1921
1922 str = buf;
1923 strsize = sizeof(buf);
1924 }
1925
1926 snprintf(str, strsize, "%s: %s, %s: %s",
1927 safamily2string(AF_INET), ifproto->ipv4 ? "yes" : "no",
1928 safamily2string(AF_INET6), ifproto->ipv6 ? "yes" : "no");
1929
1930
1931 return str;
1932 }
1933
1934
1935 char *
networktest2string(test,str,strsize)1936 networktest2string(test, str, strsize)
1937 const networktest_t *test;
1938 char *str;
1939 size_t strsize;
1940 {
1941
1942 if (strsize == 0) {
1943 static char buf[1024];
1944
1945 str = buf;
1946 strsize = sizeof(buf);
1947 }
1948
1949 snprintf(str, strsize, "mtu.dotest: %d", test->mtu.dotest);
1950
1951 return str;
1952 }
1953
1954 const char *
addrscope2string(scope)1955 addrscope2string(scope)
1956 const ipv6_addrscope_t scope;
1957 {
1958 switch (scope) {
1959 case addrscope_global:
1960 return "global";
1961
1962 case addrscope_linklocal:
1963 return "linklocal";
1964
1965 case addrscope_nodelocal:
1966 return "nodelocal";
1967 }
1968
1969 SERRX(scope);
1970 /* NOTREACHED */
1971 }
1972
1973 const char *
alarmside2string(alarmside)1974 alarmside2string(alarmside)
1975 const size_t alarmside;
1976 {
1977
1978 switch (alarmside) {
1979 case ALARM_INTERNAL:
1980 return "internal";
1981
1982 case ALARM_INTERNAL_RECV:
1983 return "internal.recv";
1984
1985 case ALARM_INTERNAL_SEND:
1986 return "internal.send";
1987
1988 case ALARM_EXTERNAL:
1989 return "external";
1990
1991 case ALARM_EXTERNAL_RECV:
1992 return "external.recv";
1993
1994 case ALARM_EXTERNAL_SEND:
1995 return "external.send";
1996
1997 case ALARM_RECV:
1998 return "recv";
1999
2000 case ALARM_SEND:
2001 return "send";
2002
2003 default:
2004 SERRX(alarmside);
2005 }
2006 }
2007
2008 const char *
clientinfo2string(cinfo,str,strsize)2009 clientinfo2string(cinfo, str, strsize)
2010 const clientinfo_t *cinfo;
2011 char *str;
2012 size_t strsize;
2013 {
2014 const char *function = "clientinfo2string()";
2015 size_t strused;
2016
2017 if (strsize == 0) {
2018 static char buf[1024];
2019
2020 str = buf;
2021 strsize = sizeof(buf);
2022 }
2023
2024 strused = 0;
2025
2026 #if HAVE_SOCKS_HOSTID
2027 {
2028 size_t i;
2029
2030 for (i = 0; i < (size_t)cinfo->hostidc; ++i) {
2031 char ntop[MAXSOCKADDRSTRING];
2032
2033 if (inet_ntop(AF_INET, &cinfo->hostidv[i], ntop, sizeof(ntop)) == NULL) {
2034 slog(LOG_DEBUG, "%s: inet_ntop(3) failed on %s %x: %s",
2035 function,
2036 atype2string(SOCKS_ADDR_IPV4),
2037 cinfo->hostidv[i].s_addr,
2038 strerror(errno));
2039
2040 snprintf(ntop, sizeof(ntop), "<unknown>");
2041 errno = 0;
2042 }
2043
2044 strused += snprintf(&str[strused], strsize - strused, "[%s] ", ntop);
2045 }
2046 }
2047 #endif /* HAVE_SOCKS_HOSTID */
2048
2049 strused += snprintf(&str[strused], strsize - strused, "%s",
2050 sockaddr2string(&cinfo->from, NULL, 0));
2051
2052 return str;
2053 }
2054
2055 const char *
statekey2string(key)2056 statekey2string(key)
2057 const statekey_t key;
2058 {
2059
2060 switch (key) {
2061 case key_unset:
2062 return "unset";
2063
2064 case key_from:
2065 return "from (client IP-address)";
2066
2067 case key_hostid:
2068 return "hostid (client hostid)";
2069
2070 default:
2071 SERRX(key);
2072 }
2073
2074 /* NOTREACHED */
2075 }
2076
2077 statekey_t
string2statekey(string)2078 string2statekey(string)
2079 const char *string;
2080 {
2081
2082 if (strcmp(string, "from") == 0)
2083 return key_from;
2084 else if (strcmp(string, "hostid") == 0)
2085 return key_hostid;
2086
2087 return key_unset;
2088 }
2089
2090 const char *
objecttype2string(type)2091 objecttype2string(type)
2092 const objecttype_t type;
2093 {
2094
2095 switch (type) {
2096 case object_sockaddr:
2097 return "sockaddr";
2098
2099 case object_sockshost:
2100 return "sockshost";
2101
2102 case object_crule:
2103 return "client-rule";
2104
2105 #if HAVE_SOCKS_HOSTID
2106 case object_hrule:
2107 return "hostid-rule";
2108 #endif /* HAVE_SOCKS_HOSTID */
2109
2110 case object_srule:
2111 return "socks-rule";
2112
2113 case object_monitor:
2114 return "monitor";
2115
2116 default:
2117 SERRX(type);
2118 }
2119
2120 /* NOTREACHED */
2121 return NULL;
2122 }
2123
2124
2125 char *
options2string(options,prefix,str,strsize)2126 options2string(options, prefix, str, strsize)
2127 const option_t *options;
2128 const char *prefix;
2129 char *str;
2130 size_t strsize;
2131 {
2132 size_t strused;
2133
2134 if (strsize == 0) {
2135 static char buf[1024];
2136
2137 str = buf;
2138 strsize = sizeof(buf);
2139 }
2140
2141 *str = NUL;
2142 strused = 0;
2143
2144 strused += snprintf(&str[strused], strsize - strused,
2145 "\"%sdaemon\": \"%d\",\n",
2146 prefix, options->daemon);
2147
2148 strused += snprintf(&str[strused], strsize - strused,
2149 "\"%sservercount\": \"%lu\",\n",
2150 prefix, (unsigned long)options->serverc);
2151
2152 strused += snprintf(&str[strused], strsize - strused,
2153 "\"%sverifyonly\": \"%s\",\n",
2154 prefix, options->verifyonly ? "yes" : "no");
2155
2156 strused += snprintf(&str[strused], strsize - strused,
2157 "\"%sdebug\": \"%d\",\n",
2158 prefix, options->debug);
2159
2160 strused += snprintf(&str[strused], strsize - strused,
2161 "\"%sconfigfile\": \"%s\",\n",
2162 prefix,
2163 options->configfile == NULL ?
2164 SOCKD_CONFIGFILE : options->configfile);
2165
2166 strused += snprintf(&str[strused], strsize - strused,
2167 "\"%sdebuglevel\": \"%d\",\n",
2168 prefix, options->debug);
2169
2170 strused += snprintf(&str[strused], strsize - strused,
2171 "\"%skeepalive\": \"%d\",\n",
2172 prefix, options->keepalive);
2173
2174 strused += snprintf(&str[strused], strsize - strused,
2175 "\"%spidfile\": \"%s\",\n",
2176 prefix,
2177 options->pidfile == NULL ?
2178 SOCKD_PIDFILE : options->pidfile);
2179
2180 STRIPTRAILING(str, strused, stripstring);
2181 return str;
2182 }
2183
2184 char *
logs2string(logs,str,strsize)2185 logs2string(logs, str, strsize)
2186 const log_t *logs;
2187 char *str;
2188 size_t strsize;
2189 {
2190 size_t strused;
2191
2192 if (strsize == 0) {
2193 static char buf[128];
2194
2195 str = buf;
2196 strsize = sizeof(buf);
2197 }
2198
2199 *str = NUL;
2200 strused = 0;
2201
2202 if (logs->connect)
2203 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2204 QUOTE(SOCKS_LOG_CONNECTs));
2205
2206 if (logs->disconnect)
2207 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2208 QUOTE(SOCKS_LOG_DISCONNECTs));
2209
2210 if (logs->data)
2211 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2212 QUOTE(SOCKS_LOG_DATAs));
2213
2214 if (logs->error)
2215 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2216 QUOTE(SOCKS_LOG_ERRORs));
2217
2218 if (logs->iooperation)
2219 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2220 QUOTE(SOCKS_LOG_IOOPERATIONs));
2221
2222 if (logs->tcpinfo)
2223 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2224 QUOTE(SOCKS_LOG_TCPINFOs));
2225
2226 STRIPTRAILING(str, strused, stripstring);
2227 return str;
2228 }
2229
2230 const char *
childtype2string(type)2231 childtype2string(type)
2232 int type;
2233 {
2234
2235 switch (type) {
2236 case PROC_MOTHER:
2237 return "mother";
2238
2239 case PROC_MONITOR:
2240 return "monitor-child";
2241
2242 case PROC_NEGOTIATE:
2243 return "negotiate-child";
2244
2245 case PROC_REQUEST:
2246 return "request-child";
2247
2248 case PROC_IO:
2249 return "io-child";
2250
2251 default:
2252 SERRX(type);
2253 }
2254
2255 /* NOTREACHED */
2256 }
2257
2258 const char *
verdict2string(verdict)2259 verdict2string(verdict)
2260 int verdict;
2261 {
2262
2263 switch (verdict) {
2264 case VERDICT_PASS:
2265 return QUOTE(VERDICT_PASSs);
2266
2267 case VERDICT_BLOCK:
2268 return QUOTE(VERDICT_BLOCKs);
2269 }
2270
2271 SERRX(verdict);
2272 /* NOTREACHED */
2273 }
2274
2275 char *
list2string(list,str,strsize)2276 list2string(list, str, strsize)
2277 const linkedname_t *list;
2278 char *str;
2279 size_t strsize;
2280 {
2281 size_t strused;
2282
2283 if (strsize)
2284 *str = NUL; /* make sure we return a NUL terminated string. */
2285 else
2286 return str;
2287
2288 strused = 0;
2289 for (; list != NULL; list = list->next)
2290 strused += snprintf(&str[strused], strsize - strused, "\"%s\", ",
2291 list->name);
2292
2293 return str;
2294 }
2295
2296 char *
compats2string(compats,str,strsize)2297 compats2string(compats, str, strsize)
2298 const compat_t *compats;
2299 char *str;
2300 size_t strsize;
2301 {
2302 size_t strused;
2303
2304 if (strsize == 0) {
2305 static char buf[32];
2306
2307 str = buf;
2308 strsize = sizeof(buf);
2309 }
2310
2311 *str = NUL;
2312 strused = 0;
2313
2314 if (compats->sameport)
2315 strused += snprintf(&str[strused], strsize - strused, "%s, ",
2316 QUOTE("sameport"));
2317
2318 STRIPTRAILING(str, strused, stripstring);
2319 return str;
2320 }
2321
2322 char *
srchosts2string(srchost,prefix,str,strsize)2323 srchosts2string(srchost, prefix, str, strsize)
2324 const srchost_t *srchost;
2325 const char *prefix;
2326 char *str;
2327 size_t strsize;
2328 {
2329 size_t strused;
2330
2331 if (strsize == 0) {
2332 static char buf[32];
2333
2334 str = buf;
2335 strsize = sizeof(buf);
2336 }
2337
2338 *str = NUL;
2339 strused = 0;
2340
2341 if (srchost->nodnsmismatch)
2342 strused += snprintf(&str[strused], strsize - strused,
2343 "\"%snodnsmismatch\", ", prefix);
2344
2345 if (srchost->nodnsunknown)
2346 strused += snprintf(&str[strused], strsize - strused,
2347 "\"%snodnsunknown\",", prefix);
2348
2349 STRIPTRAILING(str, strused, stripstring);
2350 return str;
2351 }
2352
2353 const char *
uid2name(uid)2354 uid2name(uid)
2355 uid_t uid;
2356 {
2357 struct passwd *pw;
2358
2359 if ((pw = getpwuid(uid)) == NULL)
2360 return NULL;
2361
2362 return pw->pw_name;
2363 }
2364
2365 const char *
timeouttype2string(type)2366 timeouttype2string(type)
2367 timeouttype_t type;
2368 {
2369
2370 switch (type) {
2371 case TIMEOUT_NEGOTIATE:
2372 return "negotiate timeout";
2373
2374 case TIMEOUT_CONNECT:
2375 return "connect timeout";
2376
2377 case TIMEOUT_IO:
2378 return "i/o timeout";
2379
2380 case TIMEOUT_TCP_FIN_WAIT:
2381 return "tcp-fin-wait timeout";
2382
2383 default:
2384 SERRX(type);
2385 }
2386
2387 /* NOTREACHED */
2388 }
2389
2390 char *
timeouts2string(timeouts,prefix,str,strsize)2391 timeouts2string(timeouts, prefix, str, strsize)
2392 const timeout_t *timeouts;
2393 const char *prefix;
2394 char *str;
2395 size_t strsize;
2396 {
2397 size_t strused;
2398
2399 if (strsize == 0) {
2400 static char buf[64];
2401
2402 str = buf;
2403 strsize = sizeof(buf);
2404 }
2405
2406 *str = NUL;
2407 strused = 0;
2408
2409 strused += snprintf(&str[strused], strsize - strused,
2410 "\"%sconnecttimeout\": \"%ld\",\n",
2411 prefix, (unsigned long)timeouts->negotiate);
2412
2413 strused += snprintf(&str[strused], strsize - strused,
2414 "\"%siotimeout\": tcp: \"%lu\", udp: \"%lu\" \n",
2415 prefix,
2416 (unsigned long)timeouts->tcpio,
2417 (unsigned long)timeouts->udpio);
2418
2419 STRIPTRAILING(str, strused, stripstring);
2420 return str;
2421 }
2422
2423 const char *
rotation2string(rotation)2424 rotation2string(rotation)
2425 int rotation;
2426 {
2427
2428 switch (rotation) {
2429 case ROTATION_NONE:
2430 return "none";
2431
2432 case ROTATION_SAMESAME:
2433 return "same-same";
2434
2435 case ROTATION_ROUTE:
2436 return "route";
2437
2438 default:
2439 SERRX(rotation);
2440 }
2441
2442 /* NOTREACHED */
2443 }
2444
2445 const char *
privop2string(op)2446 privop2string(op)
2447 const priv_op_t op;
2448 {
2449 switch (op) {
2450 case PRIV_ON:
2451 return "on";
2452
2453 case PRIV_OFF:
2454 return "off";
2455 }
2456
2457
2458 /* NOTREACHED */
2459 SERRX(op);
2460 }
2461
2462
2463
2464 #if HAVE_SCHED_SETAFFINITY
2465 char *
cpuset2string(set,str,strsize)2466 cpuset2string(set, str, strsize)
2467 const cpu_set_t *set;
2468 char *str;
2469 size_t strsize;
2470 {
2471 const size_t setsize = cpu_get_setsize();
2472 size_t i, strused;
2473
2474 if (strsize == 0) {
2475 static char buf[2048];
2476
2477 str = buf;
2478 strsize = sizeof(buf);
2479 }
2480
2481 *str = NUL;
2482 strused = 0;
2483
2484 for (i = 0; i < setsize; ++i)
2485 if (cpu_isset(i, set))
2486 strused += snprintf(&str[strused], strsize - strused, "%ld ", (long)i);
2487
2488 return str;
2489 }
2490 #endif /* HAVE_SCHED_SETAFFINITY */
2491
2492
2493 #if !HAVE_PRIVILEGES
2494 char *
userids2string(userids,prefix,str,strsize)2495 userids2string(userids, prefix, str, strsize)
2496 const userid_t *userids;
2497 const char *prefix;
2498 char *str;
2499 size_t strsize;
2500 {
2501 size_t strused;
2502
2503 if (strsize == 0) {
2504 static char buf[128];
2505
2506 str = buf;
2507 strsize = sizeof(buf);
2508 }
2509
2510 *str = NUL;
2511 strused = 0;
2512
2513 strused += snprintf(&str[strused], strsize - strused,
2514 "\"%sprivileged\": \"%s\",\n",
2515 prefix, uid2name(userids->privileged_uid));
2516
2517 strused += snprintf(&str[strused], strsize - strused,
2518 "\"%sunprivileged\": \"%s\",\n",
2519 prefix, uid2name(userids->unprivileged_uid));
2520
2521 strused += snprintf(&str[strused], strsize - strused,
2522 "\"%slibwrap\": \"%s\",\n",
2523 prefix, uid2name(userids->libwrap_uid));
2524
2525 STRIPTRAILING(str, strused, stripstring);
2526 return str;
2527 }
2528 #endif /* !HAVE_PRIVILEGES */
2529
2530 #if COVENANT
2531 const char *
httpcode2string(version,code)2532 httpcode2string(version, code)
2533 const int version;
2534 const int code;
2535 {
2536 static char prefix[16], buf[64];
2537
2538 SASSERTX(version == PROXY_HTTP_10
2539 || version == PROXY_HTTP_11);
2540
2541 snprintf(prefix, sizeof(prefix), "HTTP/1.%d %d",
2542 version == PROXY_HTTP_10 ? 0 : 1, code);
2543
2544 switch (code) {
2545 case HTTP_SUCCESS:
2546 snprintf(buf, sizeof(buf), "%s Success", prefix);
2547 break;
2548
2549 case HTTP_FORBIDDEN:
2550 snprintf(buf, sizeof(buf), "%s Not allowed", prefix);
2551 break;
2552
2553 case HTTP_NOTALLOWED:
2554 snprintf(buf, sizeof(buf), "%s Not authorized", prefix);
2555 break;
2556
2557 case HTTP_PROXYAUTHREQUIRED:
2558 snprintf(buf, sizeof(buf), "%s Not authorized", prefix);
2559 break;
2560
2561 case HTTP_HOSTUNREACH:
2562 snprintf(buf, sizeof(buf), "%s Not reachable", prefix);
2563 break;
2564
2565 case HTTP_FAILURE:
2566 snprintf(buf, sizeof(buf), "%s Unknown proxy server error", prefix);
2567 break;
2568
2569 default:
2570 SERRX(code);
2571 }
2572
2573 return buf;
2574 }
2575 #endif /* COVENANT */
2576
2577 #endif /* !SOCKS_CLIENT */
2578