--- src/sys/net/rtsock.c 2006/05/06 02:43:12 1.31 +++ src/sys/net/rtsock.c 2006/05/18 13:51:45 1.32 @@ -743,6 +743,7 @@ rt_msghdrsize(int type) case RTM_IFINFO: return sizeof(struct if_msghdr); case RTM_IFANNOUNCE: + case RTM_IEEE80211: return sizeof(struct if_announcemsghdr); default: return sizeof(struct rt_msghdr); @@ -1054,33 +1055,84 @@ rt_newmaddrmsg(int cmd, struct ifmultiad rts_input(m, familyof(ifma->ifma_addr)); } -/* - * This is called to generate routing socket messages indicating - * network interface arrival and departure. - */ -void -rt_ifannouncemsg(struct ifnet *ifp, int what) +static struct mbuf * +rt_makeifannouncemsg(struct ifnet *ifp, int type, int what, + struct rt_addrinfo *info) { - struct rt_addrinfo addrinfo; - struct mbuf *m; struct if_announcemsghdr *ifan; + struct mbuf *m; if (route_cb.any_count == 0) - return; + return NULL; - bzero(&addrinfo, sizeof addrinfo); - m = rt_msg_mbuf(RTM_IFANNOUNCE, &addrinfo); + bzero(info, sizeof(*info)); + m = rt_msg_mbuf(type, info); if (m == NULL) - return; + return NULL; ifan = mtod(m, struct if_announcemsghdr *); ifan->ifan_index = ifp->if_index; strlcpy(ifan->ifan_name, ifp->if_xname, sizeof ifan->ifan_name); ifan->ifan_what = what; + return m; +} + +/* + * This is called to generate routing socket messages indicating + * IEEE80211 wireless events. + * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way. + */ +void +rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len) +{ + struct rt_addrinfo info; + struct mbuf *m; + m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info); + if (m == NULL) + return; + + /* + * Append the ieee80211 data. Try to stick it in the + * mbuf containing the ifannounce msg; otherwise allocate + * a new mbuf and append. + * + * NB: we assume m is a single mbuf. + */ + if (data_len > M_TRAILINGSPACE(m)) { + struct mbuf *n = m_get(M_NOWAIT, MT_DATA); + if (n == NULL) { + m_freem(m); + return; + } + bcopy(data, mtod(n, void *), data_len); + n->m_len = data_len; + m->m_next = n; + } else if (data_len > 0) { + bcopy(data, mtod(m, u_int8_t *) + m->m_len, data_len); + m->m_len += data_len; + } + if (m->m_flags & M_PKTHDR) + m->m_pkthdr.len += data_len; + mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len; rts_input(m, 0); } +/* + * This is called to generate routing socket messages indicating + * network interface arrival and departure. + */ +void +rt_ifannouncemsg(struct ifnet *ifp, int what) +{ + struct rt_addrinfo addrinfo; + struct mbuf *m; + + m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &addrinfo); + if (m != NULL) + rts_input(m, 0); +} + static int resizewalkarg(struct walkarg *w, int len) {