3 Copyright (C) Andrew Tridgell 1999
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 /****************************************************************************
22 open a socket of the specified type, port and address for incoming data
23 ****************************************************************************/
24 int open_socket_in(int type, int port)
26 struct sockaddr_in sock;
30 memset((char *)&sock,0, sizeof(sock));
31 sock.sin_port = htons(port);
32 sock.sin_family = AF_INET;
33 sock.sin_addr.s_addr = 0;
34 res = socket(AF_INET, type, 0);
36 fprintf(stderr, "socket failed\n"); return -1;
39 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
41 /* now we've got a socket - we need to bind it */
42 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
46 set_socket_options(res, options.tcp_options);
52 /* open a socket to a tcp remote host with the specified port
53 based on code from Warren */
54 int open_socket_out(const char *host, int port)
56 int type = SOCK_STREAM;
57 struct sockaddr_in sock_out;
61 res = socket(PF_INET, type, 0);
66 hp = gethostbyname(host);
68 fprintf(stderr,"unknown host: %s\n", host);
72 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
73 sock_out.sin_port = htons(port);
74 sock_out.sin_family = PF_INET;
76 set_socket_options(res, options.tcp_options);
78 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
80 fprintf(stderr,"failed to connect to %s - %s\n",
81 host, strerror(errno));
90 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
99 } socket_options[] = {
100 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
101 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
102 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
104 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
106 #ifdef IPTOS_LOWDELAY
107 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
109 #ifdef IPTOS_THROUGHPUT
110 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
113 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
116 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
119 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
122 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
125 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
128 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
134 /****************************************************************************
135 set user socket options
136 ****************************************************************************/
137 void set_socket_options(int fd, char *options)
141 while (next_token(&options,tok," \t,"))
146 BOOL got_value = False;
148 if ((p = strchr(tok,'=')))
155 for (i=0;socket_options[i].name;i++)
156 if (strcasecmp(socket_options[i].name,tok)==0)
159 if (!socket_options[i].name)
161 fprintf(stderr, "Unknown socket option %s\n",tok);
165 switch (socket_options[i].opttype)
169 ret = setsockopt(fd,socket_options[i].level,
170 socket_options[i].option,(char *)&value,sizeof(int));
175 fprintf(stderr,"syntax error - %s does not take a value\n",tok);
178 int on = socket_options[i].value;
179 ret = setsockopt(fd,socket_options[i].level,
180 socket_options[i].option,(char *)&on,sizeof(int));
186 fprintf(stderr, "Failed to set socket option %s\n",tok);
190 int read_sock(int s, char *buf, int size)
195 int r = recv(s, buf, size, MSG_WAITALL);
197 if (r == -1) perror("recv");
207 int write_sock(int s, char *buf, int size)
212 int r = send(s, buf, size, 0);
214 if (r == -1) perror("send");