RE: Obtaining client host IP before accept()

1999-06-19 Thread Daniel J. O'Connor

On 18-Jun-99 Sheldon Hearn wrote:
   Will the IP address of the client host ever enter buf[] if the
   accept() is _not_ uncommented?
  
  I don't need portability, since this is for use within the FreeBSD inetd
  exclusively.

Well if you CAN'T do it in FreeBSD, is there an OS we can copy the API from
that DOES do it? (Providing it isn't too braindamaged of course.. :)

---
Daniel O'Connor software and network engineer
for Genesis Software - http://www.gsoft.com.au
The nice thing about standards is that there
are so many of them to choose from.
  -- Andrew Tanenbaum




pgprZseCOU2BE.pgp
Description: PGP signature


Re: Obtaining client host IP before accept()

1999-06-19 Thread Bodo Rueskamp

Will the IP address of the client host ever enter buf[] if the
accept() is _not_ uncommented?
   I don't need portability, since this is for use within the FreeBSD inetd
   exclusively.

 Well if you CAN'T do it in FreeBSD, is there an OS we can copy the API from
 that DOES do it? (Providing it isn't too braindamaged of course.. :)

There is an API that can do it: 
System V Release 4 Streams and TLI (Transport Layer Interface).

TLI is not based on systems calls doing the job.
It is based on message transfer between the user and some kernel entity.
  
Incoming calls are indicated by sending a T_CONN_IND message (connect
indication) to the user process. Then the user process opens a
second TLI stream (like using the socket() system call) and sends a
T_CONN_CON message (connect confirmation) to the kernel entity.

The TLI API is based on OSI. It doesn't provide much more functionality
than BSD sockets. Two APIs for the same task isn't very useful.
So you should better hack the BSD sockets to fit your needs.

A similar functionality in BSD-world would be:

(1) use recvfrom() instead of accept() on the socket
TLI: use getmsg() to receive the T_CONN_IND
(2) create a new socket using socket()
TLI: use open() to open a new stream
(3) accept the connection using an ioctl()
TLI: send T_CONN_CON to accept the connection
or
(2) reject the connection using an ioctl()
TLI: send T_DISCON_REQ to reject the connection

Here's an overview of the TLI messages:

TLI (user)  TLI (kernel)BSD socket

T_INFO_REQ  T_INFO_ACK  -
T_BIND_REQ  T_BIND_ACK  bind()
T_UNBIND_REQ-   -
T_OPTMGMT_REQ   T_OPTMGMT_ACK   setsockopt()
-   T_ERROR_ACK errno
T_CONN_REQ  T_CONN_RES  connect()
T_CONN_CON  T_CONN_IND  accept()
T_DISCON_REQ-   shutdown()
-   T_DISCON_INDerrno
T_ORDREL_REQ-   shutdown()
T_DATA_REQ  -   send() / sendto() / write()
-   T_DATA_IND  recv() / recvfrom() / read()
T_EXDATA_REQ-   send() / sendto()
-   T_EXDATA_INDrecv() / recvfrom()
T_UNITDATA_REQ  -   send() / sendto() / write()
-   T_UNITDATA_IND  recv() / recvfrom() / read()
-   T_UDERROR_IND   recv() / recvfrom() / read()  errno

; Bodo

-- 
Bodo Rüskamp, b...@rueskamp.com, 51°55' N 7°41' E
(1) Elvis is alive.
(2) Dinosaurs too. http://www.lochness.scotland.net/camera.htm
(3) The next millenium starts on January 1st 2000.


To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Obtaining client host IP before accept()

1999-06-18 Thread Sheldon Hearn

Hi folks,

I found a thread in the freebsd-hackers archive from 1997 that covered
my question, but the answers didn't nail it down to a yes or no
satisfactorily.

We could save ourselves a lot of angst in the work we're doing on inetd
if we could determine the client IP address of a TCP socket before
calling accept(). Alternatively, we'd love a way to accept() without
acknowledging a connection, so that the connection request could be left
for a child that expected to do its own socket() and bind() calls.

My take on the previous thread is that this is impossible in userland.
I'd appreciate it someone who knows the answer for a fact could look at
the code below and answer the following question:

Will the IP address of the client host ever enter buf[] if the
accept() is _not_ uncommented?

I don't need portability, since this is for use within the FreeBSD inetd
exclusively.

Thanks,
Sheldon.


#include err.h
#include errno.h
#include netdb.h
#include stdio.h
#include unistd.h
#include netinet/in.h
#include arpa/inet.h
#include sys/param.h
#include sys/types.h
#include sys/socket.h

/*
 * Use an arbitrary port that you know isn't in use on the system. I
 * don't run ircd, so this is safe for me.
 */
#define LISTEN_PORT (6667)

#define BUFSIZE (1500)

int
main(void)
{
int ctl;
int peek;
int i = 1;
int port = LISTEN_PORT;
char buf[BUFSIZE];
struct sockaddr_in  server_addr;
struct sockaddr_in  client_addr;
struct in_addr  bind_address;
struct msghdr   msg;

if ((ctl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))  0)
err(errno, error creating socket);
printf(socket number %d created\n, ctl);

if (setsockopt(ctl, SOL_SOCKET, SO_REUSEADDR, (char *)i, sizeof(i)))
err(errno, error setsockopt(SO_REUSEADDR): );
if (setsockopt(ctl, SOL_SOCKET, SO_REUSEPORT, (char *)i, sizeof(i)))
err(errno, error setsockopt(SO_REUSEPORT): );
printf(setsockopt(SO_REUSEADDR|SO_REUSEPORT) successful\n);

bind_address.s_addr = htonl(INADDR_ANY);
server_addr.sin_family = AF_INET;
server_addr.sin_addr = bind_address;
server_addr.sin_port = htons(port);

if (bind(ctl, (struct sockaddr *)server_addr, sizeof(server_addr)))
err(errno, error (%d) bind(%lu:%d), errno,
server_addr.sin_addr.s_addr, port);
printf(bound to port %d\n, port);

if (listen(ctl, 0))
err(errno, error listening: );
printf(listening...\n);

/*
i = sizeof(client_addr);
if (peek = accept(ctl, (struct sockaddr *)client_addr, i)  0)
err(errno, accept() failed: );
printf(connection accepted from %s\n,
inet_ntoa(client_addr.sin_addr));
*/

msg.msg_name = (void *)server_addr;
msg.msg_namelen = sizeof(server_addr);
msg.msg_iovlen = 0;
msg.msg_control = (caddr_t)buf;
msg.msg_controllen = 1;
while (recvmsg(ctl, msg, MSG_PEEK)  0) {
warn(recvmsg failed: );
printf(msg_flags = %i\n, msg.msg_flags);
sleep(2);
}
printf(recvmsg successful, wtf?\n);

close(ctl);
/*
close(peek);
*/
return(0);
}


To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message