Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- sys/net/rtsock.c.orig 2013-04-15 03:37:01.713760711 +0000
- +++ sys/net/rtsock.c 2013-04-16 21:08:21.398951884 +0000
- @@ -75,6 +75,7 @@
- #ifdef COMPAT_FREEBSD32
- #include <sys/mount.h>
- +#include <sys/sysent.h>
- #include <compat/freebsd32/freebsd32.h>
- struct if_data32 {
- @@ -141,6 +142,43 @@
- int32_t ifam_metric;
- struct if_data32 ifam_data;
- };
- +
- +struct rt_metrics32 {
- + uint32_t rmx_locks;
- + uint32_t rmx_mtu;
- + uint32_t rmx_hopcount;
- + uint32_t rmx_expire;
- + uint32_t rmx_recvpipe;
- + uint32_t rmx_sendpipe;
- + uint32_t rmx_ssthresh;
- + uint32_t rmx_rtt;
- + uint32_t rmx_rttvar;
- + uint32_t rmx_pksent;
- + uint32_t rmx_weight;
- + uint32_t rmx_filler[3];
- +};
- +
- +struct rt_msghdr32 {
- + uint16_t rtm_msglen;
- + uint8_t rtm_version;
- + uint8_t rtm_type;
- + uint16_t rtm_index;
- + uint16_t rtm_hole1;
- + uint32_t rtm_flags;
- + uint32_t rtm_addrs;
- + uint32_t rtm_pid;
- + uint32_t rtm_seq;
- + uint32_t rtm_errno;
- + uint32_t rtm_fmask;
- + uint32_t rtm_inits;
- + struct rt_metrics32 rtm_rmx;
- +};
- +
- +#define SA_SIZE32(sa) \
- + ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \
- + sizeof(int32_t) : \
- + 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int32_t) - 1)))
- +
- #endif /* COMPAT_FREEBSD32 */
- MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
- @@ -560,6 +598,138 @@
- return (0);
- }
- +#ifdef COMPAT_FREEBSD32
- +static void
- +freebsd32_rt_metrics_in(struct rt_metrics32 *src, struct rt_metrics *dst)
- +{
- +
- + bzero(dst, sizeof(*dst));
- + CP(*src, *dst, rmx_mtu);
- + CP(*src, *dst, rmx_expire);
- + CP(*src, *dst, rmx_pksent);
- + CP(*src, *dst, rmx_weight);
- +}
- +
- +static void
- +freebsd32_rt_metrics_out(struct rt_metrics *src, struct rt_metrics32 *dst)
- +{
- +
- + bzero(dst, sizeof(*dst));
- + CP(*src, *dst, rmx_mtu);
- + CP(*src, *dst, rmx_expire);
- + CP(*src, *dst, rmx_pksent);
- + CP(*src, *dst, rmx_weight);
- +}
- +
- +static void
- +freebsd32_rt_msghdr_in(struct rt_msghdr32 *src, struct rt_msghdr *dst)
- +{
- +
- + bzero(dst, sizeof(*dst));
- + /* CP(*src, *dst, rtm_msglen); */ /* updated separately */
- + CP(*src, *dst, rtm_version);
- + CP(*src, *dst, rtm_type);
- + CP(*src, *dst, rtm_index);
- + CP(*src, *dst, rtm_flags);
- + CP(*src, *dst, rtm_addrs);
- + CP(*src, *dst, rtm_pid);
- + CP(*src, *dst, rtm_seq);
- + CP(*src, *dst, rtm_errno);
- + CP(*src, *dst, rtm_fmask);
- + CP(*src, *dst, rtm_inits);
- + freebsd32_rt_metrics_in(&src->rtm_rmx, &dst->rtm_rmx);
- +}
- +
- +static void
- +freebsd32_rt_msghdr_out(struct rt_msghdr *src, struct rt_msghdr32 *dst)
- +{
- +
- + bzero(dst, sizeof(*dst));
- + /* CP(*src, *dst, rtm_msglen); */ /* updated separately */
- + CP(*src, *dst, rtm_version);
- + CP(*src, *dst, rtm_type);
- + CP(*src, *dst, rtm_index);
- + CP(*src, *dst, rtm_flags);
- + CP(*src, *dst, rtm_addrs);
- + CP(*src, *dst, rtm_pid);
- + CP(*src, *dst, rtm_seq);
- + CP(*src, *dst, rtm_errno);
- + CP(*src, *dst, rtm_fmask);
- + CP(*src, *dst, rtm_inits);
- + freebsd32_rt_metrics_out(&src->rtm_rmx, &dst->rtm_rmx);
- +}
- +
- +static int
- +freebsd32_rt_mspace_len_in(caddr_t cp, caddr_t cplim, int *buflen)
- +{
- + struct sockaddr *sa;
- + int i;
- +
- + for (i = 0, *buflen = 0; i < RTAX_MAX && cp < cplim; i++) {
- + sa = (struct sockaddr *)cp;
- +
- + if (cp + sa->sa_len > cplim)
- + return (EINVAL);
- + cp += SA_SIZE32(sa);
- + *buflen += SA_SIZE(sa);
- + }
- + return (0);
- +}
- +
- +static int
- +freebsd32_rt_mspace_len_out(caddr_t cp, caddr_t cplim, int *buflen)
- +{
- + struct sockaddr *sa;
- + int i;
- +
- + for (i = 0, *buflen = 0; i < RTAX_MAX && cp < cplim; i++) {
- + sa = (struct sockaddr *)cp;
- +
- + if (cp + sa->sa_len > cplim)
- + return (EINVAL);
- + cp += SA_SIZE(sa);
- + *buflen += SA_SIZE32(sa);
- + }
- + return (0);
- +}
- +
- +static int
- +freebsd32_rt_mspace_in(caddr_t cp, caddr_t cp64, caddr_t cplim)
- +{
- + struct sockaddr *sa;
- + int i;
- +
- + for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
- + sa = (struct sockaddr *)cp;
- +
- + if (cp + sa->sa_len > cplim)
- + return (EINVAL);
- + memcpy(cp64, cp, SA_SIZE32(sa));
- + cp += SA_SIZE32(sa);
- + cp64 += SA_SIZE(sa);
- + }
- + return (0);
- +}
- +
- +static int
- +freebsd32_rt_mspace_out(caddr_t cp, caddr_t cp32, caddr_t cplim)
- +{
- + struct sockaddr *sa;
- + int i;
- +
- + for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
- + sa = (struct sockaddr *)cp;
- +
- + if (cp + sa->sa_len > cplim)
- + return (EINVAL);
- + memcpy(cp32, cp, SA_SIZE(sa));
- + cp += SA_SIZE(sa);
- + cp32 += SA_SIZE32(sa);
- + }
- + return (0);
- +}
- +#endif
- +
- /*ARGSUSED*/
- static int
- route_output(struct mbuf *m, struct socket *so)
- @@ -573,6 +743,14 @@
- struct ifnet *ifp = NULL;
- union sockaddr_union saun;
- sa_family_t saf = AF_UNSPEC;
- + size_t rtmlen;
- +#ifdef COMPAT_FREEBSD32
- + struct rt_msghdr32 *rtm32 = NULL;
- + int len32 = 0, rt_mspace_len = 0, wrap32 = 0;
- +
- + if (SV_CURPROC_FLAG(SV_ILP32))
- + wrap32 = 1;
- +#endif
- #define senderr(e) { error = e; goto flush;}
- if (m == NULL || ((m->m_len < sizeof(long)) &&
- @@ -581,17 +759,50 @@
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("route_output");
- len = m->m_pkthdr.len;
- - if (len < sizeof(*rtm) ||
- +
- +#ifdef COMPAT_FREEBSD32
- + if (wrap32) {
- + rtmlen = sizeof(*rtm32);
- + len32 = len;
- + } else
- +#endif
- + rtmlen = sizeof(*rtm);
- +
- + if (len < rtmlen ||
- len != mtod(m, struct rt_msghdr *)->rtm_msglen) {
- info.rti_info[RTAX_DST] = NULL;
- senderr(EINVAL);
- }
- - R_Malloc(rtm, struct rt_msghdr *, len);
- +
- +#ifdef COMPAT_FREEBSD32
- + if (wrap32) {
- + R_Malloc(rtm32, struct rt_msghdr32 *, len32);
- + if (rtm32 == NULL) {
- + info.rti_info[RTAX_DST] = NULL;
- + senderr(ENOBUFS);
- + }
- + m_copydata(m, 0, len32, (caddr_t)rtm32);
- + freebsd32_rt_mspace_len_in((caddr_t)(rtm32 + 1), len32 + (caddr_t)rtm32, &rt_mspace_len);
- + /* fixup len to alloc rtm of native size */
- + len = rt_mspace_len + sizeof(*rtm);
- + }
- +#endif
- + R_Zalloc(rtm, struct rt_msghdr *, len);
- if (rtm == NULL) {
- info.rti_info[RTAX_DST] = NULL;
- senderr(ENOBUFS);
- }
- - m_copydata(m, 0, len, (caddr_t)rtm);
- +
- +#ifdef COMPAT_FREEBSD32
- + if (wrap32) {
- + freebsd32_rt_msghdr_in(rtm32, rtm);
- + freebsd32_rt_mspace_in((caddr_t)(rtm32 + 1),
- + (caddr_t)(rtm + 1), (caddr_t)rtm32 + len32);
- + rtm->rtm_msglen = len;
- + } else
- +#endif
- + m_copydata(m, 0, len, (caddr_t)rtm);
- +
- if (rtm->rtm_version != RTM_VERSION) {
- info.rti_info[RTAX_DST] = NULL;
- senderr(EPROTONOSUPPORT);
- @@ -603,6 +814,16 @@
- info.rti_info[RTAX_DST] = NULL;
- senderr(EINVAL);
- }
- +/*
- + int i; uint16_t *j;
- +
- + for (i = 0; i * (int)sizeof(uint16_t) < len; i++) {
- + j = (uint16_t *)rtm;
- + if (i % 8 == 0)
- + printf("\n0x%04jx ", (uintmax_t)i*sizeof(uint16_t));
- + printf("%04x ", bswap16(j[i]));
- + }; printf("\n");
- +*/
- info.rti_flags = rtm->rtm_flags;
- if (info.rti_info[RTAX_DST] == NULL ||
- info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
- @@ -938,12 +1159,41 @@
- rp = sotorawcb(so);
- }
- if (rtm) {
- - m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
- - if (m->m_pkthdr.len < rtm->rtm_msglen) {
- - m_freem(m);
- - m = NULL;
- - } else if (m->m_pkthdr.len > rtm->rtm_msglen)
- - m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
- +#ifdef COMPAT_FREEBSD32
- + if (wrap32) {
- + int rt_mspace_len32;
- +
- + freebsd32_rt_mspace_len_out((caddr_t)(rtm + 1),
- + len + (caddr_t)rtm, &rt_mspace_len32);
- + len32 = rt_mspace_len32 + sizeof(*rtm32);
- + if (len32 > rtm32->rtm_msglen) {
- + struct rt_msghdr32 *new_rtm32;
- + R_Malloc(new_rtm32, struct rt_msghdr32 *, len32);
- + if (new_rtm32 == NULL)
- + senderr(ENOBUFS);
- + bcopy(rtm32, new_rtm32, rtm32->rtm_msglen);
- + Free(rtm32); rtm32 = new_rtm32;
- + }
- + freebsd32_rt_msghdr_out(rtm, rtm32);
- + rtm32->rtm_msglen = len32;
- + freebsd32_rt_mspace_out((caddr_t)(rtm + 1),
- + (caddr_t)(rtm32 + 1), (caddr_t)rtm + len);
- +
- + m_copyback(m, 0, rtm32->rtm_msglen, (caddr_t)rtm32);
- + if (m->m_pkthdr.len < rtm32->rtm_msglen) {
- + m_freem(m);
- + m = NULL;
- + } else if (m->m_pkthdr.len > rtm32->rtm_msglen)
- + m_adj(m, rtm32->rtm_msglen - m->m_pkthdr.len);
- + } else {
- +#endif
- + m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
- + if (m->m_pkthdr.len < rtm->rtm_msglen) {
- + m_freem(m);
- + m = NULL;
- + } else if (m->m_pkthdr.len > rtm->rtm_msglen)
- + m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
- + }
- }
- if (m) {
- M_SETFIB(m, so->so_fibnum);
- @@ -961,8 +1211,13 @@
- rt_dispatch(m, saf);
- }
- /* info.rti_info[RTAX_DST] (used above) can point inside of rtm */
- - if (rtm)
- + if (rtm) {
- Free(rtm);
- +#ifdef COMPAT_FREEBSD32
- + if (wrap32)
- + Free(rtm32);
- +#endif
- + }
- }
- return (error);
- #undef sa_equal
Add Comment
Please, Sign In to add comment