Moved API to (attr, vendor), instead of just attr
[freeradius.git] / src / lib / valuepair.c
1 /*
2  * valuepair.c  Functions to handle VALUE_PAIRs
3  *
4  * Version:     $Id$
5  *
6  *   This library is free software; you can redistribute it and/or
7  *   modify it under the terms of the GNU Lesser General Public
8  *   License as published by the Free Software Foundation; either
9  *   version 2.1 of the License, or (at your option) any later version.
10  *
11  *   This library is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *   Lesser General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Lesser General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006  The FreeRADIUS server project
21  */
22
23 #include <freeradius-devel/ident.h>
24 RCSID("$Id$")
25
26 #include        <freeradius-devel/libradius.h>
27
28 #include        <ctype.h>
29
30 #ifdef HAVE_MALLOC_H
31 #  include      <malloc.h>
32 #endif
33
34 #ifdef HAVE_REGEX_H
35 #  include      <regex.h>
36 #endif
37
38 static const char *months[] = {
39         "jan", "feb", "mar", "apr", "may", "jun",
40         "jul", "aug", "sep", "oct", "nov", "dec" };
41
42 /*
43  *      This padding is necessary only for attributes that are NOT
44  *      in the dictionary, and then only because the rest of the
45  *      code accesses vp->name directly, rather than through an
46  *      accessor function.
47  *
48  *      The name padding only has to large enough for:
49  *
50  *              Vendor-65535-Attr-65535
51  *
52  *      i.e. 23 characters, plus a zero.  We add another 8 bytes for
53  *      padding, because the VALUE_PAIR structure may be un-aligned.
54  *
55  *      The result is that for the normal case, the server uses a less
56  *      memory (36 bytes * number of VALUE_PAIRs).
57  */
58 #define FR_VP_NAME_PAD (32)
59 #define FR_VP_NAME_LEN (24)
60
61 VALUE_PAIR *pairalloc(DICT_ATTR *da)
62 {
63         size_t name_len = 0;
64         VALUE_PAIR *vp;
65
66         /*
67          *      Not in the dictionary: the name is allocated AFTER
68          *      the VALUE_PAIR struct.
69          */
70         if (!da) name_len = FR_VP_NAME_PAD;
71
72         vp = malloc(sizeof(*vp) + name_len);
73         if (!vp) return NULL;
74         memset(vp, 0, sizeof(*vp));
75
76         if (da) {
77                 vp->attribute = da->attr;
78                 vp->vendor = da->vendor;
79                 vp->type = da->type;
80                 vp->name = da->name;
81                 vp->flags = da->flags;
82         } else {
83                 vp->attribute = 0;
84                 vp->vendor = 0;
85                 vp->type = PW_TYPE_OCTETS;
86                 vp->name = NULL;
87                 memset(&vp->flags, 0, sizeof(vp->flags));
88                 vp->flags.unknown_attr = 1;
89         }
90
91         switch (vp->type) {
92                 case PW_TYPE_BYTE:
93                         vp->length = 1;
94                         break;
95
96                 case PW_TYPE_SHORT:
97                         vp->length = 2;
98                         break;
99
100                 case PW_TYPE_INTEGER:
101                 case PW_TYPE_IPADDR:
102                 case PW_TYPE_DATE:
103                 case PW_TYPE_SIGNED:
104                         vp->length = 4;
105                         break;
106
107                 case PW_TYPE_IFID:
108                         vp->length = sizeof(vp->vp_ifid);
109                         break;
110
111                 case PW_TYPE_IPV6ADDR:
112                         vp->length = sizeof(vp->vp_ipv6addr);
113                         break;
114
115                 case PW_TYPE_IPV6PREFIX:
116                         vp->length = sizeof(vp->vp_ipv6prefix);
117                         break;
118
119                 case PW_TYPE_ETHERNET:
120                         vp->length = sizeof(vp->vp_ether);
121                         break;
122
123                 case PW_TYPE_TLV:
124                         vp->vp_tlv = NULL;
125                         vp->length = 0;
126                         break;
127
128                 case PW_TYPE_COMBO_IP:
129                 default:
130                         vp->length = 0;
131                         break;
132         }
133
134         return vp;
135 }
136
137
138 /*
139  *      Create a new valuepair.
140  */
141 VALUE_PAIR *paircreate(int attr, int vendor, int type)
142 {
143         VALUE_PAIR      *vp;
144         DICT_ATTR       *da;
145
146         da = dict_attrbyvalue(attr, vendor);
147         if ((vp = pairalloc(da)) == NULL) {
148                 fr_strerror_printf("out of memory");
149                 return NULL;
150         }
151         vp->operator = T_OP_EQ;
152
153         /*
154          *      It isn't in the dictionary: update the name.
155          */
156         if (!da) {
157                 char *p = (char *) (vp + 1);
158                 
159                 vp->vendor = vendor;
160                 vp->attribute = attr;
161                 vp->name = p;
162                 vp->type = type; /* be forgiving */
163
164                 if (!vp_print_name(p, FR_VP_NAME_LEN, attr, vendor)) {
165                         free(vp);
166                         return NULL;
167                 }
168         }
169
170         return vp;
171 }
172
173 /*
174  *      release the memory used by a single attribute-value pair
175  *      just a wrapper around free() for now.
176  */
177 void pairbasicfree(VALUE_PAIR *pair)
178 {
179         if (pair->type == PW_TYPE_TLV) free(pair->vp_tlv);
180         /* clear the memory here */
181         memset(pair, 0, sizeof(*pair));
182         free(pair);
183 }
184
185 /*
186  *      Release the memory used by a list of attribute-value
187  *      pairs, and sets the pair pointer to NULL.
188  */
189 void pairfree(VALUE_PAIR **pair_ptr)
190 {
191         VALUE_PAIR      *next, *pair;
192
193         if (!pair_ptr) return;
194         pair = *pair_ptr;
195
196         while (pair != NULL) {
197                 next = pair->next;
198                 pairbasicfree(pair);
199                 pair = next;
200         }
201
202         *pair_ptr = NULL;
203 }
204
205
206 /*
207  *      Find the pair with the matching attribute
208  */
209 VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr, int vendor)
210 {
211         while(first && (first->attribute != attr) && (first->vendor != vendor))
212                 first = first->next;
213         return first;
214 }
215
216
217 /*
218  *      Delete the pair(s) with the matching attribute
219  */
220 void pairdelete(VALUE_PAIR **first, int attr, int vendor)
221 {
222         VALUE_PAIR *i, *next;
223         VALUE_PAIR **last = first;
224
225         for(i = *first; i; i = next) {
226                 next = i->next;
227                 if ((i->attribute == attr) && (i->vendor == vendor)) {
228                         *last = next;
229                         pairbasicfree(i);
230                 } else {
231                         last = &i->next;
232                 }
233         }
234 }
235
236 /*
237  *      Add a pair at the end of a VALUE_PAIR list.
238  */
239 void pairadd(VALUE_PAIR **first, VALUE_PAIR *add)
240 {
241         VALUE_PAIR *i;
242
243         if (!add) return;
244
245         if (*first == NULL) {
246                 *first = add;
247                 return;
248         }
249         for(i = *first; i->next; i = i->next)
250                 ;
251         i->next = add;
252 }
253
254 /*
255  *      Add or replace a pair at the end of a VALUE_PAIR list.
256  */
257 void pairreplace(VALUE_PAIR **first, VALUE_PAIR *replace)
258 {
259         VALUE_PAIR *i, *next;
260         VALUE_PAIR **prev = first;
261
262         if (*first == NULL) {
263                 *first = replace;
264                 return;
265         }
266
267         /*
268          *      Not an empty list, so find item if it is there, and
269          *      replace it. Note, we always replace the first one, and
270          *      we ignore any others that might exist.
271          */
272         for(i = *first; i; i = next) {
273                 next = i->next;
274
275                 /*
276                  *      Found the first attribute, replace it,
277                  *      and return.
278                  */
279                 if (i->attribute == replace->attribute) {
280                         *prev = replace;
281
282                         /*
283                          *      Should really assert that replace->next == NULL
284                          */
285                         replace->next = next;
286                         pairbasicfree(i);
287                         return;
288                 }
289
290                 /*
291                  *      Point to where the attribute should go.
292                  */
293                 prev = &i->next;
294         }
295
296         /*
297          *      If we got here, we didn't find anything to replace, so
298          *      stopped at the last item, which we just append to.
299          */
300         *prev = replace;
301 }
302
303
304 /*
305  *      Copy just one VP.
306  */
307 VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp)
308 {
309         size_t name_len;
310         VALUE_PAIR *n;
311         
312         if (!vp->flags.unknown_attr) {
313                 name_len = 0;
314         } else {
315                 name_len = FR_VP_NAME_PAD;
316         }
317         
318         if ((n = malloc(sizeof(*n) + name_len)) == NULL) {
319                 fr_strerror_printf("out of memory");
320                 return NULL;
321         }
322         memcpy(n, vp, sizeof(*n) + name_len);
323         n->next = NULL;
324
325         if ((n->type == PW_TYPE_TLV) &&
326             (n->vp_tlv != NULL)) {
327                 n->vp_tlv = malloc(n->length);
328                 memcpy(n->vp_tlv, vp->vp_tlv, n->length);
329         }
330
331         return n;
332 }
333
334
335 /*
336  *      Copy just a certain type of pairs.
337  */
338 VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr, int vendor)
339 {
340         VALUE_PAIR      *first, *n, **last;
341
342         first = NULL;
343         last = &first;
344
345         while (vp) {
346                 if ((attr >= 0) &&
347                     (vp->attribute != attr) && (vp->vendor != vendor)) {
348                         vp = vp->next;
349                         continue;
350                 }
351
352                 n = paircopyvp(vp);
353                 if (!n) return first;
354                 *last = n;
355                 last = &n->next;
356                 vp = vp->next;
357         }
358         return first;
359 }
360
361
362 /*
363  *      Copy a pairlist.
364  */
365 VALUE_PAIR *paircopy(VALUE_PAIR *vp)
366 {
367         return paircopy2(vp, -1, 0);
368 }
369
370
371 /*
372  *      Move attributes from one list to the other
373  *      if not already present.
374  */
375 void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
376 {
377         VALUE_PAIR **tailto, *i, *j, *next;
378         VALUE_PAIR *tailfrom = NULL;
379         VALUE_PAIR *found;
380         int has_password = 0;
381
382         /*
383          *      First, see if there are any passwords here, and
384          *      point "tailto" to the end of the "to" list.
385          */
386         tailto = to;
387         for(i = *to; i; i = i->next) {
388                 if (i->attribute == PW_USER_PASSWORD ||
389                     i->attribute == PW_CRYPT_PASSWORD)
390                         has_password = 1;
391                 tailto = &i->next;
392         }
393
394         /*
395          *      Loop over the "from" list.
396          */
397         for(i = *from; i; i = next) {
398                 next = i->next;
399
400                 /*
401                  *      If there was a password in the "to" list,
402                  *      do not move any other password from the
403                  *      "from" to the "to" list.
404                  */
405                 if (has_password &&
406                     (i->attribute == PW_USER_PASSWORD ||
407                      i->attribute == PW_CRYPT_PASSWORD)) {
408                         tailfrom = i;
409                         continue;
410                 }
411
412                 switch (i->operator) {
413                         /*
414                          *      These are COMPARISON attributes
415                          *      from a check list, and are not
416                          *      supposed to be copied!
417                          */
418                         case T_OP_NE:
419                         case T_OP_GE:
420                         case T_OP_GT:
421                         case T_OP_LE:
422                         case T_OP_LT:
423                         case T_OP_CMP_TRUE:
424                         case T_OP_CMP_FALSE:
425                         case T_OP_CMP_EQ:
426                                 tailfrom = i;
427                                 continue;
428
429                         default:
430                                 break;
431                 }
432
433                 /*
434                  *      If the attribute is already present in "to",
435                  *      do not move it from "from" to "to". We make
436                  *      an exception for "Hint" which can appear multiple
437                  *      times, and we never move "Fall-Through".
438                  */
439                 if (i->attribute == PW_FALL_THROUGH ||
440                     (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {
441
442                         found = pairfind(*to, i->attribute, i->vendor);
443                         switch (i->operator) {
444
445                           /*
446                            *    If matching attributes are found,
447                            *    delete them.
448                            */
449                         case T_OP_SUB:          /* -= */
450                                 if (found) {
451                                         if (!i->vp_strvalue[0] ||
452                                             (strcmp((char *)found->vp_strvalue,
453                                                     (char *)i->vp_strvalue) == 0)){
454                                                 pairdelete(to, found->attribute, found->vendor);
455
456                                                 /*
457                                                  *      'tailto' may have been
458                                                  *      deleted...
459                                                  */
460                                                 tailto = to;
461                                                 for(j = *to; j; j = j->next) {
462                                                         tailto = &j->next;
463                                                 }
464                                         }
465                                 }
466                                 tailfrom = i;
467                                 continue;
468                                 break;
469
470 /* really HAVE_REGEX_H */
471 #if 0
472                                 /*
473                                  *  Attr-Name =~ "s/find/replace/"
474                                  *
475                                  *  Very bad code.  Barely working,
476                                  *  if at all.
477                                  */
478
479                         case T_OP_REG_EQ:
480                           if (found &&
481                               (i->vp_strvalue[0] == 's')) {
482                             regex_t             reg;
483                             regmatch_t          match[1];
484
485                             char *str;
486                             char *p, *q;
487
488                             p = i->vp_strvalue + 1;
489                             q = strchr(p + 1, *p);
490                             if (!q || (q[strlen(q) - 1] != *p)) {
491                               tailfrom = i;
492                               continue;
493                             }
494                             str = strdup(i->vp_strvalue + 2);
495                             q = strchr(str, *p);
496                             *(q++) = '\0';
497                             q[strlen(q) - 1] = '\0';
498
499                             regcomp(&reg, str, 0);
500                             if (regexec(&reg, found->vp_strvalue,
501                                         1, match, 0) == 0) {
502                               fprintf(stderr, "\"%s\" will have %d to %d replaced with %s\n",
503                                       found->vp_strvalue, match[0].rm_so,
504                                       match[0].rm_eo, q);
505
506                             }
507                             regfree(&reg);
508                             free(str);
509                           }
510                           tailfrom = i; /* don't copy it over */
511                           continue;
512                           break;
513 #endif
514                         case T_OP_EQ:           /* = */
515                                 /*
516                                  *  FIXME: Tunnel attributes with
517                                  *  different tags are different
518                                  *  attributes.
519                                  */
520                                 if (found) {
521                                         tailfrom = i;
522                                         continue; /* with the loop */
523                                 }
524                                 break;
525
526                           /*
527                            *  If a similar attribute is found,
528                            *  replace it with the new one.  Otherwise,
529                            *  add the new one to the list.
530                            */
531                         case T_OP_SET:          /* := */
532                                 if (found) {
533                                         VALUE_PAIR *mynext = found->next;
534
535                                         /*
536                                          *      Do NOT call pairdelete()
537                                          *      here, due to issues with
538                                          *      re-writing "request->username".
539                                          *
540                                          *      Everybody calls pairmove,
541                                          *      and expects it to work.
542                                          *      We can't update request->username
543                                          *      here, so instead we over-write
544                                          *      the vp that it's pointing to.
545                                          */
546                                         memcpy(found, i, sizeof(*found));
547                                         found->next = mynext;
548
549                                         pairdelete(&found->next, found->attribute, found->vendor);
550
551                                         /*
552                                          *      'tailto' may have been
553                                          *      deleted...
554                                          */
555                                         for(j = found; j; j = j->next) {
556                                                 tailto = &j->next;
557                                         }
558                                         continue;
559                                 }
560                                 break;
561
562                           /*
563                            *  Add the new element to the list, even
564                            *  if similar ones already exist.
565                            */
566                         default:
567                         case T_OP_ADD: /* += */
568                                 break;
569                         }
570                 }
571                 if (tailfrom)
572                         tailfrom->next = next;
573                 else
574                         *from = next;
575
576                 /*
577                  *      If ALL of the 'to' attributes have been deleted,
578                  *      then ensure that the 'tail' is updated to point
579                  *      to the head.
580                  */
581                 if (!*to) {
582                         tailto = to;
583                 }
584                 *tailto = i;
585                 if (i) {
586                         i->next = NULL;
587                         tailto = &i->next;
588                 }
589         }
590 }
591
592 /*
593  *      Move one kind of attributes from one list to the other
594  */
595 void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr, int vendor)
596 {
597         VALUE_PAIR *to_tail, *i, *next;
598         VALUE_PAIR *iprev = NULL;
599
600         /*
601          *      Find the last pair in the "to" list and put it in "to_tail".
602          */
603         if (*to != NULL) {
604                 to_tail = *to;
605                 for(i = *to; i; i = i->next)
606                         to_tail = i;
607         } else
608                 to_tail = NULL;
609
610         for(i = *from; i; i = next) {
611                 next = i->next;
612
613                 /*
614                  *      vendor=0, attr = PW_VENDOR_SPECIFIC means
615                  *      "match any vendor attribute".  Otherwise, do
616                  *      an exact match
617                  */
618                 if (((vendor != 0) || (attr != PW_VENDOR_SPECIFIC)) &&
619                     (i->attribute != attr) && (i->vendor != vendor)) {
620                         iprev = i;
621                         continue;
622                 }
623
624                 /*
625                  *      If the attribute to move IS a VSA, then it ignores
626                  *      any non-VSA attribute.
627                  */
628                 if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC) &&
629                     (i->vendor == 0)) {
630                         iprev = i;
631                         continue;
632                 }
633
634                 /*
635                  *      Remove the attribute from the "from" list.
636                  */
637                 if (iprev)
638                         iprev->next = next;
639                 else
640                         *from = next;
641
642                 /*
643                  *      Add the attribute to the "to" list.
644                  */
645                 if (to_tail)
646                         to_tail->next = i;
647                 else
648                         *to = i;
649                 to_tail = i;
650                 i->next = NULL;
651         }
652 }
653
654
655 /*
656  *      Sort of strtok/strsep function.
657  */
658 static char *mystrtok(char **ptr, const char *sep)
659 {
660         char    *res;
661
662         if (**ptr == 0)
663                 return NULL;
664         while (**ptr && strchr(sep, **ptr))
665                 (*ptr)++;
666         if (**ptr == 0)
667                 return NULL;
668         res = *ptr;
669         while (**ptr && strchr(sep, **ptr) == NULL)
670                 (*ptr)++;
671         if (**ptr != 0)
672                 *(*ptr)++ = 0;
673         return res;
674 }
675
676 /*
677  *      Turn printable string into time_t
678  *      Returns -1 on error, 0 on OK.
679  */
680 static int gettime(const char *valstr, time_t *date)
681 {
682         int             i;
683         time_t          t;
684         struct tm       *tm, s_tm;
685         char            buf[64];
686         char            *p;
687         char            *f[4];
688         char            *tail = '\0';
689
690         /*
691          * Test for unix timestamp date
692          */
693         *date = strtoul(valstr, &tail, 10);
694         if (*tail == '\0') {
695                 return 0;
696         }
697
698         tm = &s_tm;
699         memset(tm, 0, sizeof(*tm));
700         tm->tm_isdst = -1;      /* don't know, and don't care about DST */
701
702         strlcpy(buf, valstr, sizeof(buf));
703
704         p = buf;
705         f[0] = mystrtok(&p, " \t");
706         f[1] = mystrtok(&p, " \t");
707         f[2] = mystrtok(&p, " \t");
708         f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
709         if (!f[0] || !f[1] || !f[2]) return -1;
710
711         /*
712          *      The time has a colon, where nothing else does.
713          *      So if we find it, bubble it to the back of the list.
714          */
715         if (f[3]) {
716                 for (i = 0; i < 3; i++) {
717                         if (strchr(f[i], ':')) {
718                                 p = f[3];
719                                 f[3] = f[i];
720                                 f[i] = p;
721                                 break;
722                         }
723                 }
724         }
725
726         /*
727          *  The month is text, which allows us to find it easily.
728          */
729         tm->tm_mon = 12;
730         for (i = 0; i < 3; i++) {
731                 if (isalpha( (int) *f[i])) {
732                         /*
733                          *  Bubble the month to the front of the list
734                          */
735                         p = f[0];
736                         f[0] = f[i];
737                         f[i] = p;
738
739                         for (i = 0; i < 12; i++) {
740                                 if (strncasecmp(months[i], f[0], 3) == 0) {
741                                         tm->tm_mon = i;
742                                         break;
743                                 }
744                         }
745                 }
746         }
747
748         /* month not found? */
749         if (tm->tm_mon == 12) return -1;
750
751         /*
752          *  The year may be in f[1], or in f[2]
753          */
754         tm->tm_year = atoi(f[1]);
755         tm->tm_mday = atoi(f[2]);
756
757         if (tm->tm_year >= 1900) {
758                 tm->tm_year -= 1900;
759
760         } else {
761                 /*
762                  *  We can't use 2-digit years any more, they make it
763                  *  impossible to tell what's the day, and what's the year.
764                  */
765                 if (tm->tm_mday < 1900) return -1;
766
767                 /*
768                  *  Swap the year and the day.
769                  */
770                 i = tm->tm_year;
771                 tm->tm_year = tm->tm_mday - 1900;
772                 tm->tm_mday = i;
773         }
774
775         /*
776          *  If the day is out of range, die.
777          */
778         if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
779                 return -1;
780         }
781
782         /*
783          *      There may be %H:%M:%S.  Parse it in a hacky way.
784          */
785         if (f[3]) {
786                 f[0] = f[3];    /* HH */
787                 f[1] = strchr(f[0], ':'); /* find : separator */
788                 if (!f[1]) return -1;
789
790                 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
791
792                 f[2] = strchr(f[1], ':'); /* find : separator */
793                 if (f[2]) {
794                   *(f[2]++) = '\0';     /* nuke it, and point to SS */
795                 } else {
796                   strcpy(f[2], "0");    /* assignment would discard const */
797                 }
798
799                 tm->tm_hour = atoi(f[0]);
800                 tm->tm_min = atoi(f[1]);
801                 tm->tm_sec = atoi(f[2]);
802         }
803
804         /*
805          *  Returns -1 on error.
806          */
807         t = mktime(tm);
808         if (t == (time_t) -1) return -1;
809
810         *date = t;
811
812         return 0;
813 }
814
815 static const char *hextab = "0123456789abcdef";
816
817 /*
818  *  Parse a string value into a given VALUE_PAIR
819  *
820  *  FIXME: we probably want to fix this function to accept
821  *  octets as values for any type of attribute.  We should then
822  *  double-check the parsed value, to be sure it's legal for that
823  *  type (length, etc.)
824  */
825 static uint32_t getint(const char *value, char **end)
826 {
827         if ((value[0] == '0') && (value[1] == 'x')) {
828                 return strtoul(value, end, 16);
829         }
830
831         return strtoul(value, end, 10);
832 }
833
834 static int check_for_whitespace(const char *value)
835 {
836         while (*value) {
837                 if (!isspace((int) *value)) return 0;
838
839                 value++;
840         }
841
842         return 1;
843 }
844
845
846 VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
847 {
848         char            *p, *s=0;
849         const char      *cp, *cs;
850         int             x;
851         size_t          length;
852         DICT_VALUE      *dval;
853
854         if (!value) return NULL;
855
856         /*
857          *      Even for integers, dates and ip addresses we
858          *      keep the original string in vp->vp_strvalue.
859          */
860         if (vp->type != PW_TYPE_TLV) {
861                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
862                 vp->length = strlen(vp->vp_strvalue);
863         }
864
865         switch(vp->type) {
866                 case PW_TYPE_STRING:
867                         /*
868                          *      Do escaping here
869                          */
870                         p = vp->vp_strvalue;
871                         cp = value;
872                         length = 0;
873
874                         while (*cp && (length < (sizeof(vp->vp_strvalue) - 1))) {
875                                 char c = *cp++;
876
877                                 if (c == '\\') {
878                                         switch (*cp) {
879                                         case 'r':
880                                                 c = '\r';
881                                                 cp++;
882                                                 break;
883                                         case 'n':
884                                                 c = '\n';
885                                                 cp++;
886                                                 break;
887                                         case 't':
888                                                 c = '\t';
889                                                 cp++;
890                                                 break;
891                                         case '"':
892                                                 c = '"';
893                                                 cp++;
894                                                 break;
895                                         case '\'':
896                                                 c = '\'';
897                                                 cp++;
898                                                 break;
899                                         case '`':
900                                                 c = '`';
901                                                 cp++;
902                                                 break;
903                                         case '\0':
904                                                 c = '\\'; /* no cp++ */
905                                                 break;
906                                         default:
907                                                 if ((cp[0] >= '0') &&
908                                                     (cp[0] <= '9') &&
909                                                     (cp[1] >= '0') &&
910                                                     (cp[1] <= '9') &&
911                                                     (cp[2] >= '0') &&
912                                                     (cp[2] <= '9') &&
913                                                     (sscanf(cp, "%3o", &x) == 1)) {
914                                                         c = x;
915                                                         cp += 3;
916                                                 } /* else just do '\\' */
917                                         }
918                                 }
919                                 *p++ = c;
920                                 length++;
921                         }
922                         vp->length = length;
923                         break;
924
925                 case PW_TYPE_IPADDR:
926                         /*
927                          *      It's a comparison, not a real IP.
928                          */
929                         if ((vp->operator == T_OP_REG_EQ) ||
930                             (vp->operator == T_OP_REG_NE)) {
931                                 break;
932                         }
933
934                         /*
935                          *      FIXME: complain if hostname
936                          *      cannot be resolved, or resolve later!
937                          */
938                         s = NULL;
939                         if ((p = strrchr(value, '+')) != NULL && !p[1]) {
940                                 cs = s = strdup(value);
941                                 if (!s) return NULL;
942                                 p = strrchr(s, '+');
943                                 *p = 0;
944                                 vp->flags.addport = 1;
945                         } else {
946                                 p = NULL;
947                                 cs = value;
948                         }
949
950                         {
951                                 fr_ipaddr_t ipaddr;
952
953                                 if (ip_hton(cs, AF_INET, &ipaddr) < 0) {
954                                         free(s);
955                                         fr_strerror_printf("Failed to find IP address for %s", cs);
956                                         return NULL;
957                                 }
958
959                                 vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
960                         }
961                         free(s);
962                         vp->length = 4;
963                         break;
964
965                 case PW_TYPE_BYTE:
966                         vp->length = 1;
967
968                         /*
969                          *      Note that ALL integers are unsigned!
970                          */
971                         vp->vp_integer = getint(value, &p);
972                         if (!*p) {
973                                 if (vp->vp_integer > 255) {
974                                         fr_strerror_printf("Byte value \"%s\" is larger than 255", value);
975                                         return NULL;
976                                 }
977                                 break;
978                         }
979                         if (check_for_whitespace(p)) break;
980                         goto check_for_value;
981
982                 case PW_TYPE_SHORT:
983                         /*
984                          *      Note that ALL integers are unsigned!
985                          */
986                         vp->vp_integer = getint(value, &p);
987                         vp->length = 2;
988                         if (!*p) {
989                                 if (vp->vp_integer > 65535) {
990                                         fr_strerror_printf("Byte value \"%s\" is larger than 65535", value);
991                                         return NULL;
992                                 }
993                                 break;
994                         }
995                         if (check_for_whitespace(p)) break;
996                         goto check_for_value;
997
998                 case PW_TYPE_INTEGER:
999                         /*
1000                          *      Note that ALL integers are unsigned!
1001                          */
1002                         vp->vp_integer = getint(value, &p);
1003                         vp->length = 4;
1004                         if (!*p) break;
1005                         if (check_for_whitespace(p)) break;
1006
1007         check_for_value:
1008                         /*
1009                          *      Look for the named value for the given
1010                          *      attribute.
1011                          */
1012                         if ((dval = dict_valbyname(vp->attribute, vp->vendor, value)) == NULL) {
1013                                 fr_strerror_printf("Unknown value %s for attribute %s",
1014                                            value, vp->name);
1015                                 return NULL;
1016                         }
1017                         vp->vp_integer = dval->value;
1018                         break;
1019
1020                 case PW_TYPE_DATE:
1021                         {
1022                                 /*
1023                                  *      time_t may be 64 bits, whule vp_date
1024                                  *      MUST be 32-bits.  We need an
1025                                  *      intermediary variable to handle
1026                                  *      the conversions.
1027                                  */
1028                                 time_t date;
1029
1030                                 if (gettime(value, &date) < 0) {
1031                                         fr_strerror_printf("failed to parse time string "
1032                                                    "\"%s\"", value);
1033                                         return NULL;
1034                                 }
1035
1036                                 vp->vp_date = date;
1037                         }
1038                         vp->length = 4;
1039                         break;
1040
1041                 case PW_TYPE_ABINARY:
1042 #ifdef ASCEND_BINARY
1043                         if (strncasecmp(value, "0x", 2) == 0) {
1044                                 vp->type = PW_TYPE_OCTETS;
1045                                 goto do_octets;
1046                         }
1047
1048                         if (ascend_parse_filter(vp) < 0 ) {
1049                                 fr_strerror_printf("failed to parse Ascend binary attribute: %s",
1050                                            fr_strerror());
1051                                 return NULL;
1052                         }
1053                         break;
1054
1055                         /*
1056                          *      If Ascend binary is NOT defined,
1057                          *      then fall through to raw octets, so that
1058                          *      the user can at least make them by hand...
1059                          */
1060         do_octets:
1061 #endif
1062                         /* raw octets: 0x01020304... */
1063                 case PW_TYPE_OCTETS:
1064                         if (strncasecmp(value, "0x", 2) == 0) {
1065                                 uint8_t *us;
1066                                 cp = value + 2;
1067                                 us = vp->vp_octets;
1068                                 vp->length = 0;
1069
1070
1071                                 /*
1072                                  *      There is only one character,
1073                                  *      die.
1074                                  */
1075                                 if ((strlen(cp) & 0x01) != 0) {
1076                                         fr_strerror_printf("Hex string is not an even length string.");
1077                                         return NULL;
1078                                 }
1079
1080
1081                                 while (*cp &&
1082                                        (vp->length < MAX_STRING_LEN)) {
1083                                         unsigned int tmp;
1084
1085                                         if (sscanf(cp, "%02x", &tmp) != 1) {
1086                                                 fr_strerror_printf("Non-hex characters at %c%c", cp[0], cp[1]);
1087                                                 return NULL;
1088                                         }
1089
1090                                         cp += 2;
1091                                         *(us++) = tmp;
1092                                         vp->length++;
1093                                 }
1094                         }
1095                         break;
1096
1097                 case PW_TYPE_IFID:
1098                         if (ifid_aton(value, (void *) &vp->vp_ifid) == NULL) {
1099                                 fr_strerror_printf("failed to parse interface-id "
1100                                            "string \"%s\"", value);
1101                                 return NULL;
1102                         }
1103                         vp->length = 8;
1104                         break;
1105
1106                 case PW_TYPE_IPV6ADDR:
1107                         if (inet_pton(AF_INET6, value, &vp->vp_ipv6addr) <= 0) {
1108                                 fr_strerror_printf("failed to parse IPv6 address "
1109                                            "string \"%s\"", value);
1110                                 return NULL;
1111                         }
1112                         vp->length = 16; /* length of IPv6 address */
1113                         break;
1114
1115                 case PW_TYPE_IPV6PREFIX:
1116                         p = strchr(value, '/');
1117                         if (!p || ((p - value) >= 256)) {
1118                                 fr_strerror_printf("invalid IPv6 prefix "
1119                                            "string \"%s\"", value);
1120                                 return NULL;
1121                         } else {
1122                                 unsigned int prefix;
1123                                 char buffer[256], *eptr;
1124
1125                                 memcpy(buffer, value, p - value);
1126                                 buffer[p - value] = '\0';
1127
1128                                 if (inet_pton(AF_INET6, buffer, vp->vp_octets + 2) <= 0) {
1129                                         fr_strerror_printf("failed to parse IPv6 address "
1130                                                    "string \"%s\"", value);
1131                                         return NULL;
1132                                 }
1133
1134                                 prefix = strtoul(p + 1, &eptr, 10);
1135                                 if ((prefix > 128) || *eptr) {
1136                                         fr_strerror_printf("failed to parse IPv6 address "
1137                                                    "string \"%s\"", value);
1138                                         return NULL;
1139                                 }
1140                                 vp->vp_octets[1] = prefix;
1141                         }
1142                         vp->vp_octets[0] = '\0';
1143                         vp->length = 16 + 2;
1144                         break;
1145
1146                 case PW_TYPE_ETHERNET:
1147                         {
1148                                 const char *c1, *c2;
1149
1150                                 length = 0;
1151                                 cp = value;
1152                                 while (*cp) {
1153                                         if (cp[1] == ':') {
1154                                                 c1 = hextab;
1155                                                 c2 = memchr(hextab, tolower((int) cp[0]), 16);
1156                                                 cp += 2;
1157                                         } else if ((cp[1] != '\0') &&
1158                                                    ((cp[2] == ':') ||
1159                                                     (cp[2] == '\0'))) {
1160                                                    c1 = memchr(hextab, tolower((int) cp[0]), 16);
1161                                                    c2 = memchr(hextab, tolower((int) cp[1]), 16);
1162                                                    cp += 2;
1163                                                    if (*cp == ':') cp++;
1164                                         } else {
1165                                                 c1 = c2 = NULL;
1166                                         }
1167                                         if (!c1 || !c2 || (length >= sizeof(vp->vp_ether))) {
1168                                                 fr_strerror_printf("failed to parse Ethernet address \"%s\"", value);
1169                                                 return NULL;
1170                                         }
1171                                         vp->vp_ether[length] = ((c1-hextab)<<4) + (c2-hextab);
1172                                         length++;
1173                                 }
1174                         }
1175                         vp->length = 6;
1176                         break;
1177
1178                 case PW_TYPE_COMBO_IP:
1179                         if (inet_pton(AF_INET6, value, vp->vp_strvalue) > 0) {
1180                                 vp->type = PW_TYPE_IPV6ADDR;
1181                                 vp->length = 16; /* length of IPv6 address */
1182                                 vp->vp_strvalue[vp->length] = '\0';
1183
1184                         } else {
1185                                 fr_ipaddr_t ipaddr;
1186
1187                                 if (ip_hton(value, AF_INET, &ipaddr) < 0) {
1188                                         fr_strerror_printf("Failed to find IPv4 address for %s", value);
1189                                         return NULL;
1190                                 }
1191
1192                                 vp->type = PW_TYPE_IPADDR;
1193                                 vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
1194                                 vp->length = 4;
1195                         }
1196                         break;
1197
1198                 case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
1199                         vp->vp_signed = (int32_t) strtol(value, &p, 10);
1200                         vp->length = 4;
1201                         break;
1202
1203                 case PW_TYPE_TLV: /* don't use this! */
1204                         if (strncasecmp(value, "0x", 2) != 0) {
1205                                 fr_strerror_printf("Invalid TLV specification");
1206                                 return NULL;
1207                         }
1208                         length = strlen(value + 2) / 2;
1209                         if (vp->length < length) {
1210                                 free(vp->vp_tlv);
1211                                 vp->vp_tlv = NULL;
1212                         }
1213                         vp->vp_tlv = malloc(length);
1214                         if (!vp->vp_tlv) {
1215                                 fr_strerror_printf("No memory");
1216                                 return NULL;
1217                         }
1218                         if (fr_hex2bin(value + 2, vp->vp_tlv,
1219                                        length) != length) {
1220                                 fr_strerror_printf("Invalid hex data in TLV");
1221                                 return NULL;
1222                         }
1223                         vp->length = length;
1224                         break;
1225
1226                         /*
1227                          *  Anything else.
1228                          */
1229                 default:
1230                         fr_strerror_printf("unknown attribute type %d", vp->type);
1231                         return NULL;
1232         }
1233
1234         return vp;
1235 }
1236
1237 /*
1238  *      Create a VALUE_PAIR from an ASCII attribute and value,
1239  *      where the attribute name is in the form:
1240  *
1241  *      Attr-%d
1242  *      Vendor-%d-Attr-%d
1243  *      VendorName-Attr-%d
1244  */
1245 static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
1246                                 int operator)
1247 {
1248         int             attr, vendor;
1249         size_t          size;
1250         const char      *p = attribute;
1251         char            *q;
1252         VALUE_PAIR      *vp;
1253
1254         /*
1255          *      Unknown attributes MUST be of type 'octets'
1256          */
1257         if (value && (strncasecmp(value, "0x", 2) != 0)) {
1258                 fr_strerror_printf("Invalid octet string \"%s\" for attribute name \"%s\"", value, attribute);
1259                 return NULL;
1260         }
1261
1262         vendor = 0;
1263
1264         /*
1265          *      Pull off vendor prefix first.
1266          */
1267         if (strncasecmp(p, "Attr-", 5) != 0) {
1268                 if (strncasecmp(p, "Vendor-", 7) == 0) {
1269                         vendor = (int) strtol(p + 7, &q, 10);
1270                         if ((vendor == 0) || (vendor > 65535)) {
1271                                 fr_strerror_printf("Invalid vendor value in attribute name \"%s\"", attribute);
1272                                 return NULL;
1273                         }
1274
1275                         p = q;
1276
1277                 } else {        /* must be vendor name */
1278                         char buffer[256];
1279
1280                         q = strchr(p, '-');
1281
1282                         if (!q) {
1283                                 fr_strerror_printf("Invalid vendor name in attribute name \"%s\"", attribute);
1284                                 return NULL;
1285                         }
1286
1287                         if ((size_t) (q - p) >= sizeof(buffer)) {
1288                                 fr_strerror_printf("Vendor name too long in attribute name \"%s\"", attribute);
1289                                 return NULL;
1290                         }
1291
1292                         memcpy(buffer, p, (q - p));
1293                         buffer[q - p] = '\0';
1294
1295                         vendor = dict_vendorbyname(buffer);
1296                         if (!vendor) {
1297                                 fr_strerror_printf("Unknown vendor name in attribute name \"%s\"", attribute);
1298                                 return NULL;
1299                         }
1300
1301                         p = q;
1302                 }
1303
1304                 if (*p != '-') {
1305                         fr_strerror_printf("Invalid text following vendor definition in attribute name \"%s\"", attribute);
1306                         return NULL;
1307                 }
1308                 p++;
1309         }
1310
1311         /*
1312          *      Attr-%d
1313          */
1314         if (strncasecmp(p, "Attr-", 5) != 0) {
1315                 fr_strerror_printf("Invalid format in attribute name \"%s\"", attribute);
1316                 return NULL;
1317         }
1318
1319         attr = strtol(p + 5, &q, 10);
1320
1321         /*
1322          *      Invalid, or trailing text after number.
1323          */
1324         if ((attr == 0) || *q) {
1325                 fr_strerror_printf("Invalid value in attribute name \"%s\"", attribute);
1326                 return NULL;
1327         }
1328
1329         /*
1330          *      Double-check the size of attr.
1331          */
1332         if (vendor) {
1333                 DICT_VENDOR *dv = dict_vendorbyvalue(vendor);
1334
1335                 if (!dv) {
1336                         if (attr > 255) {
1337                         attr_error:
1338                                 fr_strerror_printf("Invalid attribute number in attribute name \"%s\"", attribute);
1339                                 return NULL;
1340                         }
1341
1342                 } else switch (dv->type) {
1343                         case 1:
1344                                 if (attr > 255) goto attr_error;
1345                                 break;
1346
1347                         case 2:
1348                                 if (attr > 65535) goto attr_error;
1349                                 break;
1350
1351                         case 4: /* Internal limitations! */
1352                                 if (attr > 65535) goto attr_error;
1353                                 break;
1354
1355                         default:
1356                                 fr_strerror_printf("Internal sanity check failed");
1357                                 return NULL;
1358                 }
1359         }
1360
1361         /*
1362          *      We've now parsed the attribute properly, Let's create
1363          *      it.  This next stop also looks the attribute up in the
1364          *      dictionary, and creates the appropriate type for it.
1365          */
1366         if ((vp = paircreate(attr, vendor, PW_TYPE_OCTETS)) == NULL) {
1367                 fr_strerror_printf("out of memory");
1368                 return NULL;
1369         }
1370
1371         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1372         if (!value) return vp;
1373
1374         size = strlen(value + 2);
1375
1376         /*
1377          *      We may be reading something like Attr-5.  i.e.
1378          *      who-ever wrote the text didn't understand it, but we
1379          *      do.
1380          */
1381         switch (vp->type) {
1382         default:
1383                 if (size == (vp->length * 2)) break;
1384                 vp->type = PW_TYPE_OCTETS;
1385                 /* FALL-THROUGH */
1386                 
1387         case PW_TYPE_STRING:
1388         case PW_TYPE_OCTETS:
1389         case PW_TYPE_ABINARY:
1390                 vp->length = size >> 1;
1391                 break;
1392         }
1393
1394         if (fr_hex2bin(value + 2, vp->vp_octets, size) != vp->length) {
1395                 fr_strerror_printf("Invalid hex string");
1396                 free(vp);
1397                 return NULL;
1398         }
1399
1400         /*
1401          *      Move contents around based on type.  This is
1402          *      to work around the historical use of "lvalue".
1403          */
1404         switch (vp->type) {
1405         case PW_TYPE_DATE:
1406         case PW_TYPE_IPADDR:
1407         case PW_TYPE_INTEGER:
1408                 memcpy(&vp->lvalue, vp->vp_octets, sizeof(vp->lvalue));
1409                 vp->vp_strvalue[0] = '\0';
1410                 break;
1411                 
1412         default:
1413                 break;
1414         }
1415        
1416         return vp;
1417 }
1418
1419
1420 /*
1421  *      Create a VALUE_PAIR from an ASCII attribute and value.
1422  */
1423 VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
1424 {
1425         DICT_ATTR       *da;
1426         VALUE_PAIR      *vp;
1427         char            *tc, *ts;
1428         signed char     tag;
1429         int             found_tag;
1430         char            buffer[64];
1431         const char      *attrname = attribute;
1432
1433         /*
1434          *    Check for tags in 'Attribute:Tag' format.
1435          */
1436         found_tag = 0;
1437         tag = 0;
1438
1439         ts = strrchr(attribute, ':');
1440         if (ts && !ts[1]) {
1441                 fr_strerror_printf("Invalid tag for attribute %s", attribute);
1442                 return NULL;
1443         }
1444
1445         if (ts && ts[1]) {
1446                 strlcpy(buffer, attribute, sizeof(buffer));
1447                 attrname = buffer;
1448                 ts = strrchr(attrname, ':');
1449
1450                  /* Colon found with something behind it */
1451                  if (ts[1] == '*' && ts[2] == 0) {
1452                          /* Wildcard tag for check items */
1453                          tag = TAG_ANY;
1454                          *ts = 0;
1455                  } else if ((ts[1] >= '0') && (ts[1] <= '9')) {
1456                          /* It's not a wild card tag */
1457                          tag = strtol(ts + 1, &tc, 0);
1458                          if (tc && !*tc && TAG_VALID_ZERO(tag))
1459                                  *ts = 0;
1460                          else tag = 0;
1461                  } else {
1462                          fr_strerror_printf("Invalid tag for attribute %s", attribute);
1463                          return NULL;
1464                  }
1465                  found_tag = 1;
1466         }
1467
1468         /*
1469          *      It's not found in the dictionary, so we use
1470          *      another method to create the attribute.
1471          */
1472         if ((da = dict_attrbyname(attrname)) == NULL) {
1473                 return pairmake_any(attrname, value, operator);
1474         }
1475
1476         if ((vp = pairalloc(da)) == NULL) {
1477                 fr_strerror_printf("out of memory");
1478                 return NULL;
1479         }
1480         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1481
1482         /*      Check for a tag in the 'Merit' format of:
1483          *      :Tag:Value.  Print an error if we already found
1484          *      a tag in the Attribute.
1485          */
1486
1487         if (value && (*value == ':' && da->flags.has_tag)) {
1488                 /* If we already found a tag, this is invalid */
1489                 if(found_tag) {
1490                         fr_strerror_printf("Duplicate tag %s for attribute %s",
1491                                    value, vp->name);
1492                         DEBUG("Duplicate tag %s for attribute %s\n",
1493                                    value, vp->name);
1494                         pairbasicfree(vp);
1495                         return NULL;
1496                 }
1497                 /* Colon found and attribute allows a tag */
1498                 if (value[1] == '*' && value[2] == ':') {
1499                        /* Wildcard tag for check items */
1500                        tag = TAG_ANY;
1501                        value += 3;
1502                 } else {
1503                        /* Real tag */
1504                        tag = strtol(value + 1, &tc, 0);
1505                        if (tc && *tc==':' && TAG_VALID_ZERO(tag))
1506                             value = tc + 1;
1507                        else tag = 0;
1508                 }
1509                 found_tag = 1;
1510         }
1511
1512         if (found_tag) {
1513           vp->flags.tag = tag;
1514         }
1515
1516         switch (vp->operator) {
1517         default:
1518                 break;
1519
1520                 /*
1521                  *      For =* and !* operators, the value is irrelevant
1522                  *      so we return now.
1523                  */
1524         case T_OP_CMP_TRUE:
1525         case T_OP_CMP_FALSE:
1526                 vp->vp_strvalue[0] = '\0';
1527                 vp->length = 0;
1528                 return vp;
1529                 break;
1530
1531                 /*
1532                  *      Regular expression comparison of integer attributes
1533                  *      does a STRING comparison of the names of their
1534                  *      integer attributes.
1535                  */
1536         case T_OP_REG_EQ:       /* =~ */
1537         case T_OP_REG_NE:       /* !~ */
1538                 if (!value) {
1539                         fr_strerror_printf("No regular expression found in %s",
1540                                            vp->name);
1541                         pairbasicfree(vp);
1542                         return NULL;
1543                 }
1544           
1545                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1546                 vp->length = strlen(vp->vp_strvalue);
1547                 /*
1548                  *      If anything goes wrong, this is a run-time error,
1549                  *      not a compile-time error.
1550                  */
1551                 return vp;
1552
1553         }
1554
1555         /*
1556          *      FIXME: if (strcasecmp(attribute, vp->name) != 0)
1557          *      then the user MAY have typed in the attribute name
1558          *      as Vendor-%d-Attr-%d, and the value MAY be octets.
1559          *
1560          *      We probably want to fix pairparsevalue to accept
1561          *      octets as values for any attribute.
1562          */
1563         if (value && (pairparsevalue(vp, value) == NULL)) {
1564                 pairbasicfree(vp);
1565                 return NULL;
1566         }
1567
1568         return vp;
1569 }
1570
1571
1572 /*
1573  *      [a-zA-Z0-9_-:]+
1574  */
1575 static const int valid_attr_name[256] = {
1576         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1577         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1578         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1579         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1580         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1581         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
1582         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1583         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1584         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1585         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1586         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1587         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1588         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1589         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1590         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1591         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1592 };
1593
1594 /*
1595  *      Read a valuepair from a buffer, and advance pointer.
1596  *      Sets *eol to T_EOL if end of line was encountered.
1597  */
1598 VALUE_PAIR *pairread(const char **ptr, FR_TOKEN *eol)
1599 {
1600         char            buf[64];
1601         char            attr[64];
1602         char            value[1024], *q;
1603         const char      *p;
1604         FR_TOKEN        token, t, xlat;
1605         VALUE_PAIR      *vp;
1606         size_t          len;
1607
1608         *eol = T_OP_INVALID;
1609
1610         p = *ptr;
1611         while ((*p == ' ') || (*p == '\t')) p++;
1612
1613         if (!*p) {
1614                 *eol = T_OP_INVALID;
1615                 fr_strerror_printf("No token read where we expected an attribute name");
1616                 return NULL;
1617         }
1618
1619         if (*p == '#') {
1620                 *eol = T_HASH;
1621                 fr_strerror_printf("Read a comment instead of a token");
1622                 return NULL;
1623         }
1624
1625         q = attr;
1626         for (len = 0; len < sizeof(attr); len++) {
1627                 if (valid_attr_name[(int)*p]) {
1628                         *q++ = *p++;
1629                         continue;
1630                 }
1631                 break;
1632         }
1633
1634         if (len == sizeof(attr)) {
1635                 *eol = T_OP_INVALID;
1636                 fr_strerror_printf("Attribute name is too long");
1637                 return NULL;
1638         }
1639
1640         /*
1641          *      We may have Foo-Bar:= stuff, so back up.
1642          */
1643         if ((len > 0) && (attr[len - 1] == ':')) {
1644                 p--;
1645                 len--;
1646         }
1647
1648         attr[len] = '\0';
1649         *ptr = p;
1650
1651         /* Now we should have an operator here. */
1652         token = gettoken(ptr, buf, sizeof(buf));
1653         if (token < T_EQSTART || token > T_EQEND) {
1654                 fr_strerror_printf("expecting operator");
1655                 return NULL;
1656         }
1657
1658         /* Read value.  Note that empty string values are allowed */
1659         xlat = gettoken(ptr, value, sizeof(value));
1660         if (xlat == T_EOL) {
1661                 fr_strerror_printf("failed to get value");
1662                 return NULL;
1663         }
1664
1665         /*
1666          *      Peek at the next token. Must be T_EOL, T_COMMA, or T_HASH
1667          */
1668         p = *ptr;
1669         t = gettoken(&p, buf, sizeof(buf));
1670         if (t != T_EOL && t != T_COMMA && t != T_HASH) {
1671                 fr_strerror_printf("Expected end of line or comma");
1672                 return NULL;
1673         }
1674
1675         *eol = t;
1676         if (t == T_COMMA) {
1677                 *ptr = p;
1678         }
1679
1680         vp = NULL;
1681         switch (xlat) {
1682                 /*
1683                  *      Make the full pair now.
1684                  */
1685         default:
1686                 vp = pairmake(attr, value, token);
1687                 break;
1688
1689                 /*
1690                  *      Perhaps do xlat's
1691                  */
1692         case T_DOUBLE_QUOTED_STRING:
1693                 p = strchr(value, '%');
1694                 if (p && (p[1] == '{')) {
1695                         if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1696                                 fr_strerror_printf("Value too long");
1697                                 return NULL;
1698                         }
1699                         vp = pairmake(attr, NULL, token);
1700                         if (!vp) {
1701                                 *eol = T_OP_INVALID;
1702                                 return NULL;
1703                         }
1704
1705                         strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1706                         vp->flags.do_xlat = 1;
1707                         vp->length = 0;
1708                 } else {
1709                         /*
1710                          *      Parse && escape it, as defined by the
1711                          *      data type.
1712                          */
1713                         vp = pairmake(attr, value, token);
1714                         if (!vp) {
1715                                 *eol = T_OP_INVALID;
1716                                 return NULL;
1717                         }
1718                 }
1719                 break;
1720
1721         case T_SINGLE_QUOTED_STRING:
1722                 vp = pairmake(attr, NULL, token);
1723                 if (!vp) {
1724                         *eol = T_OP_INVALID;
1725                         return NULL;
1726                 }
1727
1728                 /*
1729                  *      String and octet types get copied verbatim.
1730                  */
1731                 if ((vp->type == PW_TYPE_STRING) ||
1732                     (vp->type == PW_TYPE_OCTETS)) {
1733                         strlcpy(vp->vp_strvalue, value,
1734                                 sizeof(vp->vp_strvalue));
1735                         vp->length = strlen(vp->vp_strvalue);
1736
1737                         /*
1738                          *      Everything else gets parsed: it's
1739                          *      DATA, not a string!
1740                          */
1741                 } else if (!pairparsevalue(vp, value)) {
1742                         pairfree(&vp);
1743                         *eol = T_OP_INVALID;
1744                         return NULL;
1745                 }
1746                 break;
1747
1748                 /*
1749                  *      Mark the pair to be allocated later.
1750                  */
1751         case T_BACK_QUOTED_STRING:
1752                 if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1753                         fr_strerror_printf("Value too long");
1754                         return NULL;
1755                 }
1756
1757                 vp = pairmake(attr, NULL, token);
1758                 if (!vp) {
1759                         *eol = T_OP_INVALID;
1760                         return NULL;
1761                 }
1762
1763                 vp->flags.do_xlat = 1;
1764                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1765                 vp->length = 0;
1766                 break;
1767         }
1768
1769         /*
1770          *      If we didn't make a pair, return an error.
1771          */
1772         if (!vp) {
1773                 *eol = T_OP_INVALID;
1774                 return NULL;
1775         }
1776
1777         return vp;
1778 }
1779
1780 /*
1781  *      Read one line of attribute/value pairs. This might contain
1782  *      multiple pairs seperated by comma's.
1783  */
1784 FR_TOKEN userparse(const char *buffer, VALUE_PAIR **first_pair)
1785 {
1786         VALUE_PAIR      *vp;
1787         const char      *p;
1788         FR_TOKEN        last_token = T_OP_INVALID;
1789         FR_TOKEN        previous_token;
1790
1791         /*
1792          *      We allow an empty line.
1793          */
1794         if (buffer[0] == 0)
1795                 return T_EOL;
1796
1797         p = buffer;
1798         do {
1799                 previous_token = last_token;
1800                 if ((vp = pairread(&p, &last_token)) == NULL) {
1801                         return last_token;
1802                 }
1803                 pairadd(first_pair, vp);
1804         } while (*p && (last_token == T_COMMA));
1805
1806         /*
1807          *      Don't tell the caller that there was a comment.
1808          */
1809         if (last_token == T_HASH) {
1810                 return previous_token;
1811         }
1812
1813         /*
1814          *      And return the last token which we read.
1815          */
1816         return last_token;
1817 }
1818
1819 /*
1820  *      Read valuepairs from the fp up to End-Of-File.
1821  *
1822  *      Hmm... this function is only used by radclient..
1823  */
1824 VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix)
1825 {
1826         char buf[8192];
1827         FR_TOKEN last_token = T_EOL;
1828         VALUE_PAIR *vp;
1829         VALUE_PAIR *list;
1830         int error = 0;
1831
1832         list = NULL;
1833
1834         while (!error && fgets(buf, sizeof(buf), fp) != NULL) {
1835                 /*
1836                  *      If we get a '\n' by itself, we assume that's
1837                  *      the end of that VP
1838                  */
1839                 if ((buf[0] == '\n') && (list)) {
1840                         return list;
1841                 }
1842                 if ((buf[0] == '\n') && (!list)) {
1843                         continue;
1844                 }
1845
1846                 /*
1847                  *      Comments get ignored
1848                  */
1849                 if (buf[0] == '#') continue;
1850
1851                 /*
1852                  *      Read all of the attributes on the current line.
1853                  */
1854                 vp = NULL;
1855                 last_token = userparse(buf, &vp);
1856                 if (!vp) {
1857                         if (last_token != T_EOL) {
1858                                 fr_perror("%s", errprefix);
1859                                 error = 1;
1860                                 break;
1861                         }
1862                         break;
1863                 }
1864
1865                 pairadd(&list, vp);
1866                 buf[0] = '\0';
1867         }
1868
1869         if (error) pairfree(&list);
1870
1871         *pfiledone = 1;
1872
1873         return error ? NULL: list;
1874 }
1875
1876
1877
1878 /*
1879  *      Compare two pairs, using the operator from "one".
1880  *
1881  *      i.e. given two attributes, it does:
1882  *
1883  *      (two->data) (one->operator) (one->data)
1884  *
1885  *      e.g. "foo" != "bar"
1886  *
1887  *      Returns true (comparison is true), or false (comparison is not true);
1888  *
1889  *      FIXME: Ignores tags!
1890  */
1891 int paircmp(VALUE_PAIR *one, VALUE_PAIR *two)
1892 {
1893         int compare;
1894
1895         switch (one->operator) {
1896         case T_OP_CMP_TRUE:
1897                 return (two != NULL);
1898
1899         case T_OP_CMP_FALSE:
1900                 return (two == NULL);
1901
1902                 /*
1903                  *      One is a regex, compile it, print two to a string,
1904                  *      and then do string comparisons.
1905                  */
1906         case T_OP_REG_EQ:
1907         case T_OP_REG_NE:
1908 #ifndef HAVE_REGEX_H
1909                 return -1;
1910 #else
1911                 {
1912                         regex_t reg;
1913                         char buffer[MAX_STRING_LEN * 4 + 1];
1914
1915                         compare = regcomp(&reg, one->vp_strvalue,
1916                                           REG_EXTENDED);
1917                         if (compare != 0) {
1918                                 regerror(compare, &reg, buffer, sizeof(buffer));
1919                                 fr_strerror_printf("Illegal regular expression in attribute: %s: %s",
1920                                            one->name, buffer);
1921                                 return -1;
1922                         }
1923
1924                         vp_prints_value(buffer, sizeof(buffer), two, 0);
1925
1926                         /*
1927                          *      Don't care about substring matches,
1928                          *      oh well...
1929                          */
1930                         compare = regexec(&reg, buffer, 0, NULL, 0);
1931
1932                         regfree(&reg);
1933                         if (one->operator == T_OP_REG_EQ) return (compare == 0);
1934                         return (compare != 0);
1935                 }
1936 #endif
1937
1938         default:                /* we're OK */
1939                 break;
1940         }
1941
1942         /*
1943          *      After doing the previous check for special comparisons,
1944          *      do the per-type comparison here.
1945          */
1946         switch (one->type) {
1947         case PW_TYPE_ABINARY:
1948         case PW_TYPE_OCTETS:
1949         {
1950                 size_t length;
1951
1952                 if (one->length < two->length) {
1953                         length = one->length;
1954                 } else {
1955                         length = two->length;
1956                 }
1957
1958                 if (length) {
1959                         compare = memcmp(two->vp_octets, one->vp_octets,
1960                                          length);
1961                         if (compare != 0) break;
1962                 }
1963
1964                 /*
1965                  *      Contents are the same.  The return code
1966                  *      is therefore the difference in lengths.
1967                  *
1968                  *      i.e. "0x00" is smaller than "0x0000"
1969                  */
1970                 compare = two->length - one->length;
1971         }
1972                 break;
1973
1974         case PW_TYPE_STRING:
1975                 compare = strcmp(two->vp_strvalue, one->vp_strvalue);
1976                 break;
1977
1978         case PW_TYPE_BYTE:
1979         case PW_TYPE_SHORT:
1980         case PW_TYPE_INTEGER:
1981         case PW_TYPE_DATE:
1982                 compare = two->vp_integer - one->vp_integer;
1983                 break;
1984
1985         case PW_TYPE_IPADDR:
1986                 compare = ntohl(two->vp_ipaddr) - ntohl(one->vp_ipaddr);
1987                 break;
1988
1989         case PW_TYPE_IPV6ADDR:
1990                 compare = memcmp(&two->vp_ipv6addr, &one->vp_ipv6addr,
1991                                  sizeof(two->vp_ipv6addr));
1992                 break;
1993
1994         case PW_TYPE_IPV6PREFIX:
1995                 compare = memcmp(&two->vp_ipv6prefix, &one->vp_ipv6prefix,
1996                                  sizeof(two->vp_ipv6prefix));
1997                 break;
1998
1999         case PW_TYPE_IFID:
2000                 compare = memcmp(&two->vp_ifid, &one->vp_ifid,
2001                                  sizeof(two->vp_ifid));
2002                 break;
2003
2004         default:
2005                 return 0;       /* unknown type */
2006         }
2007
2008         /*
2009          *      Now do the operator comparison.
2010          */
2011         switch (one->operator) {
2012         case T_OP_CMP_EQ:
2013                 return (compare == 0);
2014
2015         case T_OP_NE:
2016                 return (compare != 0);
2017
2018         case T_OP_LT:
2019                 return (compare < 0);
2020
2021         case T_OP_GT:
2022                 return (compare > 0);
2023
2024         case T_OP_LE:
2025                 return (compare <= 0);
2026
2027         case T_OP_GE:
2028                 return (compare >= 0);
2029
2030         default:
2031                 return 0;
2032         }
2033
2034         return 0;
2035 }