Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_fwsubr.c
Show First 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, | ||||
uint8_t speed; | uint8_t speed; | ||||
uint16_t psize, fsize, dsize; | uint16_t psize, fsize, dsize; | ||||
struct mbuf *mtail; | struct mbuf *mtail; | ||||
int unicast, dgl, foff; | int unicast, dgl, foff; | ||||
static int next_dgl; | static int next_dgl; | ||||
#if defined(INET) || defined(INET6) | #if defined(INET) || defined(INET6) | ||||
int is_gw = 0; | int is_gw = 0; | ||||
#endif | #endif | ||||
int af = dst->sa_family; | |||||
#ifdef MAC | #ifdef MAC | ||||
error = mac_ifnet_check_transmit(ifp, m); | error = mac_ifnet_check_transmit(ifp, m); | ||||
if (error) | if (error) | ||||
goto bad; | goto bad; | ||||
#endif | #endif | ||||
if (!((ifp->if_flags & IFF_UP) && | if (!((ifp->if_flags & IFF_UP) && | ||||
(ifp->if_drv_flags & IFF_DRV_RUNNING))) { | (ifp->if_drv_flags & IFF_DRV_RUNNING))) { | ||||
error = ENETDOWN; | error = ENETDOWN; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
#if defined(INET) || defined(INET6) | #if defined(INET) || defined(INET6) | ||||
if (ro != NULL) | if (ro != NULL) | ||||
is_gw = (ro->ro_flags & RT_HAS_GW) != 0; | is_gw = (ro->ro_flags & RT_HAS_GW) != 0; | ||||
if (is_gw) | |||||
af = ro->ro_dst.sa_family; | |||||
#endif | #endif | ||||
/* | /* | ||||
* For unicast, we make a tag to store the lladdr of the | * For unicast, we make a tag to store the lladdr of the | ||||
* destination. This might not be the first time we have seen | * destination. This might not be the first time we have seen | ||||
* the packet (for instance, the arp code might be trying to | * the packet (for instance, the arp code might be trying to | ||||
* re-send it after receiving an arp reply) so we only | * re-send it after receiving an arp reply) so we only | ||||
* allocate a tag if there isn't one there already. For | * allocate a tag if there isn't one there already. For | ||||
* multicast, we will eventually use a different tag to store | * multicast, we will eventually use a different tag to store | ||||
Show All 11 Lines | if (!mtag) { | ||||
} | } | ||||
m_tag_prepend(m, mtag); | m_tag_prepend(m, mtag); | ||||
} | } | ||||
destfw = (struct fw_hwaddr *)(mtag + 1); | destfw = (struct fw_hwaddr *)(mtag + 1); | ||||
} else { | } else { | ||||
destfw = NULL; | destfw = NULL; | ||||
} | } | ||||
switch (af) { | |||||
#ifdef INET | |||||
case AF_INET: | |||||
type = ETHERTYPE_IP; | |||||
break; | |||||
case AF_ARP: | |||||
type = ETHERTYPE_ARP; | |||||
break; | |||||
#endif | |||||
#ifdef INET6 | |||||
case AF_INET6: | |||||
type = ETHERTYPE_IPV6; | |||||
break; | |||||
#endif | |||||
default: | |||||
if_printf(ifp, "can't handle af%d\n", af); | |||||
error = EAFNOSUPPORT; | |||||
goto bad; | |||||
} | |||||
switch (dst->sa_family) { | switch (dst->sa_family) { | ||||
#ifdef INET | #ifdef INET | ||||
case AF_INET: | case AF_INET: | ||||
/* | /* | ||||
* Only bother with arp for unicast. Allocation of | * Only bother with arp for unicast. Allocation of | ||||
* channels etc. for firewire is quite different and | * channels etc. for firewire is quite different and | ||||
* doesn't fit into the arp model. | * doesn't fit into the arp model. | ||||
*/ | */ | ||||
if (unicast) { | if (unicast) { | ||||
error = arpresolve(ifp, is_gw, m, dst, | error = arpresolve(ifp, is_gw, m, dst, | ||||
(u_char *) destfw, NULL, NULL); | (u_char *) destfw, NULL, NULL); | ||||
if (error) | if (error) | ||||
return (error == EWOULDBLOCK ? 0 : error); | return (error == EWOULDBLOCK ? 0 : error); | ||||
} | } | ||||
type = ETHERTYPE_IP; | |||||
break; | break; | ||||
case AF_ARP: | case AF_ARP: | ||||
{ | { | ||||
struct arphdr *ah; | struct arphdr *ah; | ||||
ah = mtod(m, struct arphdr *); | ah = mtod(m, struct arphdr *); | ||||
ah->ar_hrd = htons(ARPHRD_IEEE1394); | ah->ar_hrd = htons(ARPHRD_IEEE1394); | ||||
type = ETHERTYPE_ARP; | |||||
if (unicast) | if (unicast) | ||||
*destfw = *(struct fw_hwaddr *) ar_tha(ah); | *destfw = *(struct fw_hwaddr *) ar_tha(ah); | ||||
/* | /* | ||||
* The standard arp code leaves a hole for the target | * The standard arp code leaves a hole for the target | ||||
* hardware address which we need to close up. | * hardware address which we need to close up. | ||||
*/ | */ | ||||
bcopy(ar_tpa(ah), ar_tha(ah), ah->ar_pln); | bcopy(ar_tpa(ah), ar_tha(ah), ah->ar_pln); | ||||
m_adj(m, -ah->ar_hln); | m_adj(m, -ah->ar_hln); | ||||
break; | break; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
case AF_INET6: | case AF_INET6: | ||||
if (unicast) { | if (unicast) { | ||||
error = nd6_resolve(fc->fc_ifp, is_gw, m, dst, | error = nd6_resolve(fc->fc_ifp, is_gw, m, dst, | ||||
(u_char *) destfw, NULL, NULL); | (u_char *) destfw, NULL, NULL); | ||||
if (error) | if (error) | ||||
return (error == EWOULDBLOCK ? 0 : error); | return (error == EWOULDBLOCK ? 0 : error); | ||||
} | } | ||||
type = ETHERTYPE_IPV6; | |||||
break; | break; | ||||
#endif | #endif | ||||
default: | default: | ||||
if_printf(ifp, "can't handle af%d\n", dst->sa_family); | if_printf(ifp, "can't handle af%d\n", dst->sa_family); | ||||
error = EAFNOSUPPORT; | error = EAFNOSUPPORT; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 663 Lines • Show Last 20 Lines |