1 /*
2 ** ident.c High-level calls to the ident lib
3 **
4 ** Author: P�r Emanuelsson <pell@lysator.liu.se>
5 ** Hacked by: Peter Eriksson <pen@lysator.liu.se>
6 ** Updated by: R�mi Denis-Courmont <rdenis@simphalempin.com>
7 */
8
9 #if HAVE_CONFIG_H
10 # include "config.h"
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17
18 #if HAVE_SYS_TYPES_H
19 # include <sys/types.h>
20 #endif
21 #if HAVE_SYS_SOCKET_H
22 # include <sys/socket.h>
23 #endif
24 #if HAVE_NETINET_IN_H
25 # include <netinet/in.h>
26 #endif
27
28 #define IN_LIBIDENT_SRC
29 #include "ident.h"
30
31
32
33
34
35 /* Do a complete ident query and return result */
36
ident_lookup(int fd,int timeout)37 IDENT *ident_lookup (int fd, int timeout)
38 {
39 struct sockaddr_storage localaddr, remoteaddr;
40 int len;
41
42 len = sizeof(remoteaddr);
43 if (getpeername(fd, (struct sockaddr*)&remoteaddr, &len) < 0)
44 return 0;
45
46 len = sizeof(localaddr);
47 if (getsockname(fd, (struct sockaddr *)&localaddr, &len) < 0)
48 return 0;
49
50 return ident_query_addr((struct sockaddr *)&localaddr,
51 (struct sockaddr *)&remoteaddr, timeout);
52 }
53
54
ident_query(const struct in_addr * laddr,const struct in_addr * faddr,int lport,int rport,int timeout)55 IDENT *ident_query (const struct in_addr *laddr, const struct in_addr *faddr,
56 int lport, int rport, int timeout)
57 {
58 struct sockaddr_in lsockaddr, fsockaddr;
59
60 memset(&lsockaddr, 0, sizeof(lsockaddr));
61 lsockaddr.sin_family = AF_INET;
62 #if HAVE_SA_LEN
63 lsockaddr.sin_len = sizeof(lsockaddr);
64 #endif
65 lsockaddr.sin_addr.s_addr = laddr->s_addr;
66 lsockaddr.sin_port = lport;
67
68 memcpy(&fsockaddr, &lsockaddr, sizeof(fsockaddr));
69 fsockaddr.sin_addr.s_addr = faddr->s_addr;
70 fsockaddr.sin_port = rport;
71
72 return ident_query_addr((struct sockaddr *)&lsockaddr,
73 (struct sockaddr *)&fsockaddr, timeout);
74 }
75
ident_query_addr(const struct sockaddr * laddr,const struct sockaddr * raddr,int timeout)76 IDENT *ident_query_addr (const struct sockaddr *laddr,
77 const struct sockaddr *raddr, int timeout)
78 {
79 int res, lport, rport;
80 ident_t *id;
81 struct timeval timout;
82 IDENT *ident = NULL;
83
84 switch (laddr->sa_family)
85 {
86 case AF_INET:
87 /* We assume that both addresses are in the same family. */
88 lport = ntohs(((struct sockaddr_in *)laddr)->sin_port);
89 rport = ntohs(((struct sockaddr_in *)raddr)->sin_port);
90 break;
91
92 #ifdef AF_INET6
93 case AF_INET6:
94 lport = ntohs(((struct sockaddr_in6 *)laddr)->sin6_port);
95 rport = ntohs(((struct sockaddr_in6 *)raddr)->sin6_port);
96 break;
97 #endif
98
99 default:
100 return NULL;
101 }
102
103 timout.tv_sec = timeout;
104 timout.tv_usec = 0;
105
106 id = id_open_addr(laddr, raddr, (timeout) ? &timout : NULL);
107 if (id == NULL)
108 {
109 errno = EINVAL;
110 return NULL;
111 }
112
113 if (timeout)
114 res = id_query(id, rport, lport, &timout);
115 else
116 res = id_query(id, rport, lport, (struct timeval *) 0);
117
118 if (res < 0)
119 {
120 id_close(id);
121 return NULL;
122 }
123
124 ident = (IDENT *) malloc(sizeof(IDENT));
125 if (ident == NULL) {
126 id_close(id);
127 return NULL;
128 }
129
130 res = id_parse(id, (timeout) ? &timout : NULL, &ident->lport,
131 &ident->fport, &ident->identifier, &ident->opsys,
132 &ident->charset);
133
134 if (res != 1)
135 {
136 free(ident);
137 id_close(id);
138 return NULL;
139 }
140
141 id_close(id);
142 return ident; /* At last! */
143 }
144
145
ident_id(int fd,int timeout)146 char *ident_id (int fd, int timeout)
147 {
148 IDENT *ident;
149 char *id = NULL;
150
151 ident = ident_lookup(fd, timeout);
152 if (ident && ident->identifier && *ident->identifier)
153 {
154 id = id_strdup(ident->identifier);
155 if (id == NULL)
156 return NULL;
157 }
158
159 ident_free(ident);
160 return id;
161 }
162
163
ident_free(IDENT * id)164 void ident_free (IDENT * id)
165 {
166 if (id != NULL)
167 {
168 if (id->identifier)
169 free(id->identifier);
170 if (id->opsys)
171 free(id->opsys);
172 if (id->charset)
173 free(id->charset);
174 free(id);
175 }
176 }
177
178 const char *id_version = PACKAGE_VERSION;
179
180