6fa06d73e60d284bf284fbd6b930772613512c92
[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                 len = 0;
168                 break;
169         }
170
171         if (len >= buflen) return 0;
172
173         p += len;
174         buflen -= len;
175
176         return p - buffer;
177 }
178
179 size_t nr_vp_snprintf(char *buffer, size_t buflen, const VALUE_PAIR *vp)
180 {
181         size_t len;
182         char *p = buffer;
183
184         len = snprintf(p, buflen, "%s = ", vp->da->name);
185         if (len >= buflen) return 0;
186
187         p += len;
188         buflen -= len;
189
190         len = nr_vp_snprintf_value(p, buflen, vp);
191         if (len == 0) return 0;
192
193         if (len >= buflen) return 0;
194
195         p += len;
196
197         return p - buffer;
198 }
199
200 #ifndef NDEBUG
201 void nr_vp_fprintf_list(FILE *fp, const VALUE_PAIR *vps)
202 {
203         const VALUE_PAIR *vp;
204         char buffer[1024];
205
206         for (vp = vps; vp != NULL; vp = vp->next) {
207                 nr_vp_snprintf(buffer, sizeof(buffer), vp);
208                 fprintf(fp, "\t%s\n", buffer);
209         }
210 }
211 #endif
212
213 /** \cond PRIVATE */
214 #define NR_STRERROR_BUFSIZE (1024)
215 static char nr_strerror_buffer[NR_STRERROR_BUFSIZE];
216
217 void nr_strerror_printf(const char *fmt, ...)
218 {
219         va_list ap;
220         va_start(ap, fmt);
221         vsnprintf(nr_strerror_buffer, sizeof(nr_strerror_buffer), fmt, ap);
222         va_end(ap);
223
224         fprintf(stderr, "ERROR: %s\n", nr_strerror_buffer);
225 }
226 /** \endcond */
227