docs: fixed minor typo
[netsniff-ng.git] / src / aslookup.c
blob4583175800724b7a72b040e51646f48e95818ea8
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <netdb.h>
13 #include <assert.h>
14 #include <netinet/in.h>
16 #include "die.h"
17 #include "xstring.h"
18 #include "aslookup.h"
19 #include "xmalloc.h"
21 static int ai_family = 0;
22 static int ai_socktype = 0;
23 static int ai_protocol = 0;
24 static struct sockaddr_storage ai_ss;
26 int aslookup_prepare(const char *server, const char *port)
28 int ret, fd = -1, try = 1;
29 struct addrinfo hints, *ahead, *ai;
30 struct sockaddr_in6 *saddr6;
32 assert(server && port);
33 memset(&ai_ss, 0, sizeof(ai_ss));
35 memset(&hints, 0, sizeof(hints));
36 hints.ai_family = PF_UNSPEC;
37 hints.ai_socktype = SOCK_STREAM;
38 hints.ai_protocol = IPPROTO_TCP;
39 hints.ai_flags = AI_NUMERICSERV;
41 /* This function is really fucked up and seems to have high-stack
42 * usage since it provokes segfaults in some situations when it is
43 * directly included in aslookup! */
44 ret = getaddrinfo(server, port, &hints, &ahead);
45 if (ret != 0) {
46 whine("Cannot get address info!\n");
47 return -EIO;
50 for (ai = ahead; ai != NULL && fd < 0; ai = ai->ai_next) {
51 if (ai->ai_family == PF_INET6)
52 saddr6 = (struct sockaddr_in6 *) ai->ai_addr;
53 fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
54 if (fd < 0)
55 continue;
56 ret = connect(fd, ai->ai_addr, ai->ai_addrlen);
57 if (ret < 0) {
58 whine("Cannot connect to remote, try %d: %s!\n",
59 try++, strerror(errno));
60 close(fd);
61 fd = -1;
62 continue;
65 ai_family = ai->ai_family;
66 ai_socktype = ai->ai_socktype;
67 ai_protocol = ai->ai_protocol;
68 memcpy(&ai_ss, ai->ai_addr, ai->ai_addrlen);
70 close(fd);
71 break;
74 freeaddrinfo(ahead);
75 return 0;
78 int aslookup(const char *lhost, struct asrecord *rec)
80 int ret, err, fd = -1;
81 char *buff;
82 size_t len = 1024;
84 assert(strlen(lhost) + 8 < len);
86 fd = socket(ai_family, ai_socktype, ai_protocol);
87 if (fd < 0)
88 return -EIO;
89 ret = connect(fd, (struct sockaddr *) &ai_ss, sizeof(ai_ss));
90 if (ret < 0)
91 return -EIO;
93 buff = xzmalloc(len);
94 slprintf(buff, len, "-v -f %s\r\n", lhost);
96 err = write(fd, buff, strlen(buff));
97 if (unlikely(err < 0)) {
98 whine("Cannot write to socket!\n");
99 close(fd);
100 xfree(buff);
101 return err;
104 memset(buff, 0, len);
105 while ((err = read(fd, buff, len)) > 0) {
106 int state = 0, i;
107 char *ptr = skips(buff), *ptr2;
108 for (i = 0; i < len; ++i) {
109 if (buff[i] == '|' && state == 0) {
110 buff[i] = 0;
111 ptr2 = &buff[i] - 1;
112 while (*ptr2 == ' ' && ptr2 > ptr) {
113 *ptr2 = 0;
114 ptr2--;
116 strlcpy(rec->number, ptr, strlen(ptr) + 1);
117 ptr = skips(&buff[i] + 1);
118 state = 1;
119 } else if (buff[i] == '|' && state == 1) {
120 buff[i] = 0;
121 ptr2 = &buff[i] - 1;
122 while (*ptr2 == ' ' && ptr2 > ptr) {
123 *ptr2 = 0;
124 ptr2--;
126 strlcpy(rec->ip, ptr, strlen(ptr) + 1);
127 ptr = skips(&buff[i] + 1);
128 state = 2;
129 } else if (buff[i] == '|' && state == 2) {
130 buff[i] = 0;
131 ptr2 = &buff[i] - 1;
132 while (*ptr2 == ' ' && ptr2 > ptr) {
133 *ptr2 = 0;
134 ptr2--;
136 strlcpy(rec->prefix, ptr, strlen(ptr) + 1);
137 ptr = skips(&buff[i] + 1);
138 state = 3;
139 } else if (buff[i] == '|' && state == 3) {
140 buff[i] = 0;
141 ptr2 = &buff[i] - 1;
142 while (*ptr2 == ' ' && ptr2 > ptr) {
143 *ptr2 = 0;
144 ptr2--;
146 strlcpy(rec->country, ptr, strlen(ptr) + 1);
147 ptr = skips(&buff[i] + 1);
148 state = 4;
149 } else if (buff[i] == '|' && state == 4) {
150 buff[i] = 0;
151 ptr2 = &buff[i] - 1;
152 while (*ptr2 == ' ' && ptr2 > ptr) {
153 *ptr2 = 0;
154 ptr2--;
156 strlcpy(rec->registry, ptr, strlen(ptr) + 1);
157 ptr = skips(&buff[i] + 1);
158 state = 5;
159 } else if (buff[i] == '|' && state == 5) {
160 buff[i] = 0;
161 ptr2 = &buff[i] - 1;
162 while (*ptr2 == ' ' && ptr2 > ptr) {
163 *ptr2 = 0;
164 ptr2--;
166 strlcpy(rec->since, ptr, strlen(ptr) + 1);
167 ptr = skips(&buff[i] + 1);
168 state = 6;
169 } else if (buff[i] == '\n' && state == 6) {
170 buff[i] = 0;
171 ptr2 = &buff[i] - 1;
172 while (*ptr2 == ' ' && ptr2 > ptr) {
173 *ptr2 = 0;
174 ptr2--;
176 strlcpy(rec->name, ptr, strlen(ptr) + 1);
177 goto out;
180 memset(buff, 0, len);
182 out:
183 close(fd);
184 xfree(buff);
185 return 0;