RIP协议中使用了两种套接字,分别来接受RIP数据报文和RIP相关消息。

RIP套接字的注册

RIP数据报文套接字的注册如下所示。

void ripTask()
{
    /* ... */

    ripState.s = getsocket (AF_INET, SOCK_DGRAM, &ripState.addr);
    if (ripState.s < 0)
    {
        log_err (RIP_V4_LOG, "Unable to get input/output socket.");
        priv_ripInitFlag = INIT_FAILED;
        return (ERROR);
    }
    /* ... */
}

LOCAL int getsocket (domain, type, sin)
	int domain, type;
	struct sockaddr_in *sin;
{
	int sock, on = 1;

	if ((sock = socket (domain, type, 0)) < 0) {
                log_err (RIP_V4_LOG, "Error creating socket.");
		return (-1);
	}
#ifdef SO_BROADCAST
	if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, 
                        sizeof (on)) < 0) {
                log_err (RIP_V4_LOG, "error setting SO_BROADCAST option");
		close (sock);
		return (-1);
	}
#endif
#ifdef SO_RCVBUF
	for (on = BUFSPACE; ; on -= 1024) {
		if (setsockopt (sock, SOL_SOCKET, SO_RCVBUF, 
                                (char *)&on, sizeof (on)) == 0)
			break;
		if (on <= 8*1024) {
                        log_debug (RIP_V4_LOG, "unable to set SO_RCVBUF option");
			break;
		}
	}
        log_debug (RIP_V4_LOG, "Receive buffer size %d.", on);
#endif
	if (bind (sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) {
                log_err (RIP_V4_LOG, "error binding socket.");
		close (sock);
		return (-1);
	}
        on = 1;
	if (ioctl (sock, FIONBIO, (int) &on) == -1)
                log_err (RIP_V4_LOG, "error setting O_NONBLOCK option.");

	return (sock);
}

RIP消息套接字的注册如下所示:

void ripTask()
{
    /* ... */
    ripState.routeSocket = socket (AF_ROUTE, SOCK_RAW, 0);
    if (ripState.routeSocket < 0)
        {
        log_err (RIP_V4_LOG, "Unable to get route socket.");
        close (ripState.s); 
        priv_ripInitFlag = INIT_FAILED;
        return (ERROR);
        }
    
    /* ... */
}