rtsock.c revision 127141
1327Sjkh/* $KAME: rtsock.c,v 1.3 2000/10/10 08:46:45 itojun Exp $ */ 2327Sjkh/* $FreeBSD: head/usr.sbin/rtsold/rtsock.c 127141 2004-03-17 20:10:59Z ru $ */ 3327Sjkh 4327Sjkh/* 5327Sjkh * Copyright (C) 2000 WIDE Project. 6327Sjkh * All rights reserved. 7327Sjkh * 8327Sjkh * Redistribution and use in source and binary forms, with or without 9327Sjkh * modification, are permitted provided that the following conditions 10327Sjkh * are met: 11327Sjkh * 1. Redistributions of source code must retain the above copyright 12327Sjkh * notice, this list of conditions and the following disclaimer. 13327Sjkh * 2. Redistributions in binary form must reproduce the above copyright 14327Sjkh * notice, this list of conditions and the following disclaimer in the 15327Sjkh * documentation and/or other materials provided with the distribution. 16327Sjkh * 3. Neither the name of the project nor the names of its contributors 17327Sjkh * may be used to endorse or promote products derived from this software 18327Sjkh * without specific prior written permission. 19327Sjkh * 20327Sjkh * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2193520Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2293520Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2393520Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2430221Scharnier * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2569793Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26327Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27327Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28327Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2984670Ssobomax * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30327Sjkh * SUCH DAMAGE. 314996Sjkh */ 32327Sjkh 33327Sjkh#include <sys/param.h> 34327Sjkh#include <sys/socket.h> 35327Sjkh#include <sys/uio.h> 3637728Seivind#include <sys/time.h> 37327Sjkh#include <sys/queue.h> 38327Sjkh 39327Sjkh#include <net/if.h> 40327Sjkh#include <net/route.h> 41327Sjkh#include <net/if_dl.h> 42327Sjkh 43327Sjkh#include <netinet/in.h> 44327Sjkh#include <netinet/ip6.h> 45327Sjkh#include <netinet/icmp6.h> 46382Sjkh 47382Sjkh#include <time.h> 48382Sjkh#include <unistd.h> 49382Sjkh#include <stdio.h> 50382Sjkh#include <stddef.h> 51382Sjkh#include <err.h> 52327Sjkh#include <errno.h> 53327Sjkh#include <string.h> 54327Sjkh#include <stdlib.h> 55327Sjkh#include <syslog.h> 5611780Sjkh#include "rtsold.h" 57327Sjkh 588083Sjkh#define ROUNDUP(a, size) \ 598083Sjkh (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) 608083Sjkh 618083Sjkh#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ 628083Sjkh ((caddr_t)(ap) + \ 63327Sjkh ((ap)->sa_len ? ROUNDUP((ap)->sa_len, sizeof(u_long)) \ 64327Sjkh : sizeof(u_long))) 65327Sjkh 66327Sjkh#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/ 6711780Sjkhstatic int rtsock_input_ifannounce __P((int, struct rt_msghdr *, char *)); 687998Sjkh#endif 6984670Ssobomax 70327Sjkhstatic struct { 7111780Sjkh u_char type; 721545Sjkh size_t minlen; 733364Sjkh int (*func) __P((int, struct rt_msghdr *, char *)); 74131280Seik} rtsock_dispatch[] = { 7541866Sjkh#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/ 7641866Sjkh { RTM_IFANNOUNCE, sizeof(struct if_announcemsghdr), 7741866Sjkh rtsock_input_ifannounce }, 7841866Sjkh#endif 7941866Sjkh { 0, 0, NULL }, 80113594Skris}; 81113594Skris 82327Sjkhint 83113594Skrisrtsock_open(void) 8411780Sjkh{ 8537728Seivind 86327Sjkh return socket(PF_ROUTE, SOCK_RAW, 0); 8711780Sjkh} 8811780Sjkh 898075Sjkhint 908083Sjkhrtsock_input(int s) 9111780Sjkh{ 9211780Sjkh ssize_t n; 9311780Sjkh char msg[2048]; 9411780Sjkh char *lim, *next; 9530221Scharnier struct rt_msghdr *rtm; 96382Sjkh int idx; 97382Sjkh size_t len; 98382Sjkh int ret = 0; 9911780Sjkh const size_t lenlim = 100327Sjkh offsetof(struct rt_msghdr, rtm_msglen) + sizeof(rtm->rtm_msglen); 1018083Sjkh 102382Sjkh n = read(s, msg, sizeof(msg)); 103102383Sobrien 1048083Sjkh lim = msg + n; 105154145Sflz for (next = msg; next < lim; next += len) { 10681046Ssobomax rtm = (struct rt_msghdr *)next; 1078083Sjkh if (lim - next < lenlim) 1088083Sjkh break; 10911780Sjkh len = rtm->rtm_msglen; 11011780Sjkh if (len < lenlim) 11111780Sjkh break; 11211780Sjkh 11330221Scharnier if (dflag > 1) { 11481046Ssobomax warnmsg(LOG_INFO, __func__, 11530221Scharnier "rtmsg type %d, len=%lu", rtm->rtm_type, 11611780Sjkh (u_long)len); 11711780Sjkh } 11811780Sjkh 11911780Sjkh for (idx = 0; rtsock_dispatch[idx].func; idx++) { 120382Sjkh if (rtm->rtm_type != rtsock_dispatch[idx].type) 1218083Sjkh continue; 12276739Ssobomax if (rtm->rtm_msglen < rtsock_dispatch[idx].minlen) { 12376739Ssobomax warnmsg(LOG_INFO, __func__, 12476739Ssobomax "rtmsg type %d too short!", rtm->rtm_type); 12576739Ssobomax continue; 12614582Sjkh } 12714582Sjkh 12830221Scharnier ret = (*rtsock_dispatch[idx].func)(s, rtm, lim); 12914582Sjkh break; 13014582Sjkh } 13114582Sjkh } 13214582Sjkh 13311780Sjkh return ret; 13422750Sjkh} 13514582Sjkh 13622750Sjkh#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/ 13722750Sjkhstatic int 13811780Sjkhrtsock_input_ifannounce(int s, struct rt_msghdr *rtm, char *lim) 13911780Sjkh{ 140132799Sstefanf struct if_announcemsghdr *ifan; 14111780Sjkh struct ifinfo *ifinfo; 14238583Sjkh 14338583Sjkh ifan = (struct if_announcemsghdr *)rtm; 14438583Sjkh if ((char *)(ifan + 1) > lim) 14514582Sjkh return -1; 14630221Scharnier 14781046Ssobomax switch (ifan->ifan_what) { 14830221Scharnier case IFAN_ARRIVAL: 14911780Sjkh /* 15011780Sjkh * XXX for NetBSD 1.5, interface index will monotonically be 15111780Sjkh * increased as new pcmcia card gets inserted. 15211780Sjkh * we may be able to do a name-based interface match, 15330221Scharnier * and call ifreconfig() to enable the interface again. 15481046Ssobomax */ 15530221Scharnier warnmsg(LOG_INFO, __func__, 15611780Sjkh "interface %s inserted", ifan->ifan_name); 15711780Sjkh break; 15811780Sjkh case IFAN_DEPARTURE: 15911780Sjkh warnmsg(LOG_WARNING, __func__, 1607998Sjkh "interface %s removed", ifan->ifan_name); 16111780Sjkh ifinfo = find_ifinfo(ifan->ifan_index); 16211780Sjkh if (ifinfo) { 16311780Sjkh if (dflag > 1) { 16411780Sjkh warnmsg(LOG_INFO, __func__, 16511780Sjkh "bring interface %s to DOWN state", 16611780Sjkh ifan->ifan_name); 16711780Sjkh } 16811780Sjkh ifinfo->state = IFS_DOWN; 16911780Sjkh } 170131285Seik break; 17111780Sjkh } 17281046Ssobomax 17311780Sjkh return 0; 17411780Sjkh} 1757998Sjkh#endif 17611780Sjkh