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