mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
Move ISO88025 source routing information into sockaddr_dl's sdl_data
field. This returns the sdl_data field to a variable-length field. More importantly, this prevents a easily-reproduceable data-corruption bug when the interface name plus the hardware address exceed the sdl_data field's original 12 byte limit. However, token-ring interfaces may still overflow the new sdl_data field's 46 byte limit if the interface name exceeds 6 characters (since 6 characters for interface name plus 6 for hardware address plus 34 for source routing = the size of sdl_data). Further refinements could overcome this limitation but would break binary compatibility; this commit only addresses fixing the bug for commonly-occuring cases without breaking binary compatibility with the intention that the functionality can be MFC'ed to -stable. See message ID's (both send to -arch): 20020421013332.F87395-100000@gateway.posi.net 20020430181359.G11009-300000@gateway.posi.net for a more thorough description of the bug addressed and how to reproduce it. Approved by: silence on -arch and -net Sponsored by: NTT Multimedia Communications Labs MFC after: 1 week
This commit is contained in:
parent
0d93809e04
commit
42fdfc126a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96184
@ -66,10 +66,8 @@ struct sockaddr_dl {
|
||||
u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */
|
||||
u_char sdl_alen; /* link level address length */
|
||||
u_char sdl_slen; /* link layer selector length */
|
||||
char sdl_data[12]; /* minimum work area, can be larger;
|
||||
char sdl_data[46]; /* minimum work area, can be larger;
|
||||
contains both if name and ll address */
|
||||
u_short sdl_rcf; /* source routing control */
|
||||
u_short sdl_route[16]; /* source routing information */
|
||||
};
|
||||
|
||||
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
|
||||
|
@ -253,8 +253,8 @@ iso88025_output(ifp, m, dst, rt0)
|
||||
|
||||
/* Calculate routing info length based on arp table entry */
|
||||
if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway))
|
||||
if (sdl->sdl_rcf != NULL)
|
||||
rif_len = TR_RCF_RIFLEN(sdl->sdl_rcf);
|
||||
if (SDL_ISO88025(sdl)->trld_rcf != NULL)
|
||||
rif_len = TR_RCF_RIFLEN(SDL_ISO88025(sdl)->trld_rcf);
|
||||
|
||||
/* Generate a generic 802.5 header for the packet */
|
||||
gen_th.ac = TR_AC;
|
||||
@ -264,9 +264,10 @@ iso88025_output(ifp, m, dst, rt0)
|
||||
if (rif_len) {
|
||||
gen_th.iso88025_shost[0] |= TR_RII;
|
||||
if (rif_len > 2) {
|
||||
gen_th.rcf = sdl->sdl_rcf;
|
||||
gen_th.rcf = SDL_ISO88025(sdl)->trld_rcf;
|
||||
(void)memcpy((caddr_t)gen_th.rd,
|
||||
(caddr_t)sdl->sdl_route, rif_len - 2);
|
||||
(caddr_t)SDL_ISO88025(sdl)->trld_route,
|
||||
rif_len - 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,15 @@ struct iso88025_sockaddr_data {
|
||||
u_char fc;
|
||||
};
|
||||
|
||||
struct iso88025_sockaddr_dl_data {
|
||||
u_short trld_rcf;
|
||||
u_short *trld_route[RIF_MAX_LEN];
|
||||
};
|
||||
|
||||
#define SDL_ISO88025(s) ((struct iso88025_sockaddr_dl_data *) \
|
||||
((s)->sdl_data + min((s)->sdl_nlen + \
|
||||
(s)->sdl_alen + (s)->sdl_slen, 12)))
|
||||
|
||||
/*
|
||||
* Structure of a 48-bit iso 802.5 address.
|
||||
* ( We could also add the 16 bit addresses as a union)
|
||||
|
@ -571,6 +571,7 @@ in_arpinput(m)
|
||||
struct ether_header *eh;
|
||||
struct arc_header *arh;
|
||||
struct iso88025_header *th = (struct iso88025_header *)0;
|
||||
struct iso88025_sockaddr_dl_data *trld;
|
||||
register struct llinfo_arp *la = 0;
|
||||
register struct rtentry *rt;
|
||||
struct ifaddr *ifa;
|
||||
@ -697,7 +698,6 @@ match:
|
||||
}
|
||||
(void)memcpy(LLADDR(sdl), ar_sha(ah),
|
||||
sdl->sdl_alen = ah->ar_hln);
|
||||
sdl->sdl_rcf = (u_short)0;
|
||||
/*
|
||||
* If we receive an arp from a token-ring station over
|
||||
* a token-ring nic then try to save the source
|
||||
@ -705,13 +705,14 @@ match:
|
||||
*/
|
||||
if (ifp->if_type == IFT_ISO88025) {
|
||||
th = (struct iso88025_header *)m->m_pkthdr.header;
|
||||
trld = SDL_ISO88025(sdl);
|
||||
rif_len = TR_RCF_RIFLEN(th->rcf);
|
||||
if ((th->iso88025_shost[0] & TR_RII) &&
|
||||
(rif_len > 2)) {
|
||||
sdl->sdl_rcf = th->rcf;
|
||||
sdl->sdl_rcf ^= htons(TR_RCF_DIR);
|
||||
memcpy(sdl->sdl_route, th->rd, rif_len - 2);
|
||||
sdl->sdl_rcf &= ~htons(TR_RCF_BCST_MASK);
|
||||
trld->trld_rcf = th->rcf;
|
||||
trld->trld_rcf ^= htons(TR_RCF_DIR);
|
||||
memcpy(trld->trld_route, th->rd, rif_len - 2);
|
||||
trld->trld_rcf &= ~htons(TR_RCF_BCST_MASK);
|
||||
/*
|
||||
* Set up source routing information for
|
||||
* reply packet (XXX)
|
||||
@ -725,9 +726,7 @@ match:
|
||||
m->m_data -= 8;
|
||||
m->m_len += 8;
|
||||
m->m_pkthdr.len += 8;
|
||||
th->rcf = sdl->sdl_rcf;
|
||||
} else {
|
||||
sdl->sdl_rcf = (u_short)0;
|
||||
th->rcf = trld->trld_rcf;
|
||||
}
|
||||
if (rt->rt_expire)
|
||||
rt->rt_expire = time_second + arpt_keep;
|
||||
|
Loading…
Reference in New Issue
Block a user