17c478bd9Sstevel@tonic-gate /*
2*4e567b44SStacey Marshall  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
37c478bd9Sstevel@tonic-gate  */
47c478bd9Sstevel@tonic-gate 
59525b14bSRao Shoaib 
67c478bd9Sstevel@tonic-gate /*
79525b14bSRao Shoaib  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
87c478bd9Sstevel@tonic-gate  * Copyright (c) 1995-1999 by Internet Software Consortium.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
117c478bd9Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
127c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies.
137c478bd9Sstevel@tonic-gate  *
149525b14bSRao Shoaib  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
159525b14bSRao Shoaib  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
169525b14bSRao Shoaib  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
179525b14bSRao Shoaib  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
189525b14bSRao Shoaib  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
199525b14bSRao Shoaib  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
209525b14bSRao Shoaib  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate #include "port_before.h"
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #include <sys/types.h>
267c478bd9Sstevel@tonic-gate #include <sys/param.h>
277c478bd9Sstevel@tonic-gate #include <sys/socket.h>
287c478bd9Sstevel@tonic-gate #include <sys/time.h>
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <netinet/in.h>
317c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
327c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <ctype.h>
357c478bd9Sstevel@tonic-gate #include <netdb.h>
367c478bd9Sstevel@tonic-gate #include <resolv.h>
377c478bd9Sstevel@tonic-gate #include <res_update.h>
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <stdlib.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate #include <unistd.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #include "port_after.h"
447c478bd9Sstevel@tonic-gate 
459525b14bSRao Shoaib #ifndef	ORIGINAL_ISC_CODE
467c478bd9Sstevel@tonic-gate #pragma weak	__fp_nquery	=	fp_nquery
477c478bd9Sstevel@tonic-gate #pragma weak	__fp_query	=	fp_query
487c478bd9Sstevel@tonic-gate #pragma weak	__p_query	=	p_query
497c478bd9Sstevel@tonic-gate #pragma weak	__hostalias	=	hostalias
509525b14bSRao Shoaib #pragma weak	__res_randomid	=	res_randomid
517c478bd9Sstevel@tonic-gate #endif
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate const char *_res_opcodes[] = {
547c478bd9Sstevel@tonic-gate 	"QUERY",
557c478bd9Sstevel@tonic-gate 	"IQUERY",
567c478bd9Sstevel@tonic-gate 	"CQUERYM",
579525b14bSRao Shoaib 	"CQUERYU",	/*%< experimental */
589525b14bSRao Shoaib 	"NOTIFY",	/*%< experimental */
597c478bd9Sstevel@tonic-gate 	"UPDATE",
607c478bd9Sstevel@tonic-gate 	"6",
617c478bd9Sstevel@tonic-gate 	"7",
627c478bd9Sstevel@tonic-gate 	"8",
637c478bd9Sstevel@tonic-gate 	"9",
647c478bd9Sstevel@tonic-gate 	"10",
657c478bd9Sstevel@tonic-gate 	"11",
667c478bd9Sstevel@tonic-gate 	"12",
677c478bd9Sstevel@tonic-gate 	"13",
687c478bd9Sstevel@tonic-gate 	"ZONEINIT",
697c478bd9Sstevel@tonic-gate 	"ZONEREF",
707c478bd9Sstevel@tonic-gate };
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate #ifdef BIND_UPDATE
737c478bd9Sstevel@tonic-gate const char *_res_sectioncodes[] = {
747c478bd9Sstevel@tonic-gate 	"ZONE",
757c478bd9Sstevel@tonic-gate 	"PREREQUISITES",
767c478bd9Sstevel@tonic-gate 	"UPDATE",
777c478bd9Sstevel@tonic-gate 	"ADDITIONAL",
787c478bd9Sstevel@tonic-gate };
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate 
819525b14bSRao Shoaib #undef _res
827c478bd9Sstevel@tonic-gate #ifndef __BIND_NOSTATIC
837c478bd9Sstevel@tonic-gate struct __res_state _res
847c478bd9Sstevel@tonic-gate # if defined(__BIND_RES_TEXT)
859525b14bSRao Shoaib 	= { RES_TIMEOUT, }	/*%< Motorola, et al. */
867c478bd9Sstevel@tonic-gate # endif
877c478bd9Sstevel@tonic-gate         ;
887c478bd9Sstevel@tonic-gate 
89*4e567b44SStacey Marshall #ifdef	ORIGINAL_ISC_CODE
909525b14bSRao Shoaib #if defined(DO_PTHREADS) || defined(__linux)
919525b14bSRao Shoaib #define _res (*__res_state())
929525b14bSRao Shoaib #endif
93*4e567b44SStacey Marshall #endif
949525b14bSRao Shoaib 
957c478bd9Sstevel@tonic-gate /* Proto. */
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate int  res_ourserver_p(const res_state, const struct sockaddr_in *);
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate int
res_init(void)1007c478bd9Sstevel@tonic-gate res_init(void) {
1017c478bd9Sstevel@tonic-gate 	extern int __res_vinit(res_state, int);
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	/*
1047c478bd9Sstevel@tonic-gate 	 * These three fields used to be statically initialized.  This made
1057c478bd9Sstevel@tonic-gate 	 * it hard to use this code in a shared library.  It is necessary,
1067c478bd9Sstevel@tonic-gate 	 * now that we're doing dynamic initialization here, that we preserve
1077c478bd9Sstevel@tonic-gate 	 * the old semantics: if an application modifies one of these three
1087c478bd9Sstevel@tonic-gate 	 * fields of _res before res_init() is called, res_init() will not
1097c478bd9Sstevel@tonic-gate 	 * alter them.  Of course, if an application is setting them to
1107c478bd9Sstevel@tonic-gate 	 * _zero_ before calling res_init(), hoping to override what used
1117c478bd9Sstevel@tonic-gate 	 * to be the static default, we can't detect it and unexpected results
1127c478bd9Sstevel@tonic-gate 	 * will follow.  Zero for any of these fields would make no sense,
1137c478bd9Sstevel@tonic-gate 	 * so one can safely assume that the applications were already getting
1147c478bd9Sstevel@tonic-gate 	 * unexpected results.
1157c478bd9Sstevel@tonic-gate 	 *
1167c478bd9Sstevel@tonic-gate 	 * _res.options is tricky since some apps were known to diddle the bits
1177c478bd9Sstevel@tonic-gate 	 * before res_init() was first called. We can't replicate that semantic
1187c478bd9Sstevel@tonic-gate 	 * with dynamic initialization (they may have turned bits off that are
1197c478bd9Sstevel@tonic-gate 	 * set in RES_DEFAULT).  Our solution is to declare such applications
1207c478bd9Sstevel@tonic-gate 	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
1217c478bd9Sstevel@tonic-gate 	 */
1227c478bd9Sstevel@tonic-gate 	if (!_res.retrans)
1237c478bd9Sstevel@tonic-gate 		_res.retrans = RES_TIMEOUT;
1247c478bd9Sstevel@tonic-gate 	if (!_res.retry)
1257c478bd9Sstevel@tonic-gate 		_res.retry = 4;
1267c478bd9Sstevel@tonic-gate 	if (!(_res.options & RES_INIT))
1277c478bd9Sstevel@tonic-gate 		_res.options = RES_DEFAULT;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	/*
1307c478bd9Sstevel@tonic-gate 	 * This one used to initialize implicitly to zero, so unless the app
1317c478bd9Sstevel@tonic-gate 	 * has set it to something in particular, we can randomize it now.
1327c478bd9Sstevel@tonic-gate 	 */
1337c478bd9Sstevel@tonic-gate 	if (!_res.id)
1349525b14bSRao Shoaib 		_res.id = res_nrandomid(&_res);
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	return (__res_vinit(&_res, 1));
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate void
p_query(const u_char * msg)1407c478bd9Sstevel@tonic-gate p_query(const u_char *msg) {
1417c478bd9Sstevel@tonic-gate 	fp_query(msg, stdout);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate void
fp_query(const u_char * msg,FILE * file)1457c478bd9Sstevel@tonic-gate fp_query(const u_char *msg, FILE *file) {
1467c478bd9Sstevel@tonic-gate 	fp_nquery(msg, PACKETSZ, file);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate void
fp_nquery(const u_char * msg,int len,FILE * file)1507c478bd9Sstevel@tonic-gate fp_nquery(const u_char *msg, int len, FILE *file) {
1519525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1)
1527c478bd9Sstevel@tonic-gate 		return;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	res_pquery(&_res, msg, len, file);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate int
res_mkquery(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)1589525b14bSRao Shoaib res_mkquery(int op,			/*!< opcode of query  */
1599525b14bSRao Shoaib 	    const char *dname,		/*!< domain name  */
1609525b14bSRao Shoaib 	    int class, int type,	/*!< class and type of query  */
1619525b14bSRao Shoaib 	    const u_char *data,		/*!< resource record data  */
1629525b14bSRao Shoaib 	    int datalen,		/*!< length of data  */
1639525b14bSRao Shoaib 	    const u_char *newrr_in,	/*!< new rr for modify or append  */
1649525b14bSRao Shoaib 	    u_char *buf,		/*!< buffer to put query  */
1659525b14bSRao Shoaib 	    int buflen)			/*!< size of buffer  */
1667c478bd9Sstevel@tonic-gate {
1679525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1687c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1697c478bd9Sstevel@tonic-gate 		return (-1);
1707c478bd9Sstevel@tonic-gate 	}
1717c478bd9Sstevel@tonic-gate 	return (res_nmkquery(&_res, op, dname, class, type,
1727c478bd9Sstevel@tonic-gate 			     data, datalen,
1737c478bd9Sstevel@tonic-gate 			     newrr_in, buf, buflen));
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate int
res_mkupdate(ns_updrec * rrecp_in,u_char * buf,int buflen)1777c478bd9Sstevel@tonic-gate res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
1789525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1797c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1807c478bd9Sstevel@tonic-gate 		return (-1);
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate int
res_query(const char * name,int class,int type,u_char * answer,int anslen)1879525b14bSRao Shoaib res_query(const char *name,	/*!< domain name  */
1889525b14bSRao Shoaib 	  int class, int type,	/*!< class and type of query  */
1899525b14bSRao Shoaib 	  u_char *answer,	/*!< buffer to put answer  */
1909525b14bSRao Shoaib 	  int anslen)		/*!< size of answer buffer  */
1917c478bd9Sstevel@tonic-gate {
1929525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1937c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1947c478bd9Sstevel@tonic-gate 		return (-1);
1957c478bd9Sstevel@tonic-gate 	}
1967c478bd9Sstevel@tonic-gate 	return (res_nquery(&_res, name, class, type, answer, anslen));
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate void
res_send_setqhook(res_send_qhook hook)2007c478bd9Sstevel@tonic-gate res_send_setqhook(res_send_qhook hook) {
2017c478bd9Sstevel@tonic-gate 	_res.qhook = hook;
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate void
res_send_setrhook(res_send_rhook hook)2057c478bd9Sstevel@tonic-gate res_send_setrhook(res_send_rhook hook) {
2067c478bd9Sstevel@tonic-gate 	_res.rhook = hook;
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate int
res_isourserver(const struct sockaddr_in * inp)2107c478bd9Sstevel@tonic-gate res_isourserver(const struct sockaddr_in *inp) {
2117c478bd9Sstevel@tonic-gate 	return (res_ourserver_p(&_res, inp));
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate int
res_send(const u_char * buf,int buflen,u_char * ans,int anssiz)2157c478bd9Sstevel@tonic-gate res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
2169525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2177c478bd9Sstevel@tonic-gate 		/* errno should have been set by res_init() in this case. */
2187c478bd9Sstevel@tonic-gate 		return (-1);
2197c478bd9Sstevel@tonic-gate 	}
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	return (res_nsend(&_res, buf, buflen, ans, anssiz));
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate int
res_sendsigned(const u_char * buf,int buflen,ns_tsig_key * key,u_char * ans,int anssiz)2257c478bd9Sstevel@tonic-gate res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
2267c478bd9Sstevel@tonic-gate 	       u_char *ans, int anssiz)
2277c478bd9Sstevel@tonic-gate {
2289525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2297c478bd9Sstevel@tonic-gate 		/* errno should have been set by res_init() in this case. */
2307c478bd9Sstevel@tonic-gate 		return (-1);
2317c478bd9Sstevel@tonic-gate 	}
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate void
res_close(void)2377c478bd9Sstevel@tonic-gate res_close(void) {
2387c478bd9Sstevel@tonic-gate 	res_nclose(&_res);
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate int
res_update(ns_updrec * rrecp_in)2427c478bd9Sstevel@tonic-gate res_update(ns_updrec *rrecp_in) {
2439525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2447c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2457c478bd9Sstevel@tonic-gate 		return (-1);
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	return (res_nupdate(&_res, rrecp_in, NULL));
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate int
res_search(const char * name,int class,int type,u_char * answer,int anslen)2529525b14bSRao Shoaib res_search(const char *name,	/*!< domain name  */
2539525b14bSRao Shoaib 	   int class, int type,	/*!< class and type of query  */
2549525b14bSRao Shoaib 	   u_char *answer,	/*!< buffer to put answer  */
2559525b14bSRao Shoaib 	   int anslen)		/*!< size of answer  */
2567c478bd9Sstevel@tonic-gate {
2579525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2587c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2597c478bd9Sstevel@tonic-gate 		return (-1);
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 	return (res_nsearch(&_res, name, class, type, answer, anslen));
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate int
res_querydomain(const char * name,const char * domain,int class,int type,u_char * answer,int anslen)2667c478bd9Sstevel@tonic-gate res_querydomain(const char *name,
2677c478bd9Sstevel@tonic-gate 		const char *domain,
2689525b14bSRao Shoaib 		int class, int type,	/*!< class and type of query  */
2699525b14bSRao Shoaib 		u_char *answer,		/*!< buffer to put answer  */
2709525b14bSRao Shoaib 		int anslen)		/*!< size of answer  */
2717c478bd9Sstevel@tonic-gate {
2729525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2737c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2747c478bd9Sstevel@tonic-gate 		return (-1);
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	return (res_nquerydomain(&_res, name, domain,
2787c478bd9Sstevel@tonic-gate 				 class, type,
2797c478bd9Sstevel@tonic-gate 				 answer, anslen));
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate 
2829525b14bSRao Shoaib u_int
res_randomid(void)2839525b14bSRao Shoaib res_randomid(void) {
2849525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2859525b14bSRao Shoaib 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2869525b14bSRao Shoaib 		return (-1);
2879525b14bSRao Shoaib 	}
2889525b14bSRao Shoaib 
2899525b14bSRao Shoaib 	return (res_nrandomid(&_res));
2909525b14bSRao Shoaib }
2919525b14bSRao Shoaib 
2927c478bd9Sstevel@tonic-gate const char *
hostalias(const char * name)2937c478bd9Sstevel@tonic-gate hostalias(const char *name) {
2947c478bd9Sstevel@tonic-gate 	static char abuf[MAXDNAME];
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	return (res_hostalias(&_res, name, abuf, sizeof abuf));
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate #ifdef ultrix
3007c478bd9Sstevel@tonic-gate int
local_hostname_length(const char * hostname)3017c478bd9Sstevel@tonic-gate local_hostname_length(const char *hostname) {
3027c478bd9Sstevel@tonic-gate 	int len_host, len_domain;
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	if (!*_res.defdname)
3057c478bd9Sstevel@tonic-gate 		res_init();
3067c478bd9Sstevel@tonic-gate 	len_host = strlen(hostname);
3077c478bd9Sstevel@tonic-gate 	len_domain = strlen(_res.defdname);
3087c478bd9Sstevel@tonic-gate 	if (len_host > len_domain &&
3097c478bd9Sstevel@tonic-gate 	    !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
3107c478bd9Sstevel@tonic-gate 	    hostname[len_host - len_domain - 1] == '.')
3117c478bd9Sstevel@tonic-gate 		return (len_host - len_domain - 1);
3127c478bd9Sstevel@tonic-gate 	return (0);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate #endif /*ultrix*/
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate #endif
3179525b14bSRao Shoaib 
3189525b14bSRao Shoaib /*! \file */
319