--- //depot/vendor/freebsd_6/src/sys/compat/freebsd32/freebsd32.h 2004/10/22 16:37:59 +++ //depot/yahoo/ybsd_6/src/sys/compat/freebsd32/freebsd32.h 2006/10/31 15:17:15 @@ -38,10 +39,6 @@ #define PTROUT_CP(src,dst,fld) \ do { (dst).fld = PTROUT((src).fld); } while (0) -struct timeval32 { - int32_t tv_sec; - int32_t tv_usec; -}; #define TV_CP(src,dst,fld) do { \ CP((src).fld,(dst).fld,tv_sec); \ CP((src).fld,(dst).fld,tv_usec); \ --- //depot/vendor/freebsd_6/src/sys/net/bpf.c 2007/02/17 13:28:41 +++ //depot/yahoo/ybsd_6/src/sys/net/bpf.c 2007/02/23 13:00:01 @@ -78,6 +79,24 @@ #define PRINET 26 /* interruptible */ +#ifdef __amd64__ +#define BPF_ALIGNMENT32 sizeof(int32_t) +#define BPF_WORDALIGN32(x) (((x)+(BPF_ALIGNMENT32-1))&~(BPF_ALIGNMENT32-1)) + +/* + * 32-bit version of structure prepended to each packet. We use this header + * instead of the standard one for 32-bit streams. We mark the a stream as + * 32-bit the first time we see a 32-bit compat ioctl request. + */ +struct bpf_hdr32 { + struct timeval32 bh_tstamp; /* time stamp */ + uint32_t bh_caplen; /* length of captured portion */ + uint32_t bh_datalen; /* original length of packet */ + uint16_t bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; +#endif + /* * bpf_iflist is a list of BPF interface structures, each corresponding to a * specific DLT. The same network interface might have several BPF interface @@ -677,6 +696,9 @@ case BIOCGDLTLIST: case BIOCGETIF: case BIOCGRTIMEOUT: +#ifdef __amd64__ + case BIOCGRTIMEOUT32: +#endif case BIOCGSTATS: case BIOCVERSION: case BIOCGRSIG: @@ -684,6 +706,9 @@ case FIONREAD: case BIOCLOCK: case BIOCSRTIMEOUT: +#ifdef __amd64__ + case BIOCSRTIMEOUT32: +#endif case BIOCIMMEDIATE: case TIOCGPGRP: break; @@ -691,6 +716,20 @@ return (EPERM); } } +#ifdef __amd64__ + /* + * If we see a 32-bit compat ioctl, mark the stream as 32-bit so + * that it will get 32-bit packet headers. + */ + switch (cmd) { + case BIOCSETF32: + case BIOCSETWF32: + case BIOCGRTIMEOUT32: + case BIOCSRTIMEOUT32: + d->bd_compat32 = 1; + } +#endif + switch (cmd) { default: @@ -756,6 +795,10 @@ */ case BIOCSETF: case BIOCSETWF: +#ifdef __amd64__ + case BIOCSETF32: + case BIOCSETWF32: +#endif error = bpf_setf(d, (struct bpf_program *)addr, cmd); break; @@ -844,9 +887,22 @@ * Set read timeout. */ case BIOCSRTIMEOUT: +#ifdef __amd64__ + case BIOCSRTIMEOUT32: +#endif { struct timeval *tv = (struct timeval *)addr; +#ifdef __amd64__ + struct timeval32 *tv32 = (struct timeval32 *)addr; + struct timeval tv64; + if (cmd == BIOCSRTIMEOUT32) { + tv = &tv64; + tv->tv_sec = tv32->tv_sec; + tv->tv_usec = tv32->tv_usec; + } +#endif + /* * Subtract 1 tick from tvtohz() since this isn't * a one-shot timer. @@ -860,11 +916,26 @@ * Get read timeout. */ case BIOCGRTIMEOUT: +#ifdef __amd64__ + case BIOCGRTIMEOUT32: +#endif { struct timeval *tv = (struct timeval *)addr; +#ifdef __amd64__ + struct timeval32 *tv32 = (struct timeval32 *)addr; + struct timeval tv64; + if (cmd == BIOCGRTIMEOUT32) + tv = &tv64; +#endif tv->tv_sec = d->bd_rtout / hz; tv->tv_usec = (d->bd_rtout % hz) * tick; +#ifdef __amd64__ + if (cmd == BIOCGRTIMEOUT32) { + tv32->tv_sec = tv->tv_sec; + tv32->tv_usec = tv->tv_usec; + } +#endif break; } @@ -980,7 +1051,19 @@ { struct bpf_insn *fcode, *old; u_int wfilter, flen, size; +#ifdef __amd64__ + struct bpf_program32 *fp32; + struct bpf_program fp_swab; + if (cmd == BIOCSETWF32 || cmd == BIOCSETF32) { + fp32 = (struct bpf_program32 *)fp; + fp_swab.bf_len = fp32->bf_len; + fp_swab.bf_insns = (struct bpf_insn *)(uintptr_t)fp32->bf_insns; + fp = &fp_swab; + if (cmd == BIOCSETWF32) + cmd = BIOCSETWF; + } +#endif if (cmd == BIOCSETWF) { old = d->bd_wfilter; wfilter = 1; @@ -1321,6 +1404,9 @@ void (*cpfn)(const void *, void *, size_t), struct timeval *tv) { struct bpf_hdr *hp; +#ifdef __amd64__ + struct bpf_hdr32 *hp32; +#endif int totlen, curlen; int hdrlen = d->bd_bif->bif_hdrlen; int do_wakeup = 0; @@ -1339,6 +1425,11 @@ /* * Round up the end of the previous packet to the next longword. */ +#ifdef __amd64__ + if (d->bd_compat32) + curlen = BPF_WORDALIGN32(d->bd_slen); + else +#endif curlen = BPF_WORDALIGN(d->bd_slen); if (curlen + totlen > d->bd_bufsize) { /* @@ -1366,7 +1457,23 @@ */ do_wakeup = 1; +#ifdef __amd64__ /* + * If this is a 32-bit stream, then stick a 32-bit header at the + * front and copy the data into the buffer. + */ + if (d->bd_compat32) { + hp32 = (struct bpf_hdr32 *)(d->bd_sbuf + curlen); + hp32->bh_tstamp.tv_sec = tv->tv_sec; + hp32->bh_tstamp.tv_usec = tv->tv_usec; + hp32->bh_datalen = pktlen; + hp32->bh_hdrlen = hdrlen; + (*cpfn)(pkt, (u_char *)hp32 + hdrlen, + (hp32->bh_caplen = totlen - hdrlen)); + goto done; + } +#endif + /* * Append the bpf header. */ hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); @@ -1377,6 +1484,9 @@ * Copy the packet data into the store buffer and update its length. */ (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); +#ifdef __amd64__ +done: +#endif d->bd_slen = curlen + totlen; if (do_wakeup) --- //depot/vendor/freebsd_6/src/sys/net/bpf.h 2007/01/19 15:28:39 +++ //depot/yahoo/ybsd_6/src/sys/net/bpf.h 2007/01/22 17:35:27 @@ -65,6 +66,13 @@ struct bpf_insn *bf_insns; }; +#if defined(__amd64__) || defined(COMPAT_32BIT) +struct bpf_program32 { + u_int bf_len; + uint32_t bf_insns; +}; +#endif + /* * Struct returned by BIOCGSTATS. */ @@ -95,6 +103,9 @@ #define BIOCGBLEN _IOR('B',102, u_int) #define BIOCSBLEN _IOWR('B',102, u_int) #define BIOCSETF _IOW('B',103, struct bpf_program) +#if defined(__amd64__) || defined(COMPAT_32BIT) +#define BIOCSETF32 _IOW('B', 103, struct bpf_program32) +#endif #define BIOCFLUSH _IO('B',104) #define BIOCPROMISC _IO('B',105) #define BIOCGDLT _IOR('B',106, u_int) @@ -102,6 +113,10 @@ #define BIOCSETIF _IOW('B',108, struct ifreq) #define BIOCSRTIMEOUT _IOW('B',109, struct timeval) #define BIOCGRTIMEOUT _IOR('B',110, struct timeval) +#if defined(__amd64__) || defined(COMPAT_32BIT) +#define BIOCSRTIMEOUT32 _IOW('B',109, struct timeval32) +#define BIOCGRTIMEOUT32 _IOR('B',110, struct timeval32) +#endif #define BIOCGSTATS _IOR('B',111, struct bpf_stat) #define BIOCIMMEDIATE _IOW('B',112, u_int) #define BIOCVERSION _IOR('B',113, struct bpf_version) @@ -115,6 +130,9 @@ #define BIOCGDLTLIST _IOWR('B',121, struct bpf_dltlist) #define BIOCLOCK _IO('B', 122) #define BIOCSETWF _IOW('B',123, struct bpf_program) +#if defined(__amd64__) || defined(COMPAT_32BIT) +#define BIOCSETWF32 _IOW('B',123, struct bpf_program32) +#endif /* * Structure prepended to each packet. --- //depot/vendor/freebsd_6/src/sys/net/bpfdesc.h 2007/01/19 15:28:39 +++ //depot/yahoo/ybsd_6/src/sys/net/bpfdesc.h 2007/01/22 17:35:27 @@ -97,6 +98,9 @@ pid_t bd_pid; /* PID which created descriptor */ char bd_pcomm[MAXCOMLEN + 1]; int bd_locked; /* true if descriptor is locked */ +#ifdef __amd64__ + int bd_compat32; +#endif }; /* Values for bd_state */ --- //depot/vendor/freebsd_6/src/sys/net/rtsock.c 2007/04/09 13:28:58 +++ //depot/yahoo/ybsd_6/src/sys/net/rtsock.c 2007/04/23 12:03:21 @@ -51,6 +52,49 @@ #include +#ifdef SCTL_MASK32 +#include +#include + +struct if_data32 { + uint8_t ifi_type; + uint8_t ifi_physical; + uint8_t ifi_addrlen; + uint8_t ifi_hdrlen; + uint8_t ifi_link_state; + uint8_t ifi_recvquota; + uint8_t ifi_xmitquota; + uint8_t ifi_datalen; + uint32_t ifi_mtu; + uint32_t ifi_metric; + uint32_t ifi_baudrate; + uint32_t ifi_ipackets; + uint32_t ifi_ierrors; + uint32_t ifi_opackets; + uint32_t ifi_oerrors; + uint32_t ifi_collisions; + uint32_t ifi_ibytes; + uint32_t ifi_obytes; + uint32_t ifi_imcasts; + uint32_t ifi_omcasts; + uint32_t ifi_iqdrops; + uint32_t ifi_noproto; + uint32_t ifi_hwassist; + int32_t ifi_epoch; + struct timeval32 ifi_lastchange; +}; + +struct if_msghdr32 { + uint16_t ifm_msglen; + uint8_t ifm_version; + uint8_t ifm_type; + int32_t ifm_addrs; + int32_t ifm_flags; + uint16_t ifm_index; + struct if_data32 ifm_data; +}; +#endif + MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables"); /* NB: these are not modified */ @@ -745,6 +789,12 @@ break; case RTM_IFINFO: +#ifdef SCTL_MASK32 + if (w != NULL && w->w_req->flags & SCTL_MASK32) { + len = sizeof(struct if_msghdr32); + break; + } +#endif len = sizeof(struct if_msghdr); break; @@ -1088,6 +1138,39 @@ return (error); } +#ifdef SCTL_MASK32 +static void +copy_ifdata32(struct if_data *src, struct if_data32 *dst) +{ + + CP(*src, *dst, ifi_type); + CP(*src, *dst, ifi_physical); + CP(*src, *dst, ifi_addrlen); + CP(*src, *dst, ifi_hdrlen); + CP(*src, *dst, ifi_link_state); + CP(*src, *dst, ifi_recvquota); + CP(*src, *dst, ifi_xmitquota); + CP(*src, *dst, ifi_datalen); + CP(*src, *dst, ifi_mtu); + CP(*src, *dst, ifi_metric); + CP(*src, *dst, ifi_baudrate); + CP(*src, *dst, ifi_ipackets); + CP(*src, *dst, ifi_ierrors); + CP(*src, *dst, ifi_opackets); + CP(*src, *dst, ifi_oerrors); + CP(*src, *dst, ifi_collisions); + CP(*src, *dst, ifi_ibytes); + CP(*src, *dst, ifi_obytes); + CP(*src, *dst, ifi_imcasts); + CP(*src, *dst, ifi_omcasts); + CP(*src, *dst, ifi_iqdrops); + CP(*src, *dst, ifi_noproto); + CP(*src, *dst, ifi_hwassist); + CP(*src, *dst, ifi_epoch); + TV_CP(*src, *dst, ifi_lastchange); +} +#endif + static int sysctl_iflist(int af, struct walkarg *w) { @@ -1108,12 +1191,28 @@ if (w->w_req && w->w_tmem) { struct if_msghdr *ifm; +#ifdef SCTL_MASK32 + if (w->w_req->flags & SCTL_MASK32) { + struct if_msghdr32 *ifm32; + + ifm32 = (struct if_msghdr32 *)w->w_tmem; + ifm32->ifm_index = ifp->if_index; + ifm32->ifm_flags = ifp->if_flags | + ifp->if_drv_flags; + copy_ifdata32(&ifp->if_data, &ifm32->ifm_data); + ifm32->ifm_addrs = info.rti_addrs; + goto sysctl_out; + } +#endif ifm = (struct if_msghdr *)w->w_tmem; ifm->ifm_index = ifp->if_index; ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; ifm->ifm_data = ifp->if_data; ifm->ifm_addrs = info.rti_addrs; - error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len); +#ifdef SCTL_MASK32 + sysctl_out: +#endif + error = SYSCTL_OUT(w->w_req, w->w_tmem, len); if (error) goto done; } --- //depot/vendor/freebsd_6/src/sys/sys/_timeval.h 2006/06/23 17:28:26 +++ //depot/yahoo/ybsd_6/src/sys/sys/_timeval.h 2006/10/31 15:17:15 @@ -53,4 +54,11 @@ suseconds_t tv_usec; /* and microseconds */ }; +#if defined(__amd64__) || defined(COMPAT_32BIT) +struct timeval32 { + int tv_sec; + int tv_usec; +}; +#endif + #endif /* !_SYS__TIMEVAL_H_ */