[LLC]: Fix sockaddr, only need to provide one MAC address not three.

parent 1cca41e2
...@@ -12,20 +12,17 @@ ...@@ -12,20 +12,17 @@
* *
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
*/ */
#define __LLC_SOCK_SIZE__ 28 /* sizeof(sockaddr_llc), word align. */ #define __LLC_SOCK_SIZE__ 16 /* sizeof(sockaddr_llc), word align. */
struct sockaddr_llc { struct sockaddr_llc {
sa_family_t sllc_family; /* AF_LLC */ sa_family_t sllc_family; /* AF_LLC */
sa_family_t sllc_arphrd; /* ARPHRD_ETHER */ sa_family_t sllc_arphrd; /* ARPHRD_ETHER */
unsigned char sllc_test; unsigned char sllc_test;
unsigned char sllc_xid; unsigned char sllc_xid;
unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */ unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */
unsigned char sllc_dsap; unsigned char sllc_sap;
unsigned char sllc_ssap; unsigned char sllc_mac[IFHWADDRLEN];
unsigned char sllc_dmac[IFHWADDRLEN];
unsigned char sllc_smac[IFHWADDRLEN];
unsigned char sllc_mmac[IFHWADDRLEN];
unsigned char __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 - unsigned char __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 -
sizeof(unsigned char) * 5 - IFHWADDRLEN * 3]; sizeof(unsigned char) * 4 - IFHWADDRLEN];
}; };
/* sockopt definitions. */ /* sockopt definitions. */
......
...@@ -246,32 +246,20 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) ...@@ -246,32 +246,20 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct llc_opt *llc = llc_sk(sk); struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap; struct llc_sap *sap;
struct net_device *dev = NULL;
int rc = -EINVAL; int rc = -EINVAL;
if (!sk->sk_zapped) if (!sk->sk_zapped)
goto out; goto out;
/* bind to a specific mac, optional. */
if (!llc_mac_null(addr->sllc_smac)) {
rtnl_lock();
dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
rtnl_unlock();
rc = -ENETUNREACH;
if (!dev)
goto out;
dev_hold(dev);
llc->dev = dev;
}
/* bind to a specific sap, optional. */ /* bind to a specific sap, optional. */
if (!addr->sllc_ssap) { if (!addr->sllc_sap) {
rc = -EUSERS; rc = -EUSERS;
addr->sllc_ssap = llc_ui_autoport(); addr->sllc_sap = llc_ui_autoport();
if (!addr->sllc_ssap) if (!addr->sllc_sap)
goto out; goto out;
} }
sap = llc_sap_find(addr->sllc_ssap); sap = llc_sap_find(addr->sllc_sap);
if (!sap) { if (!sap) {
sap = llc_sap_open(addr->sllc_ssap, NULL); sap = llc_sap_open(addr->sllc_sap, NULL);
rc = -EBUSY; /* some other network layer is using the sap */ rc = -EBUSY; /* some other network layer is using the sap */
if (!sap) if (!sap)
goto out; goto out;
...@@ -279,20 +267,14 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) ...@@ -279,20 +267,14 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
struct llc_addr laddr, daddr; struct llc_addr laddr, daddr;
struct sock *ask; struct sock *ask;
rc = -EUSERS; /* can't get exclusive use of sap */
if (!dev && llc_mac_null(addr->sllc_mmac))
goto out;
memset(&laddr, 0, sizeof(laddr)); memset(&laddr, 0, sizeof(laddr));
memset(&daddr, 0, sizeof(daddr)); memset(&daddr, 0, sizeof(daddr));
if (!llc_mac_null(addr->sllc_mmac)) { /*
if (sk->sk_type != SOCK_DGRAM) { * FIXME: check if the the address is multicast,
rc = -EOPNOTSUPP; * only SOCK_DGRAM can do this.
goto out; */
} memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
memcpy(laddr.mac, addr->sllc_mmac, IFHWADDRLEN); laddr.lsap = addr->sllc_sap;
} else
memcpy(laddr.mac, addr->sllc_smac, IFHWADDRLEN);
laddr.lsap = addr->sllc_ssap;
rc = -EADDRINUSE; /* mac + sap clash. */ rc = -EADDRINUSE; /* mac + sap clash. */
ask = llc_lookup_established(sap, &daddr, &laddr); ask = llc_lookup_established(sap, &daddr, &laddr);
if (ask) { if (ask) {
...@@ -300,11 +282,9 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) ...@@ -300,11 +282,9 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
goto out; goto out;
} }
} }
llc->laddr.lsap = addr->sllc_ssap; llc->laddr.lsap = addr->sllc_sap;
if (llc->dev) if (llc->dev)
memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN); memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
llc->daddr.lsap = addr->sllc_dsap;
memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
memcpy(&llc->addr, addr, sizeof(llc->addr)); memcpy(&llc->addr, addr, sizeof(llc->addr));
/* assign new connection to its SAP */ /* assign new connection to its SAP */
llc_sap_add_socket(sap, sk); llc_sap_add_socket(sap, sk);
...@@ -337,7 +317,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) ...@@ -337,7 +317,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
int rc = -EINVAL; int rc = -EINVAL;
dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_ssap); dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
if (!sk->sk_zapped || addrlen != sizeof(*addr)) if (!sk->sk_zapped || addrlen != sizeof(*addr))
goto out; goto out;
rc = -EAFNOSUPPORT; rc = -EAFNOSUPPORT;
...@@ -416,6 +396,8 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -416,6 +396,8 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
rc = llc_ui_autobind(sock, addr); rc = llc_ui_autobind(sock, addr);
if (rc) if (rc)
goto out; goto out;
llc->daddr.lsap = addr->sllc_sap;
memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
} }
if (!llc->dev) { if (!llc->dev) {
rc = -ENODEV; rc = -ENODEV;
...@@ -435,7 +417,7 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -435,7 +417,7 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
sk->sk_state = TCP_SYN_SENT; sk->sk_state = TCP_SYN_SENT;
llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap); llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap);
rc = llc_establish_connection(sk, dev->dev_addr, rc = llc_establish_connection(sk, dev->dev_addr,
addr->sllc_dmac, addr->sllc_dsap); addr->sllc_mac, addr->sllc_sap);
if (rc) { if (rc) {
dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__); dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
...@@ -628,7 +610,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -628,7 +610,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
int rc = -EOPNOTSUPP; int rc = -EOPNOTSUPP;
dprintk("%s: accepting on %02X\n", __FUNCTION__, dprintk("%s: accepting on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_ssap); llc_sk(sk)->addr.sllc_sap);
lock_sock(sk); lock_sock(sk);
if (sk->sk_type != SOCK_STREAM) if (sk->sk_type != SOCK_STREAM)
goto out; goto out;
...@@ -640,7 +622,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -640,7 +622,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
if (rc) if (rc)
goto out; goto out;
dprintk("%s: got a new connection on %02X\n", __FUNCTION__, dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_ssap); llc_sk(sk)->addr.sllc_sap);
skb = skb_dequeue(&sk->sk_receive_queue); skb = skb_dequeue(&sk->sk_receive_queue);
rc = -EINVAL; rc = -EINVAL;
if (!skb->sk) if (!skb->sk)
...@@ -656,8 +638,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -656,8 +638,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
llc = llc_sk(sk); llc = llc_sk(sk);
newllc = llc_sk(newsk); newllc = llc_sk(newsk);
memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr)); memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr));
memcpy(newllc->addr.sllc_dmac, newllc->daddr.mac, IFHWADDRLEN);
newllc->addr.sllc_dsap = newllc->daddr.lsap;
newllc->link = llc_ui_next_link_no(newllc->laddr.lsap); newllc->link = llc_ui_next_link_no(newllc->laddr.lsap);
/* put original socket back into a clean listen state. */ /* put original socket back into a clean listen state. */
...@@ -665,7 +645,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -665,7 +645,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
sk->sk_ack_backlog--; sk->sk_ack_backlog--;
skb->sk = NULL; skb->sk = NULL;
dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__, dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_ssap, newllc->addr.sllc_dsap); llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
frees: frees:
kfree_skb(skb); kfree_skb(skb);
out: out:
...@@ -792,18 +772,18 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -792,18 +772,18 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
if (rc) if (rc)
goto out; goto out;
if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) { if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_dmac, llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_dsap); addr->sllc_sap);
goto out; goto out;
} }
if (addr->sllc_test) { if (addr->sllc_test) {
llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_dmac, llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_dsap); addr->sllc_sap);
goto out; goto out;
} }
if (addr->sllc_xid) { if (addr->sllc_xid) {
llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_dmac, llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_dsap); addr->sllc_sap);
goto out; goto out;
} }
rc = -ENOPROTOOPT; rc = -ENOPROTOOPT;
...@@ -851,17 +831,17 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -851,17 +831,17 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
goto out; goto out;
if(llc->dev) if(llc->dev)
sllc.sllc_arphrd = llc->dev->type; sllc.sllc_arphrd = llc->dev->type;
sllc.sllc_dsap = llc->daddr.lsap; sllc.sllc_sap = llc->daddr.lsap;
memcpy(&sllc.sllc_dmac, &llc->daddr.mac, IFHWADDRLEN); memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
} else { } else {
rc = -EINVAL; rc = -EINVAL;
if (!llc->sap) if (!llc->sap)
goto out; goto out;
sllc.sllc_ssap = llc->sap->laddr.lsap; sllc.sllc_sap = llc->sap->laddr.lsap;
if (llc->dev) { if (llc->dev) {
sllc.sllc_arphrd = llc->dev->type; sllc.sllc_arphrd = llc->dev->type;
memcpy(&sllc.sllc_smac, &llc->dev->dev_addr, memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
IFHWADDRLEN); IFHWADDRLEN);
} }
} }
......
...@@ -125,18 +125,16 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) ...@@ -125,18 +125,16 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)
sk = v; sk = v;
llc = llc_sk(sk); llc = llc_sk(sk);
seq_printf(seq, "%2X %2X ", sk->sk_type, /* FIXME: check if the address is multicast */
!llc_mac_null(llc->addr.sllc_mmac)); seq_printf(seq, "%2X %2X ", sk->sk_type, 0);
if (llc->dev && llc_mac_null(llc->addr.sllc_mmac)) if (llc->dev)
llc_ui_format_mac(seq, llc->dev->dev_addr); llc_ui_format_mac(seq, llc->dev->dev_addr);
else if (!llc_mac_null(llc->addr.sllc_mmac))
llc_ui_format_mac(seq, llc->addr.sllc_mmac);
else else
seq_printf(seq, "00:00:00:00:00:00"); seq_printf(seq, "00:00:00:00:00:00");
seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
llc_ui_format_mac(seq, llc->addr.sllc_dmac); llc_ui_format_mac(seq, llc->daddr.mac);
seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->addr.sllc_dsap, seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
atomic_read(&sk->sk_wmem_alloc), atomic_read(&sk->sk_wmem_alloc),
atomic_read(&sk->sk_rmem_alloc), atomic_read(&sk->sk_rmem_alloc),
sk->sk_state, sk->sk_state,
......
...@@ -54,10 +54,8 @@ void llc_save_primitive(struct sk_buff* skb, u8 prim) ...@@ -54,10 +54,8 @@ void llc_save_primitive(struct sk_buff* skb, u8 prim)
addr->sllc_test = prim == LLC_TEST_PRIM; addr->sllc_test = prim == LLC_TEST_PRIM;
addr->sllc_xid = prim == LLC_XID_PRIM; addr->sllc_xid = prim == LLC_XID_PRIM;
addr->sllc_ua = prim == LLC_DATAUNIT_PRIM; addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
llc_pdu_decode_sa(skb, addr->sllc_smac); llc_pdu_decode_sa(skb, addr->sllc_mac);
llc_pdu_decode_da(skb, addr->sllc_dmac); llc_pdu_decode_ssap(skb, &addr->sllc_sap);
llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment