1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 #include <sys/socket.h>
7 #include <netinet/tcp.h>
12 #include <sys/ioctl.h>
17 #include <arpa/inet.h>
18 #include <netinet/in.h>
22 #include <libcfs/portals_utils.h>
23 #include <portals/api-support.h>
24 #include <portals/lib-types.h>
25 #include <portals/socknal.h>
27 /* should get this from autoconf somehow */
29 #define PIDFILE_DIR "/var/run"
32 #define PROGNAME "acceptor"
35 /* needed because libwrap declares these as externs */
36 int allow_severity = LOG_INFO;
37 int deny_severity = LOG_WARNING;
40 void usage(char *myname)
42 fprintf(stderr, "usage: %s [-N nal_id] [-p] [-l] port\n\n"
43 " -l\tKeep stdin/stdout open\n"
44 " -p\tAllow connections from non-privileged ports\n", myname);
48 void create_pidfile(char *name, int port)
53 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
54 PIDFILE_DIR, name, port);
56 if ((fp = fopen(pidfile, "w"))) {
57 fprintf(fp, "%d\n", getpid());
60 syslog(LOG_ERR, "%s: %s\n", pidfile,
65 int pidfile_exists(char *name, int port)
69 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
70 PIDFILE_DIR, name, port);
72 if (!access(pidfile, F_OK)) {
73 fprintf(stderr, "%s: exists, acceptor already running.\n",
81 show_connection (int fd, __u32 net_ip)
83 static long last_time;
90 /* Don't show repeats for same host, it adds no value */
91 if (host_ip == ntohl(net_ip) && (now - last_time) < 5)
94 h = gethostbyaddr((char *)&net_ip, sizeof(net_ip), AF_INET);
96 host_ip = ntohl(net_ip);
99 snprintf(host, sizeof(host), "%d.%d.%d.%d",
100 (host_ip >> 24) & 0xff, (host_ip >> 16) & 0xff,
101 (host_ip >> 8) & 0xff, host_ip & 0xff);
103 snprintf(host, sizeof(host), "%s", h->h_name);
105 syslog(LOG_INFO, "Accepted host: %s\n", host);
108 int main(int argc, char **argv)
110 int o, fd, rc, port, pfd;
111 struct sockaddr_in srvaddr;
116 int require_privports = 1;
118 while ((c = getopt (argc, argv, "N:lp")) != -1) {
121 if (sscanf(optarg, "%d", &nal) != 1 ||
122 nal < 0 || nal > NAL_MAX_NR)
129 require_privports = 0;
140 port = atol(argv[optind++]);
142 if (pidfile_exists(PROGNAME, port))
145 memset(&srvaddr, 0, sizeof(srvaddr));
146 srvaddr.sin_family = AF_INET;
147 srvaddr.sin_port = htons(port);
148 srvaddr.sin_addr.s_addr = INADDR_ANY;
150 fd = socket(PF_INET, SOCK_STREAM, 0);
152 perror("opening socket");
157 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &o, sizeof(o))) {
158 perror("Cannot set REUSEADDR socket opt");
162 rc = bind(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
168 if (listen(fd, 127)) {
172 fprintf(stderr, "listening on port %d\n", port);
174 pfd = open("/dev/portals", O_RDWR);
176 perror("opening portals device");
180 rc = daemon(0, noclose);
182 perror("daemon(): ");
186 openlog(PROGNAME, LOG_PID, LOG_DAEMON);
187 syslog(LOG_INFO, "started, listening on port %d\n", port);
188 create_pidfile(PROGNAME, port);
191 struct sockaddr_in clntaddr;
192 int len = sizeof(clntaddr);
194 struct portal_ioctl_data data;
195 struct portals_cfg pcfg;
197 struct request_info request;
199 char addrstr[INET_ADDRSTRLEN];
201 cfd = accept(fd, (struct sockaddr *)&clntaddr, &len);
209 /* libwrap access control */
210 request_init(&request, RQ_DAEMON, "lustre", RQ_FILE, cfd, 0);
212 if (!hosts_access(&request)) {
213 inet_ntop(AF_INET, &clntaddr.sin_addr,
214 addrstr, INET_ADDRSTRLEN);
215 syslog(LOG_WARNING, "Unauthorized access from %s:%hd\n",
216 addrstr, ntohs(clntaddr.sin_port));
222 if (require_privports && ntohs(clntaddr.sin_port) >= IPPORT_RESERVED) {
223 inet_ntop(AF_INET, &clntaddr.sin_addr,
224 addrstr, INET_ADDRSTRLEN);
225 syslog(LOG_ERR, "Closing non-privileged connection from %s:%d\n",
226 addrstr, ntohs(clntaddr.sin_port));
229 perror ("close un-privileged client failed");
233 show_connection (cfd, clntaddr.sin_addr.s_addr);
235 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
238 pcfg.pcfg_misc = SOCKNAL_CONN_NONE; /* == incoming connection */
240 PORTAL_IOC_INIT(data);
241 data.ioc_pbuf1 = (char*)&pcfg;
242 data.ioc_plen1 = sizeof(pcfg);
244 if (ioctl(pfd, IOC_PORTAL_NAL_CMD, &data) < 0) {
245 perror("ioctl failed");
247 printf("client registered\n");
251 perror ("close failed");