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