port to new RADIUS client library
[radsecproxy.git] / lib / radius / print.c
1 /*
2 Copyright (c) 2011, Network RADIUS SARL
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in the
11       documentation and/or other materials provided with the distribution.
12     * Neither the name of the <organization> nor the
13       names of its contributors may be used to endorse or promote products
14       derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /** \file print.c
29  *  \brief Functions to print things.
30  */
31
32 #include "client.h"
33 #include <string.h>
34 #ifdef RS_TYPE_IPV6ADDR
35 #include <arpa/inet.h>
36 #endif
37
38 #ifndef NDEBUG
39 void nr_packet_print_hex(RADIUS_PACKET *packet)
40 {
41         int i;
42
43         if (!packet->data) return;
44
45         printf("  Code:\t\t%u\n", packet->data[0]);
46         printf("  Id:\t\t%u\n", packet->data[1]);
47         printf("  Length:\t%u\n", ((packet->data[2] << 8) |
48                                    (packet->data[3])));
49         printf("  Vector:\t");
50         for (i = 4; i < 20; i++) {
51                 printf("%02x", packet->data[i]);
52         }
53         printf("\n");
54         if ((packet->flags & RS_PACKET_SIGNED) == 0) printf("\t\tWARNING: nr_packet_sign() was not called!\n");
55
56         if (packet->length > 20) {
57                 int total;
58                 const uint8_t *ptr;
59                 printf("  Data:");
60
61                 total = packet->length - 20;
62                 ptr = packet->data + 20;
63
64                 while (total > 0) {
65                         int attrlen;
66
67                         printf("\t\t");
68                         if (total < 2) { /* too short */
69                                 printf("%02x\n", *ptr);
70                                 break;
71                         }
72
73                         if (ptr[1] > total) { /* too long */
74                                 for (i = 0; i < total; i++) {
75                                         printf("%02x ", ptr[i]);
76                                 }
77                                 break;
78                         }
79
80                         printf("%02x  %02x  ", ptr[0], ptr[1]);
81                         attrlen = ptr[1] - 2;
82                         ptr += 2;
83                         total -= 2;
84
85                         for (i = 0; i < attrlen; i++) {
86                                 if ((i > 0) && ((i & 0x0f) == 0x00))
87                                         printf("\t\t\t");
88                                 printf("%02x ", ptr[i]);
89                                 if ((i & 0x0f) == 0x0f) printf("\n");
90                         }
91
92                         if (!attrlen || ((attrlen & 0x0f) != 0x00)) printf("\n");
93
94                         ptr += attrlen;
95                         total -= attrlen;
96                 }
97         }
98         printf("\n");
99         fflush(stdout);
100 }
101 #endif
102
103 size_t nr_vp_snprintf_value(char *buffer, size_t buflen, const VALUE_PAIR *vp)
104 {
105         size_t i, len;
106         char *p = buffer;
107
108         switch (vp->da->type) {
109         case RS_TYPE_STRING:
110                 /*
111                  *      FIXME: escape backslash && quotes!
112                  */
113                 len = snprintf(p, buflen, "%s", vp->vp_strvalue);
114                 break;
115
116         case RS_TYPE_DATE:
117         case RS_TYPE_INTEGER:
118         case RS_TYPE_SHORT:
119         case RS_TYPE_BYTE:
120                 len = snprintf(p, buflen, "%u", vp->vp_integer);
121                 break;
122
123         case RS_TYPE_IPADDR:
124                 len = snprintf(p, buflen, "%u.%u.%u.%u",
125                                (vp->vp_ipaddr >> 24) & 0xff,
126                                (vp->vp_ipaddr >> 16) & 0xff,
127                                (vp->vp_ipaddr >> 8) & 0xff,
128                                vp->vp_ipaddr & 0xff);
129                 break;
130
131 #ifdef RS_TYPE_IPV6ADDR
132         case RS_TYPE_IPV6ADDR:
133                 if (!inet_ntop(AF_INET6, &vp->vp_ipv6addr, buffer, buflen)) {
134                         return -RSE_SYSTEM;
135                 }
136                 break;
137 #endif
138
139 #ifdef RS_TYPE_IFID
140         case RS_TYPE_IFID:
141                 len = snprintf(p, buflen, "%02x%02x%02x%02x%02x%02x%02x%02x",
142                                vp->vp_ifid[0], vp->vp_ifid[1],
143                                vp->vp_ifid[2], vp->vp_ifid[3],
144                                vp->vp_ifid[4], vp->vp_ifid[5],
145                                vp->vp_ifid[6], vp->vp_ifid[7]);
146                 break;
147 #endif
148
149         case RS_TYPE_OCTETS:
150                 len = snprintf(p, buflen, "0x");
151                 if (len >= buflen) return 0;
152
153                 p += len;
154                 buflen -= len;
155
156                 for (i = 0; i < vp->length; i++) {
157                         len = snprintf(p, buflen, "%02x", vp->vp_octets[i]);
158                         if (len >= buflen) return 0;
159                         
160                         p += len;
161                         buflen -= len;
162                 }
163                 len = 0;
164                 break;
165
166         default:
167                 break;
168         }
169
170         if (len >= buflen) return 0;
171
172         p += len;
173         buflen -= len;
174
175         return p - buffer;
176 }
177
178 size_t nr_vp_snprintf(char *buffer, size_t buflen, const VALUE_PAIR *vp)
179 {
180         size_t len;
181         char *p = buffer;
182
183         len = snprintf(p, buflen, "%s = ", vp->da->name);
184         if (len >= buflen) return 0;
185
186         p += len;
187         buflen -= len;
188
189         len = nr_vp_snprintf_value(p, buflen, vp);
190         if (len == 0) return 0;
191
192         if (len >= buflen) return 0;
193
194         p += len;
195
196         return p - buffer;
197 }
198
199 #ifndef NDEBUG
200 void nr_vp_fprintf_list(FILE *fp, const VALUE_PAIR *vps)
201 {
202         const VALUE_PAIR *vp;
203         char buffer[1024];
204
205         for (vp = vps; vp != NULL; vp = vp->next) {
206                 nr_vp_snprintf(buffer, sizeof(buffer), vp);
207                 fprintf(fp, "\t%s\n", buffer);
208         }
209 }
210 #endif
211
212 /** \cond PRIVATE */
213 #define NR_STRERROR_BUFSIZE (1024)
214 static char nr_strerror_buffer[NR_STRERROR_BUFSIZE];
215
216 void nr_strerror_printf(const char *fmt, ...)
217 {
218         va_list ap;
219         va_start(ap, fmt);
220         vsnprintf(nr_strerror_buffer, sizeof(nr_strerror_buffer), fmt, ap);
221         va_end(ap);
222
223         fprintf(stderr, "ERROR: %s\n", nr_strerror_buffer);
224 }
225 /** \endcond */
226