1 /*
2 ** Copyright 1998 - 2000 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 #include	"config.h"
7 #include	"rfc1035.h"
8 #include	"spf.h"
9 #include	<sys/types.h>
10 #include	<stdio.h>
11 #include	<stdlib.h>
12 #include	<string.h>
13 #include	<errno.h>
14 #include	<arpa/inet.h>
15 
16 #include	"soxwrap/soxwrap.h"
17 #include	"rfc1035_res.h"
18 
19 static const char rcsid[]="$Id: testlookup.c,v 1.11 2004/08/15 16:41:02 mrsam Exp $";
20 
setns(const char * p)21 static void setns(const char *p)
22 {
23 #if	RFC1035_IPV6
24 struct in6_addr ia[4];
25 #else
26 struct in_addr ia[4];
27 #endif
28 int	i=0;
29 char	*q=malloc(strlen(p)+1), *r;
30 
31 	strcpy(q, p);
32 	for (r=q; (r=strtok(r, ", ")) != 0; r=0)
33 		if (i < 4)
34 			if (rfc1035_aton(r, &ia[i]) == 0)
35 				++i;
36 
37 	rfc1035_init_ns(&rfc1035_default_resolver, ia, i);
38 }
39 
40 extern char rfc1035_spf_gettxt(const char *current_domain,
41 			       char *buf);
42 
spflookup(const char * current_domain)43 static void spflookup(const char *current_domain)
44 {
45 	char buf[256];
46 
47 	switch (rfc1035_spf_gettxt(current_domain, buf)) {
48 	case SPF_NONE:
49 		printf("none\n");
50 		return;
51 	case SPF_NEUTRAL:
52 		printf("neutral\n");
53 		return;
54 	case SPF_PASS:
55 		printf("pass: %s\n", buf);
56 		return;
57 	case SPF_FAIL:
58 		printf("fail\n");
59 		return;
60 	case SPF_SOFTFAIL:
61 		printf("softfail\n");
62 		return;
63 	case SPF_ERROR:
64 		printf("error\n");
65 		return;
66 	default:
67 		printf("unknown\n");
68 	}
69 }
70 
main(int argc,char ** argv)71 int main(int argc, char **argv)
72 {
73 struct	rfc1035_reply *replyp;
74 int	argn;
75 const char *q_name;
76 int	q_type;
77 int	q_class;
78 int	q_xflag=0;
79 int	q_rflag=0;
80 char	ptrbuf[RFC1035_MAXNAMESIZE+1];
81 
82 	argn=1;
83 	while (argn < argc)
84 	{
85 		if (argv[argn][0] == '@')
86 		{
87 			setns(argv[argn]+1);
88 			++argn;
89 			continue;
90 		}
91 
92 		if (strcmp(argv[argn], "-x") == 0)
93 		{
94 			q_xflag=1;
95 			++argn;
96 			continue;
97 		}
98 		if (strcmp(argv[argn], "-r") == 0)
99 		{
100 			q_rflag=1;
101 			++argn;
102 			continue;
103 		}
104 		break;
105 	}
106 
107 	if (argn >= argc)	exit(0);
108 
109 	q_name=argv[argn++];
110 
111 	if (q_xflag)
112 	{
113 	struct in_addr ia;
114 #if	RFC1035_IPV6
115 	struct in6_addr ia6;
116 
117 		if (inet_pton(AF_INET6, q_name, &ia6) > 0)
118 		{
119 		const char *sin6=(const char *)&ia6;
120 		unsigned i;
121 
122 			ptrbuf[0]=0;
123 
124 			for (i=sizeof(struct in6_addr); i; )
125 			{
126 			char    buf[10];
127 
128 				--i;
129 				sprintf(buf, "%x.%x.",
130 					(int)(unsigned char)(sin6[i] & 0x0F),
131 					(int)(unsigned char)((sin6[i] >> 4)
132 							& 0x0F));
133 				strcat(ptrbuf, buf);
134 			}
135 			strcat(ptrbuf, "ip6.arpa");
136 			q_name=ptrbuf;
137 		}
138 		else
139 #endif
140 		if ( rfc1035_aton_ipv4(q_name, &ia) == 0)
141 		{
142 		char buf[RFC1035_MAXNAMESIZE];
143 		unsigned char a=0,b=0,c=0,d=0;
144 		const char *p=buf;
145 
146 			rfc1035_ntoa_ipv4(&ia, buf);
147 
148 			while (*p >= '0' && *p <= '9')
149 				a= (int)a * 10 + (*p++ - '0');
150 			if (*p)	p++;
151 			while (*p >= '0' && *p <= '9')
152 				b= (int)b * 10 + (*p++ - '0');
153 			if (*p)	p++;
154 			while (*p >= '0' && *p <= '9')
155 				c= (int)c * 10 + (*p++ - '0');
156 			if (*p)	p++;
157 			while (*p >= '0' && *p <= '9')
158 				d= (int)d * 10 + (*p++ - '0');
159 
160 			sprintf(ptrbuf, "%d.%d.%d.%d.in-addr.arpa",
161 				(int)d, (int)c, (int)b, (int)a);
162 			q_name=ptrbuf;
163 		}
164 	}
165 
166 	if (q_rflag)
167 	{
168 	RFC1035_ADDR a;
169 	int	rc;
170 
171 		if (rfc1035_aton(q_name, &a) == 0)
172 		{
173 			rc=rfc1035_ptr(&rfc1035_default_resolver,
174 				&a, ptrbuf);
175 			if (rc == 0)
176 			{
177 				printf("%s\n", ptrbuf);
178 				exit(0);
179 			}
180 		}
181 		else
182 		{
183 		RFC1035_ADDR	*aptr;
184 		unsigned alen;
185 
186 			rc=rfc1035_a(&rfc1035_default_resolver, q_name,
187 				&aptr, &alen);
188 			if (rc == 0)
189 			{
190 			unsigned i;
191 
192 				for (i=0; i<alen; i++)
193 				{
194 					rfc1035_ntoa(&aptr[i], ptrbuf);
195 					printf("%s\n", ptrbuf);
196 				}
197 				exit(0);
198 			}
199 		}
200 		fprintf(stderr, "%s error.\n", errno == ENOENT ? "Hard":"Soft");
201 		exit(1);
202 	}
203 
204 	q_type= -1;
205 
206 	if (argn < argc)
207 	{
208 		if (strcmp(argv[argn], "spf") == 0)
209 			q_type= -2;
210 		else
211 			q_type=rfc1035_type_strtoi(argv[argn++]);
212 	}
213 
214 	if (q_type == -1)
215 		q_type=q_xflag ? RFC1035_TYPE_PTR:RFC1035_TYPE_ANY;
216 
217 	q_class= -1;
218 	if (argn < argc)
219 		q_class=rfc1035_class_strtoi(argv[argn]);
220 	if (q_class < 0)
221 		q_class=RFC1035_CLASS_IN;
222 
223 	if (q_type == -2)
224 	{
225 		spflookup(q_name);
226 		exit(0);
227 	}
228 
229 	replyp=rfc1035_resolve(&rfc1035_default_resolver,
230 		RFC1035_OPCODE_QUERY, 1, q_name, q_type, q_class);
231 
232 	if (!replyp)
233 	{
234 		perror(argv[0]);
235 		exit(1);
236 	}
237 
238 	rfc1035_dump(replyp, stdout);
239 	rfc1035_replyfree(replyp);
240 	return (0);
241 }
242