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 2 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, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 /****************************************************************************
23 open a socket of the specified type, port and address for incoming data
24 ****************************************************************************/
25 int open_socket_in(int type, int port, uint32 socket_addr)
28 struct sockaddr_in sock;
32 extern char *tcp_options;
34 /* get my host name */
35 if (gethostname(host_name, sizeof(host_name)) == -1) {
36 fprintf(stderr,"gethostname failed\n"); return -1;
40 if ((hp = gethostbyname(host_name)) == 0) {
41 fprintf(stderr,"Get_Hostbyname: Unknown host %s\n",host_name);
45 bzero((char *)&sock,sizeof(sock));
46 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
48 #ifdef HAVE_SOCK_SIN_LEN
49 sock.sin_len = sizeof(sock);
51 sock.sin_port = htons( port );
52 sock.sin_family = hp->h_addrtype;
53 sock.sin_addr.s_addr = socket_addr;
54 res = socket(hp->h_addrtype, type, 0);
56 fprintf(stderr, "socket failed\n"); return -1;
59 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
61 /* now we've got a socket - we need to bind it */
62 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
66 set_socket_options(res, tcp_options);
72 /* open a socket to a tcp remote host with the specified port
73 based on code from Warren */
74 int open_socket_out(char *host, int port)
76 int type = SOCK_STREAM;
77 struct sockaddr_in sock_out;
80 extern char *tcp_options;
82 res = socket(PF_INET, type, 0);
87 hp = gethostbyname(host);
89 fprintf(stderr,"unknown host: %s\n", host);
93 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
94 sock_out.sin_port = htons(port);
95 sock_out.sin_family = PF_INET;
97 set_socket_options(res, tcp_options);
99 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
101 fprintf(stderr,"failed to connect to %s - %s\n",
102 host, strerror(errno));
111 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
120 } socket_options[] = {
121 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
122 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
123 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
125 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
127 #ifdef IPTOS_LOWDELAY
128 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
130 #ifdef IPTOS_THROUGHPUT
131 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
134 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
137 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
140 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
143 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
146 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
149 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
155 /****************************************************************************
156 set user socket options
157 ****************************************************************************/
158 void set_socket_options(int fd, char *options)
162 while (next_token(&options,tok," \t,"))
167 BOOL got_value = False;
169 if ((p = strchr(tok,'=')))
176 for (i=0;socket_options[i].name;i++)
177 if (strcasecmp(socket_options[i].name,tok)==0)
180 if (!socket_options[i].name)
182 fprintf(stderr, "Unknown socket option %s\n",tok);
186 switch (socket_options[i].opttype)
190 ret = setsockopt(fd,socket_options[i].level,
191 socket_options[i].option,(char *)&value,sizeof(int));
196 fprintf(stderr,"syntax error - %s does not take a value\n",tok);
199 int on = socket_options[i].value;
200 ret = setsockopt(fd,socket_options[i].level,
201 socket_options[i].option,(char *)&on,sizeof(int));
207 fprintf(stderr, "Failed to set socket option %s\n",tok);
211 int read_sock(int s, char *buf, int size)
216 int r = recv(s, buf, size, MSG_WAITALL);
225 int write_sock(int s, char *buf, int size)
230 int r = send(s, buf, size, 0);