Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/arp/arp.c
Show First 20 Lines • Show All 711 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static struct rt_msghdr * | static struct rt_msghdr * | ||||
rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl *sdl) | rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl *sdl) | ||||
{ | { | ||||
static int seq; | static int seq; | ||||
int rlen; | int rlen; | ||||
int l; | int l; | ||||
struct sockaddr_in so_mask, *som = &so_mask; | |||||
static int s = -1; | static int s = -1; | ||||
static pid_t pid; | static pid_t pid; | ||||
static struct { | static struct { | ||||
struct rt_msghdr m_rtm; | struct rt_msghdr m_rtm; | ||||
char m_space[512]; | char m_space[512]; | ||||
} m_rtmsg; | } m_rtmsg; | ||||
struct rt_msghdr *rtm = &m_rtmsg.m_rtm; | struct rt_msghdr *rtm = &m_rtmsg.m_rtm; | ||||
char *cp = m_rtmsg.m_space; | char *cp = m_rtmsg.m_space; | ||||
if (s < 0) { /* first time: open socket, get pid */ | if (s < 0) { /* first time: open socket, get pid */ | ||||
s = socket(PF_ROUTE, SOCK_RAW, 0); | s = socket(PF_ROUTE, SOCK_RAW, 0); | ||||
if (s < 0) | if (s < 0) | ||||
xo_err(1, "socket"); | xo_err(1, "socket"); | ||||
pid = getpid(); | pid = getpid(); | ||||
} | } | ||||
bzero(&so_mask, sizeof(so_mask)); | |||||
so_mask.sin_len = 8; | |||||
so_mask.sin_addr.s_addr = 0xffffffff; | |||||
errno = 0; | errno = 0; | ||||
/* | /* | ||||
* XXX RTM_DELETE relies on a previous RTM_GET to fill the buffer | * XXX RTM_DELETE relies on a previous RTM_GET to fill the buffer | ||||
* appropriately. | * appropriately. | ||||
*/ | */ | ||||
if (cmd == RTM_DELETE) | if (cmd == RTM_DELETE) | ||||
goto doit; | goto doit; | ||||
bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); | bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); | ||||
rtm->rtm_flags = flags; | rtm->rtm_flags = flags; | ||||
rtm->rtm_version = RTM_VERSION; | rtm->rtm_version = RTM_VERSION; | ||||
switch (cmd) { | switch (cmd) { | ||||
default: | default: | ||||
xo_errx(1, "internal wrong cmd"); | xo_errx(1, "internal wrong cmd"); | ||||
case RTM_ADD: | case RTM_ADD: | ||||
rtm->rtm_addrs |= RTA_GATEWAY; | rtm->rtm_addrs |= RTA_GATEWAY; | ||||
rtm->rtm_rmx.rmx_expire = expire_time; | rtm->rtm_rmx.rmx_expire = expire_time; | ||||
rtm->rtm_inits = RTV_EXPIRE; | rtm->rtm_inits = RTV_EXPIRE; | ||||
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA); | rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA); | ||||
if (doing_proxy) { | |||||
rtm->rtm_addrs |= RTA_NETMASK; | |||||
rtm->rtm_flags &= ~RTF_HOST; | |||||
} | |||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case RTM_GET: | case RTM_GET: | ||||
rtm->rtm_addrs |= RTA_DST; | rtm->rtm_addrs |= RTA_DST; | ||||
} | } | ||||
#define NEXTADDR(w, s) \ | #define NEXTADDR(w, s) \ | ||||
do { \ | do { \ | ||||
if ((s) != NULL && rtm->rtm_addrs & (w)) { \ | if ((s) != NULL && rtm->rtm_addrs & (w)) { \ | ||||
bcopy((s), cp, sizeof(*(s))); \ | bcopy((s), cp, sizeof(*(s))); \ | ||||
cp += SA_SIZE(s); \ | cp += SA_SIZE(s); \ | ||||
} \ | } \ | ||||
} while (0) | } while (0) | ||||
NEXTADDR(RTA_DST, dst); | NEXTADDR(RTA_DST, dst); | ||||
NEXTADDR(RTA_GATEWAY, sdl); | NEXTADDR(RTA_GATEWAY, sdl); | ||||
NEXTADDR(RTA_NETMASK, som); | |||||
rtm->rtm_msglen = cp - (char *)&m_rtmsg; | rtm->rtm_msglen = cp - (char *)&m_rtmsg; | ||||
doit: | doit: | ||||
l = rtm->rtm_msglen; | l = rtm->rtm_msglen; | ||||
rtm->rtm_seq = ++seq; | rtm->rtm_seq = ++seq; | ||||
rtm->rtm_type = cmd; | rtm->rtm_type = cmd; | ||||
if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { | if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { | ||||
if (errno != ESRCH || cmd != RTM_DELETE) { | if (errno != ESRCH || cmd != RTM_DELETE) { | ||||
▲ Show 20 Lines • Show All 104 Lines • Show Last 20 Lines |