xref: /freebsd/lib/libc/resolv/res_mkquery.c (revision dc36d6f9)
16e778a7eSPedro F. Giffuni /*-
26e778a7eSPedro F. Giffuni  * SPDX-License-Identifier: (ISC AND BSD-3-Clause)
36e778a7eSPedro F. Giffuni  *
4046c3635SPedro F. Giffuni  * Portions Copyright (C) 2004, 2005, 2008  Internet Systems Consortium, Inc. ("ISC")
5046c3635SPedro F. Giffuni  * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003  Internet Software Consortium.
6046c3635SPedro F. Giffuni  *
7046c3635SPedro F. Giffuni  * Permission to use, copy, modify, and/or distribute this software for any
8046c3635SPedro F. Giffuni  * purpose with or without fee is hereby granted, provided that the above
9046c3635SPedro F. Giffuni  * copyright notice and this permission notice appear in all copies.
10046c3635SPedro F. Giffuni  *
11046c3635SPedro F. Giffuni  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12046c3635SPedro F. Giffuni  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13046c3635SPedro F. Giffuni  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14046c3635SPedro F. Giffuni  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15046c3635SPedro F. Giffuni  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16046c3635SPedro F. Giffuni  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17046c3635SPedro F. Giffuni  * PERFORMANCE OF THIS SOFTWARE.
18046c3635SPedro F. Giffuni  */
19046c3635SPedro F. Giffuni 
208a16b7a1SPedro F. Giffuni /*-
2165e96449SHajimu UMEMOTO  * Copyright (c) 1985, 1993
2265e96449SHajimu UMEMOTO  *    The Regents of the University of California.  All rights reserved.
2365e96449SHajimu UMEMOTO  *
2465e96449SHajimu UMEMOTO  * Redistribution and use in source and binary forms, with or without
2565e96449SHajimu UMEMOTO  * modification, are permitted provided that the following conditions
2665e96449SHajimu UMEMOTO  * are met:
2765e96449SHajimu UMEMOTO  * 1. Redistributions of source code must retain the above copyright
2865e96449SHajimu UMEMOTO  *    notice, this list of conditions and the following disclaimer.
2965e96449SHajimu UMEMOTO  * 2. Redistributions in binary form must reproduce the above copyright
3065e96449SHajimu UMEMOTO  *    notice, this list of conditions and the following disclaimer in the
3165e96449SHajimu UMEMOTO  *    documentation and/or other materials provided with the distribution.
32fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
3365e96449SHajimu UMEMOTO  *    may be used to endorse or promote products derived from this software
3465e96449SHajimu UMEMOTO  *    without specific prior written permission.
3565e96449SHajimu UMEMOTO  *
3665e96449SHajimu UMEMOTO  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3765e96449SHajimu UMEMOTO  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3865e96449SHajimu UMEMOTO  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3965e96449SHajimu UMEMOTO  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4065e96449SHajimu UMEMOTO  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4165e96449SHajimu UMEMOTO  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4265e96449SHajimu UMEMOTO  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4365e96449SHajimu UMEMOTO  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4465e96449SHajimu UMEMOTO  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4565e96449SHajimu UMEMOTO  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4665e96449SHajimu UMEMOTO  * SUCH DAMAGE.
4765e96449SHajimu UMEMOTO  */
4865e96449SHajimu UMEMOTO 
4965e96449SHajimu UMEMOTO /*
5065e96449SHajimu UMEMOTO  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
5165e96449SHajimu UMEMOTO  *
5265e96449SHajimu UMEMOTO  * Permission to use, copy, modify, and distribute this software for any
5365e96449SHajimu UMEMOTO  * purpose with or without fee is hereby granted, provided that the above
5465e96449SHajimu UMEMOTO  * copyright notice and this permission notice appear in all copies, and that
5565e96449SHajimu UMEMOTO  * the name of Digital Equipment Corporation not be used in advertising or
5665e96449SHajimu UMEMOTO  * publicity pertaining to distribution of the document or software without
5765e96449SHajimu UMEMOTO  * specific, written prior permission.
5865e96449SHajimu UMEMOTO  *
5965e96449SHajimu UMEMOTO  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
6065e96449SHajimu UMEMOTO  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
6165e96449SHajimu UMEMOTO  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
6265e96449SHajimu UMEMOTO  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
6365e96449SHajimu UMEMOTO  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
6465e96449SHajimu UMEMOTO  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
6565e96449SHajimu UMEMOTO  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
6665e96449SHajimu UMEMOTO  * SOFTWARE.
6765e96449SHajimu UMEMOTO  */
6865e96449SHajimu UMEMOTO 
6965e96449SHajimu UMEMOTO #include "port_before.h"
7065e96449SHajimu UMEMOTO #include <sys/param.h>
7165e96449SHajimu UMEMOTO #include <netinet/in.h>
7265e96449SHajimu UMEMOTO #include <arpa/nameser.h>
7365e96449SHajimu UMEMOTO #include <netdb.h>
7465e96449SHajimu UMEMOTO #include <resolv.h>
7565e96449SHajimu UMEMOTO #include <stdio.h>
7665e96449SHajimu UMEMOTO #include <string.h>
7765e96449SHajimu UMEMOTO #include "port_after.h"
7865e96449SHajimu UMEMOTO 
7965e96449SHajimu UMEMOTO /* Options.  Leave them on. */
808a615d0fSEnji Cooper #ifndef	DEBUG
8165e96449SHajimu UMEMOTO #define	DEBUG
828a615d0fSEnji Cooper #endif
8365e96449SHajimu UMEMOTO 
8465e96449SHajimu UMEMOTO extern const char *_res_opcodes[];
8565e96449SHajimu UMEMOTO 
86dde4a85dSHajimu UMEMOTO /*%
8765e96449SHajimu UMEMOTO  * Form all types of queries.
8865e96449SHajimu UMEMOTO  * Returns the size of the result or -1.
8965e96449SHajimu UMEMOTO  */
9065e96449SHajimu UMEMOTO int
res_nmkquery(res_state statp,int op,const char * dname,int class,int type,const u_char * data,int datalen,const u_char * newrr_in,u_char * buf,int buflen)9165e96449SHajimu UMEMOTO res_nmkquery(res_state statp,
92dde4a85dSHajimu UMEMOTO 	     int op,			/*!< opcode of query  */
93dde4a85dSHajimu UMEMOTO 	     const char *dname,		/*!< domain name  */
94dde4a85dSHajimu UMEMOTO 	     int class, int type,	/*!< class and type of query  */
95dde4a85dSHajimu UMEMOTO 	     const u_char *data,	/*!< resource record data  */
96dde4a85dSHajimu UMEMOTO 	     int datalen,		/*!< length of data  */
97dde4a85dSHajimu UMEMOTO 	     const u_char *newrr_in,	/*!< new rr for modify or append  */
98dde4a85dSHajimu UMEMOTO 	     u_char *buf,		/*!< buffer to put query  */
99dde4a85dSHajimu UMEMOTO 	     int buflen)		/*!< size of buffer  */
10065e96449SHajimu UMEMOTO {
101ab96eeabSHajimu UMEMOTO 	HEADER *hp;
102ab96eeabSHajimu UMEMOTO 	u_char *cp, *ep;
103ab96eeabSHajimu UMEMOTO 	int n;
10465e96449SHajimu UMEMOTO 	u_char *dnptrs[20], **dpp, **lastdnptr;
10565e96449SHajimu UMEMOTO 
10665e96449SHajimu UMEMOTO 	UNUSED(newrr_in);
10765e96449SHajimu UMEMOTO 
10865e96449SHajimu UMEMOTO #ifdef DEBUG
10965e96449SHajimu UMEMOTO 	if (statp->options & RES_DEBUG)
11065e96449SHajimu UMEMOTO 		printf(";; res_nmkquery(%s, %s, %s, %s)\n",
11165e96449SHajimu UMEMOTO 		       _res_opcodes[op], dname, p_class(class), p_type(type));
11265e96449SHajimu UMEMOTO #endif
11365e96449SHajimu UMEMOTO 	/*
11465e96449SHajimu UMEMOTO 	 * Initialize header fields.
11565e96449SHajimu UMEMOTO 	 */
11665e96449SHajimu UMEMOTO 	if ((buf == NULL) || (buflen < HFIXEDSZ))
11765e96449SHajimu UMEMOTO 		return (-1);
11865e96449SHajimu UMEMOTO 	memset(buf, 0, HFIXEDSZ);
11965e96449SHajimu UMEMOTO 	hp = (HEADER *) buf;
120046c3635SPedro F. Giffuni 	statp->id = res_nrandomid(statp);
121046c3635SPedro F. Giffuni 	hp->id = htons(statp->id);
12265e96449SHajimu UMEMOTO 	hp->opcode = op;
12365e96449SHajimu UMEMOTO 	hp->rd = (statp->options & RES_RECURSE) != 0U;
12465e96449SHajimu UMEMOTO 	hp->rcode = NOERROR;
12565e96449SHajimu UMEMOTO 	cp = buf + HFIXEDSZ;
12665e96449SHajimu UMEMOTO 	ep = buf + buflen;
12765e96449SHajimu UMEMOTO 	dpp = dnptrs;
12865e96449SHajimu UMEMOTO 	*dpp++ = buf;
12965e96449SHajimu UMEMOTO 	*dpp++ = NULL;
130bf51882aSPedro F. Giffuni 	lastdnptr = dnptrs + nitems(dnptrs);
13165e96449SHajimu UMEMOTO 	/*
13265e96449SHajimu UMEMOTO 	 * perform opcode specific processing
13365e96449SHajimu UMEMOTO 	 */
13465e96449SHajimu UMEMOTO 	switch (op) {
13565e96449SHajimu UMEMOTO 	case QUERY:	/*FALLTHROUGH*/
13665e96449SHajimu UMEMOTO 	case NS_NOTIFY_OP:
13765e96449SHajimu UMEMOTO 		if (ep - cp < QFIXEDSZ)
13865e96449SHajimu UMEMOTO 			return (-1);
13965e96449SHajimu UMEMOTO 		if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
14065e96449SHajimu UMEMOTO 		    lastdnptr)) < 0)
14165e96449SHajimu UMEMOTO 			return (-1);
14265e96449SHajimu UMEMOTO 		cp += n;
14365e96449SHajimu UMEMOTO 		ns_put16(type, cp);
14465e96449SHajimu UMEMOTO 		cp += INT16SZ;
14565e96449SHajimu UMEMOTO 		ns_put16(class, cp);
14665e96449SHajimu UMEMOTO 		cp += INT16SZ;
14765e96449SHajimu UMEMOTO 		hp->qdcount = htons(1);
14865e96449SHajimu UMEMOTO 		if (op == QUERY || data == NULL)
14965e96449SHajimu UMEMOTO 			break;
15065e96449SHajimu UMEMOTO 		/*
15165e96449SHajimu UMEMOTO 		 * Make an additional record for completion domain.
15265e96449SHajimu UMEMOTO 		 */
15365e96449SHajimu UMEMOTO 		if ((ep - cp) < RRFIXEDSZ)
15465e96449SHajimu UMEMOTO 			return (-1);
15565e96449SHajimu UMEMOTO 		n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
15665e96449SHajimu UMEMOTO 			    dnptrs, lastdnptr);
15765e96449SHajimu UMEMOTO 		if (n < 0)
15865e96449SHajimu UMEMOTO 			return (-1);
15965e96449SHajimu UMEMOTO 		cp += n;
16065e96449SHajimu UMEMOTO 		ns_put16(T_NULL, cp);
16165e96449SHajimu UMEMOTO 		cp += INT16SZ;
16265e96449SHajimu UMEMOTO 		ns_put16(class, cp);
16365e96449SHajimu UMEMOTO 		cp += INT16SZ;
16465e96449SHajimu UMEMOTO 		ns_put32(0, cp);
16565e96449SHajimu UMEMOTO 		cp += INT32SZ;
16665e96449SHajimu UMEMOTO 		ns_put16(0, cp);
16765e96449SHajimu UMEMOTO 		cp += INT16SZ;
16865e96449SHajimu UMEMOTO 		hp->arcount = htons(1);
16965e96449SHajimu UMEMOTO 		break;
17065e96449SHajimu UMEMOTO 
17165e96449SHajimu UMEMOTO 	case IQUERY:
17265e96449SHajimu UMEMOTO 		/*
17365e96449SHajimu UMEMOTO 		 * Initialize answer section
17465e96449SHajimu UMEMOTO 		 */
17565e96449SHajimu UMEMOTO 		if (ep - cp < 1 + RRFIXEDSZ + datalen)
17665e96449SHajimu UMEMOTO 			return (-1);
177dde4a85dSHajimu UMEMOTO 		*cp++ = '\0';	/*%< no domain name */
17865e96449SHajimu UMEMOTO 		ns_put16(type, cp);
17965e96449SHajimu UMEMOTO 		cp += INT16SZ;
18065e96449SHajimu UMEMOTO 		ns_put16(class, cp);
18165e96449SHajimu UMEMOTO 		cp += INT16SZ;
18265e96449SHajimu UMEMOTO 		ns_put32(0, cp);
18365e96449SHajimu UMEMOTO 		cp += INT32SZ;
18465e96449SHajimu UMEMOTO 		ns_put16(datalen, cp);
18565e96449SHajimu UMEMOTO 		cp += INT16SZ;
18665e96449SHajimu UMEMOTO 		if (datalen) {
18765e96449SHajimu UMEMOTO 			memcpy(cp, data, datalen);
18865e96449SHajimu UMEMOTO 			cp += datalen;
18965e96449SHajimu UMEMOTO 		}
19065e96449SHajimu UMEMOTO 		hp->ancount = htons(1);
19165e96449SHajimu UMEMOTO 		break;
19265e96449SHajimu UMEMOTO 
19365e96449SHajimu UMEMOTO 	default:
19465e96449SHajimu UMEMOTO 		return (-1);
19565e96449SHajimu UMEMOTO 	}
19665e96449SHajimu UMEMOTO 	return (cp - buf);
19765e96449SHajimu UMEMOTO }
19865e96449SHajimu UMEMOTO 
19965e96449SHajimu UMEMOTO #ifdef RES_USE_EDNS0
20065e96449SHajimu UMEMOTO /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
20165e96449SHajimu UMEMOTO 
20265e96449SHajimu UMEMOTO int
res_nopt(res_state statp,int n0,u_char * buf,int buflen,int anslen)20365e96449SHajimu UMEMOTO res_nopt(res_state statp,
204dde4a85dSHajimu UMEMOTO 	 int n0,		/*%< current offset in buffer */
205dde4a85dSHajimu UMEMOTO 	 u_char *buf,		/*%< buffer to put query */
206dde4a85dSHajimu UMEMOTO 	 int buflen,		/*%< size of buffer */
207dde4a85dSHajimu UMEMOTO 	 int anslen)		/*%< UDP answer buffer size */
20865e96449SHajimu UMEMOTO {
209ab96eeabSHajimu UMEMOTO 	HEADER *hp;
210ab96eeabSHajimu UMEMOTO 	u_char *cp, *ep;
21165e96449SHajimu UMEMOTO 	u_int16_t flags = 0;
21265e96449SHajimu UMEMOTO 
21365e96449SHajimu UMEMOTO #ifdef DEBUG
21465e96449SHajimu UMEMOTO 	if ((statp->options & RES_DEBUG) != 0U)
21565e96449SHajimu UMEMOTO 		printf(";; res_nopt()\n");
21665e96449SHajimu UMEMOTO #endif
21765e96449SHajimu UMEMOTO 
21865e96449SHajimu UMEMOTO 	hp = (HEADER *) buf;
21965e96449SHajimu UMEMOTO 	cp = buf + n0;
22065e96449SHajimu UMEMOTO 	ep = buf + buflen;
22165e96449SHajimu UMEMOTO 
22265e96449SHajimu UMEMOTO 	if ((ep - cp) < 1 + RRFIXEDSZ)
22365e96449SHajimu UMEMOTO 		return (-1);
22465e96449SHajimu UMEMOTO 
225dde4a85dSHajimu UMEMOTO 	*cp++ = 0;				/*%< "." */
22654ebdd63SHajimu UMEMOTO 	ns_put16(ns_t_opt, cp);			/*%< TYPE */
22765e96449SHajimu UMEMOTO 	cp += INT16SZ;
228ab96eeabSHajimu UMEMOTO 	if (anslen > 0xffff)
229ab96eeabSHajimu UMEMOTO 		anslen = 0xffff;		/* limit to 16bit value */
230dde4a85dSHajimu UMEMOTO 	ns_put16(anslen & 0xffff, cp);		/*%< CLASS = UDP payload size */
23165e96449SHajimu UMEMOTO 	cp += INT16SZ;
232dde4a85dSHajimu UMEMOTO 	*cp++ = NOERROR;			/*%< extended RCODE */
233dde4a85dSHajimu UMEMOTO 	*cp++ = 0;				/*%< EDNS version */
23454ebdd63SHajimu UMEMOTO 
23565e96449SHajimu UMEMOTO 	if (statp->options & RES_USE_DNSSEC) {
23665e96449SHajimu UMEMOTO #ifdef DEBUG
23765e96449SHajimu UMEMOTO 		if (statp->options & RES_DEBUG)
23865e96449SHajimu UMEMOTO 			printf(";; res_opt()... ENDS0 DNSSEC\n");
23965e96449SHajimu UMEMOTO #endif
24065e96449SHajimu UMEMOTO 		flags |= NS_OPT_DNSSEC_OK;
24165e96449SHajimu UMEMOTO 	}
24265e96449SHajimu UMEMOTO 	ns_put16(flags, cp);
24365e96449SHajimu UMEMOTO 	cp += INT16SZ;
24454ebdd63SHajimu UMEMOTO 
24554ebdd63SHajimu UMEMOTO 	ns_put16(0U, cp);			/*%< RDLEN */
24665e96449SHajimu UMEMOTO 	cp += INT16SZ;
24754ebdd63SHajimu UMEMOTO 
24865e96449SHajimu UMEMOTO 	hp->arcount = htons(ntohs(hp->arcount) + 1);
24965e96449SHajimu UMEMOTO 
25065e96449SHajimu UMEMOTO 	return (cp - buf);
25165e96449SHajimu UMEMOTO }
25254ebdd63SHajimu UMEMOTO 
25354ebdd63SHajimu UMEMOTO /*
254b4ce0ff1SGordon Bergling  * Construct variable data (RDATA) block for OPT pseudo-RR, append it
25554ebdd63SHajimu UMEMOTO  * to the buffer, then update the RDLEN field (previously set to zero by
25654ebdd63SHajimu UMEMOTO  * res_nopt()) with the new RDATA length.
25754ebdd63SHajimu UMEMOTO  */
25854ebdd63SHajimu UMEMOTO int
res_nopt_rdata(res_state statp,int n0,u_char * buf,int buflen,u_char * rdata,u_short code,u_short len,u_char * data)25954ebdd63SHajimu UMEMOTO res_nopt_rdata(res_state statp,
26054ebdd63SHajimu UMEMOTO 	  int n0,	 	/*%< current offset in buffer */
26154ebdd63SHajimu UMEMOTO 	  u_char *buf,	 	/*%< buffer to put query */
26254ebdd63SHajimu UMEMOTO 	  int buflen,		/*%< size of buffer */
26354ebdd63SHajimu UMEMOTO 	  u_char *rdata,	/*%< ptr to start of opt rdata */
26454ebdd63SHajimu UMEMOTO 	  u_short code,		/*%< OPTION-CODE */
26554ebdd63SHajimu UMEMOTO 	  u_short len,		/*%< OPTION-LENGTH */
26654ebdd63SHajimu UMEMOTO 	  u_char *data)		/*%< OPTION_DATA */
26754ebdd63SHajimu UMEMOTO {
26854ebdd63SHajimu UMEMOTO 	register u_char *cp, *ep;
26954ebdd63SHajimu UMEMOTO 
27054ebdd63SHajimu UMEMOTO #ifdef DEBUG
27154ebdd63SHajimu UMEMOTO 	if ((statp->options & RES_DEBUG) != 0U)
27254ebdd63SHajimu UMEMOTO 		printf(";; res_nopt_rdata()\n");
27354ebdd63SHajimu UMEMOTO #endif
27454ebdd63SHajimu UMEMOTO 
27554ebdd63SHajimu UMEMOTO 	cp = buf + n0;
27654ebdd63SHajimu UMEMOTO 	ep = buf + buflen;
27754ebdd63SHajimu UMEMOTO 
27854ebdd63SHajimu UMEMOTO 	if ((ep - cp) < (4 + len))
27954ebdd63SHajimu UMEMOTO 		return (-1);
28054ebdd63SHajimu UMEMOTO 
28154ebdd63SHajimu UMEMOTO 	if (rdata < (buf + 2) || rdata >= ep)
28254ebdd63SHajimu UMEMOTO 		return (-1);
28354ebdd63SHajimu UMEMOTO 
28454ebdd63SHajimu UMEMOTO 	ns_put16(code, cp);
28554ebdd63SHajimu UMEMOTO 	cp += INT16SZ;
28654ebdd63SHajimu UMEMOTO 
28754ebdd63SHajimu UMEMOTO 	ns_put16(len, cp);
28854ebdd63SHajimu UMEMOTO 	cp += INT16SZ;
28954ebdd63SHajimu UMEMOTO 
29054ebdd63SHajimu UMEMOTO 	memcpy(cp, data, len);
29154ebdd63SHajimu UMEMOTO 	cp += len;
29254ebdd63SHajimu UMEMOTO 
29354ebdd63SHajimu UMEMOTO 	len = cp - rdata;
29454ebdd63SHajimu UMEMOTO 	ns_put16(len, rdata - 2);	/* Update RDLEN field */
29554ebdd63SHajimu UMEMOTO 
29654ebdd63SHajimu UMEMOTO 	return (cp - buf);
29754ebdd63SHajimu UMEMOTO }
29865e96449SHajimu UMEMOTO #endif
299dde4a85dSHajimu UMEMOTO 
300dde4a85dSHajimu UMEMOTO /*! \file */
301