TAYBENGH@NUSDISCS.BITNET (03/05/91)
Hi netlander,
I would like to use SOCK_RAW provided in BSD socket to implement a new
transport protocol on top of IP. Regretably, the documentation of SOCK_RAW
usage is very scare, it is not clearly discussed in BSD documantation, nor the
two precious books - The design and implementation of 4.3BSD OS (published by
Addsion-Wesley), and Unix Network Programming (published by Prentice-Hall).
As such, I would like to sort for the net experience. The questions are:
1) How one can associate a new protocol (that is not defined in in.h -
socket) to the socket? Specifically, how one can initialize the rcp_proto
field so as to filter packets on input, and also the rcb_pcb field so as to
attach the new protocol-specific information? (note: the rcb_* and raw socket
are discussed in 11.7 of the BSD4.3 book - pg 332)
2) If one cannot filter out the packets on input using the above
method, then if I open a socket using protocol 0 (the default protocol - IP?),
does this socket receive all the packets including TCP, UDP, ICMP, and pure IP
packets? (in fact, I did an experiment on SunOS4.1, I found out the socket
receives only the ICMP packets, not even the pure IP packets, the program
segment are attached as follow, did I did sth wrong?, I also crashed the system
several times when I tried to send out IP packets, is this a bug or I did sth
wrong again?) Moreover, how to initialize the socket so that it can receive all
IP packets in order to extract the newly defined packets?
3) In SunOS4.1, I opened a raw socket with protocol 0 to receive IP
packets using the attached program segment shown below, then when I used ping
(within same host) to ping itself, this program only receive the echo ICMP
messages, but NOT the request ICMP messages. On the other hand, if I ping from
other host to this particular host, the request ICMP messages are also NOT
received by this program. As such it seems that all ICMP request messages are
filtered out by IP layer and thus cannot be received by user process? Is that
true? Morevoer, if I used an connected UDP socket to send message to an
unreachable port within the same host, this program is also able receives the
port unreachable ICMP messages (type=3, code=3). Why is it so? I thought it
should EITHER receive ALL ICMP messages (including echo, request and etc), OR
it should not receive any ICMP messages at all.
4) After looking thru the in.h, I found out there is a IPPROTO_RAW (255)
, should I use this instead of the default 0 in order to receive pure IP
packets? If not, what is the purpose of this protocol?
Could somebody please solve/explain all these puzzles? I am desparated,
please help. Thanks a lot.
==> Here are the receiving part (in C), this part can receive ICMP
message, BUT NOT the pure IP packets sent by the below program.
int sock, socklen;
struct sockaddr_in local_in, remote_in;
char buf[1024], hostname[15], s1[10];
u_short local_port, remote_port;
sock = socket(AF_INET, SOCK_RAW, 0);
if (sock <0)
{
perror("opening datagram socket");
exit(1);
}
for (;;)
{
int i;
long *lp;
socklen = sizeof(remote_in);
/* read from the socket */
if (recvfrom(sock, buf, 1024, 0, &remote_in, &socklen)
< 0)
perror("receiving datagram packets");
lp = (long *)buf;
printf("-->%s\n", buf);
for (i=0; i<12; i++)
printf("x%2.2x: x%8.8x\n", i*sizeof(long), *lp++);
}
close(sock);
===> Here are the sending part (in C), the receving part above never
receive the message sent here, anything worng here? This segment
also crashed the SunOS4.1 many times, error message saying the panic
in m_copy, any clues?
char buf[BUFLEN], remote_host[40], str[40];
int local_port, remote_port, size;
struct sockaddr_in local_sock, remote_sock;
struct hostent *host;
if ((id = socket(AF_INET, SOCK_RAW, 0)) < 0)
syserr("main(): socket()")
/* Get the messages and sendto */
for (;;)
{
printf("\nPls input the messages:\n");
gets(buf);
if (buf[0] == '\n' || buf[0] == '\0')
break;
host = gethostbyname(remote_host);
bcopy(host->h_addr, &remote_sock.sin_addr, host->h_length);
remote_sock.sin_family = AF_INET;
size = sendto(id, buf, sizeof(buf), 0,
(struct sockaddr *)&remote_sock, sizeof(remote_sock));
if (size < 0)
syserr("main(): sendto()")
}
Sorry for the lenghty posting, Thanks in advance for any help.
- Beng Hang (EMAIL: taybengh@nusdiscs.bitnet)
Dept of Information Systems and Computer Science
National University of Singapore