int rtmsg(int cmd) { static int seq; struct rt_msghdr *rtm = &m_rtmsg.m_rtm; char *cp = m_rtmsg.m_space; int l; errno = 0; if (cmd == RTM_DELETE) goto doit; memset((char *)&m_rtmsg, 0, sizeof(m_rtmsg)); rtm->rtm_flags = flags; rtm->rtm_version = RTM_VERSION; switch (cmd) { default: syslog(LOG_ERR, "arptab_set: internal wrong cmd"); exit(1); case RTM_ADD: rtm->rtm_addrs |= RTA_GATEWAY; rtm->rtm_rmx.rmx_expire = expire_time; rtm->rtm_inits = RTV_EXPIRE; rtm->rtm_flags |= (RTF_HOST | RTF_STATIC); sin_m.sin_other = 0; if (doing_proxy) { if (export_only) sin_m.sin_other = SIN_PROXY; else { rtm->rtm_addrs |= RTA_NETMASK; rtm->rtm_flags &= ~RTF_HOST; } } /* FALLTHROUGH */ case RTM_GET: rtm->rtm_addrs |= RTA_DST; } #define NEXTADDR(w, s) \ if (rtm->rtm_addrs & (w)) { \ memcpy(cp, (char *)&s, sizeof(s)); \ cp += sizeof(s); \ } NEXTADDR(RTA_DST, sin_m); NEXTADDR(RTA_GATEWAY, sdl_m); NEXTADDR(RTA_NETMASK, so_mask); rtm->rtm_msglen = cp - (char *)&m_rtmsg; doit: l = rtm->rtm_msglen; rtm->rtm_seq = ++seq; rtm->rtm_type = cmd; if (write(s, (char *)&m_rtmsg, l) < 0) { if (errno != ESRCH && errno != EEXIST) { syslog(LOG_ERR, "writing to routing socket: %m"); return (-1); } } do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm->rtm_version != RTM_VERSION || rtm->rtm_seq != seq || rtm->rtm_pid != pid)); if (l < 0) syslog(LOG_ERR, "arptab_set: read from routing socket: %m"); return (0); }
int getdefaultgateway(in_addr_t *addr) { int s, seq, l, rtm_addrs, i; pid_t pid; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; struct rt_msghdr *msg_hdr; pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; memset(&so_dst, 0, sizeof(so_dst)); memset(&so_mask, 0, sizeof(so_mask)); memset(&rtm, 0, sizeof(struct rt_msghdr)); rtm.rtm_type = RTM_GET; rtm.rtm_flags = RTF_UP | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; so_mask.sa_family = AF_INET; NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; s = socket(PF_ROUTE, SOCK_RAW, 0); if (write(s, (char *)&m_rtmsg, l) < 0) { close(s); return FAILED; } do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); close(s); msg_hdr = &rtm; cp = ((char *)(msg_hdr + 1)); if (msg_hdr->rtm_addrs) { for (i = 1; i; i <<= 1) if (i & msg_hdr->rtm_addrs) { sa = (struct sockaddr *)cp; if (i == RTA_GATEWAY ) gate = sa; cp += sizeof(struct sockaddr); } } else { return FAILED; } if (gate != NULL ) { *addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr; return SUCCESS; } else { return FAILED; } }
static void get_default_gw(Enna_Buffer *b) { #ifdef __FreeBSD__ int s, seq, l, pid, rtm_addrs, i; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; struct rt_msghdr *rtm_aux; pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; memset(&so_dst, 0, sizeof(so_dst)); memset(&so_mask, 0, sizeof(so_mask)); memset(&rtm, 0, sizeof(struct rt_msghdr)); rtm.rtm_type = RTM_GET; rtm.rtm_flags = RTF_UP | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; so_dst.sa_len = sizeof(struct sockaddr_in); so_mask.sa_family = AF_INET; so_mask.sa_len = sizeof(struct sockaddr_in); NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; s = socket(PF_ROUTE, SOCK_RAW, 0); if (write(s, (char *)&m_rtmsg, l) < 0) return; do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); close(s); rtm_aux = &rtm; cp = ((char *)(rtm_aux + 1)); if (rtm_aux->rtm_addrs) { for (i = 1; i; i <<= 1) if (i & rtm_aux->rtm_addrs) { sa = (struct sockaddr *)cp; if (i == RTA_GATEWAY ) gate = sa; ADVANCE(cp, sa); } } else return; if (gate) { enna_buffer_append(b, "<hilight>"); enna_buffer_append(b, _("Default gateway:")); enna_buffer_append(b, "</hilight> "); enna_buffer_appendf(b, "%s<br>", inet_ntoa(((struct sockaddr_in *)gate)->sin_addr)); } #else /* __FreeBSD__ */ char devname[64]; unsigned long d, g, m; int res, flgs, ref, use, metric, mtu, win, ir; FILE *fp; fp = fopen("/proc/net/route", "r"); if (!fp) return; if (fscanf(fp, "%*[^\n]\n") < 0) /* Skip the first line. */ return; enna_buffer_append(b, "<hilight>"); enna_buffer_append(b, _("Default gateway:")); enna_buffer_append(b, "</hilight> "); res = 0; while (1) { struct in_addr gw; int r; r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", devname, &d, &g, &flgs, &ref, &use, &metric, &m, &mtu, &win, &ir); if (r != 11) if ((r < 0) && feof(fp)) break; /* we only care about default gateway */ if (d != 0) continue; gw.s_addr = g; enna_buffer_appendf(b, "%s<br>", inet_ntoa (gw)); res = 1; break; } if (!res) { enna_buffer_append(b, _("None")); enna_buffer_append(b, "<br>"); } fclose(fp); #endif /* !__FreeBSD__ */ }
static int rtmsg(int cmd) { static int seq; int rlen; struct rt_msghdr *rtm = &m_rtmsg.m_rtm; char *cp = m_rtmsg.m_space; int l; errno = 0; bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); rtm->rtm_flags = flags; rtm->rtm_version = RTM_VERSION; switch (cmd) { default: report(LOG_ERR, "set_arp: internal wrong cmd - exiting"); exit(1); case RTM_ADD: case RTM_CHANGE: rtm->rtm_addrs |= RTA_GATEWAY; rtm->rtm_rmx.rmx_expire = expire_time; rtm->rtm_inits = RTV_EXPIRE; rtm->rtm_flags |= (RTF_HOST | RTF_STATIC); sin_m.sin_other = 0; if (doing_proxy) { if (export_only) sin_m.sin_other = SIN_PROXY; else { rtm->rtm_addrs |= RTA_NETMASK; rtm->rtm_flags &= ~RTF_HOST; } } /* FALLTHROUGH */ case RTM_GET: rtm->rtm_addrs |= RTA_DST; } #define NEXTADDR(w, s) \ if (rtm->rtm_addrs & (w)) { \ bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);} NEXTADDR(RTA_DST, sin_m); NEXTADDR(RTA_GATEWAY, sdl_m); NEXTADDR(RTA_NETMASK, so_mask); rtm->rtm_msglen = cp - (char *)&m_rtmsg; l = rtm->rtm_msglen; rtm->rtm_seq = ++seq; rtm->rtm_type = cmd; if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { if ((errno != ESRCH) && !(errno == EEXIST && cmd == RTM_ADD)){ report(LOG_WARNING, "writing to routing socket: %s", strerror(errno)); return (-1); } } do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm->rtm_type != cmd || rtm->rtm_seq != seq || rtm->rtm_pid != getpid())); if (l < 0) report(LOG_WARNING, "arp: read from routing socket: %s\n", strerror(errno)); return (0); }