OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / satot.c
1 /*
2  * convert from binary form of SA ID to text
3  * Copyright (C) 2000, 2001  Henry Spencer.
4  * 
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Library General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9  * 
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13  * License for more details.
14  *
15  * RCSID $Id: satot.c,v 1.8 2001/10/23 03:06:16 henry Exp $
16  */
17 #include "internal.h"
18 #include "freeswan.h"
19
20 static struct typename {
21         char type;
22         char *name;
23 } typenames[] = {
24         { SA_AH,        "ah" },
25         { SA_ESP,       "esp" },
26         { SA_IPIP,      "tun" },
27         { SA_COMP,      "comp" },
28         { SA_INT,       "int" },
29         { 0,            NULL }
30 };
31
32 /*
33  - satot - convert SA to text "ah507@1.2.3.4"
34  */
35 size_t                          /* space needed for full conversion */
36 satot(sa, format, dst, dstlen)
37 const ip_said *sa;
38 int format;                     /* character */
39 char *dst;                      /* need not be valid if dstlen is 0 */
40 size_t dstlen;
41 {
42         size_t len = 0;         /* 0 means "not recognized yet" */
43         int base;
44         int showversion;        /* use delimiter to show IP version? */
45         struct typename *tn;
46         char *p;
47         char *pre;
48         char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
49         char unk[10];
50
51         switch (format) {
52         case 0:
53                 base = 16;
54                 showversion = 1;
55                 break;
56         case 'f':
57                 base = 17;
58                 showversion = 1;
59                 break;
60         case 'x':
61                 base = 'x';
62                 showversion = 0;
63                 break;
64         case 'd':
65                 base = 10;
66                 showversion = 0;
67                 break;
68         default:
69                 return 0;
70                 break;
71         }
72
73         pre = NULL;
74         for (tn = typenames; tn->name != NULL; tn++)
75                 if (sa->proto == tn->type) {
76                         pre = tn->name;
77                         break;                  /* NOTE BREAK OUT */
78                 }
79         if (pre == NULL) {              /* unknown protocol */
80                 strcpy(unk, "unk");
81                 (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
82                                                 sizeof(unk)-strlen(unk));
83                 pre = unk;
84         }
85
86         if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
87                                         sa->spi == PASSTHROUGHSPI &&
88                                         isunspecaddr(&sa->dst)) {
89                 strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
90                                                         PASSTHROUGH4NAME :
91                                                         PASSTHROUGH6NAME);
92                 len = strlen(buf);
93         }
94         
95         if (sa->proto == SA_INT && addrtypeof(&sa->dst) == AF_INET &&
96                                                 isunspecaddr(&sa->dst)) {
97                 switch (ntohl(sa->spi)) {
98                 case SPI_PASS:  p = "%pass";    break;
99                 case SPI_DROP:  p = "%drop";    break;
100                 case SPI_REJECT:        p = "%reject";  break;
101                 case SPI_HOLD:  p = "%hold";    break;
102                 case SPI_TRAP:  p = "%trap";    break;
103                 case SPI_TRAPSUBNET:    p = "%trapsubnet";      break;
104                 default:        p = NULL;       break;
105                 }
106                 if (p != NULL) {
107                         strcpy(buf, p);
108                         len = strlen(buf);
109                 }
110         }
111
112         if (len == 0) {                 /* general case needed */
113                 strcpy(buf, pre);
114                 len = strlen(buf);
115                 if (showversion) {
116                         *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
117                                                                         ':';
118                         len++;
119                         *(buf+len) = '\0';
120                 }
121                 len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
122                 *(buf+len-1) = '@';
123                 len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
124         }
125
126         if (dst != NULL) {
127                 if (len > dstlen)
128                         *(buf+dstlen-1) = '\0';
129                 strcpy(dst, buf);
130         }
131         return len;
132 }