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); } /* ... */ }