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

parent 1cca41e2
......@@ -12,20 +12,17 @@
*
* 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 {
sa_family_t sllc_family; /* AF_LLC */
sa_family_t sllc_arphrd; /* ARPHRD_ETHER */
unsigned char sllc_test;
unsigned char sllc_xid;
unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */
unsigned char sllc_dsap;
unsigned char sllc_ssap;
unsigned char sllc_dmac[IFHWADDRLEN];
unsigned char sllc_smac[IFHWADDRLEN];
unsigned char sllc_mmac[IFHWADDRLEN];
unsigned char sllc_sap;
unsigned char sllc_mac[IFHWADDRLEN];
unsigned char __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 -
sizeof(unsigned char) * 5 - IFHWADDRLEN * 3];
sizeof(unsigned char) * 4 - IFHWADDRLEN];
};
/* sockopt definitions. */
......
......@@ -246,32 +246,20 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
struct sock *sk = sock->sk;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap;
struct net_device *dev = NULL;
int rc = -EINVAL;
if (!sk->sk_zapped)
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. */
if (!addr->sllc_ssap) {
if (!addr->sllc_sap) {
rc = -EUSERS;
addr->sllc_ssap = llc_ui_autoport();
if (!addr->sllc_ssap)
addr->sllc_sap = llc_ui_autoport();
if (!addr->sllc_sap)
goto out;
}
sap = llc_sap_find(addr->sllc_ssap);
sap = llc_sap_find(addr->sllc_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 */
if (!sap)
goto out;
......@@ -279,20 +267,14 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
struct llc_addr laddr, daddr;
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(&daddr, 0, sizeof(daddr));
if (!llc_mac_null(addr->sllc_mmac)) {
if (sk->sk_type != SOCK_DGRAM) {
rc = -EOPNOTSUPP;
goto out;
}
memcpy(laddr.mac, addr->sllc_mmac, IFHWADDRLEN);
} else
memcpy(laddr.mac, addr->sllc_smac, IFHWADDRLEN);
laddr.lsap = addr->sllc_ssap;
/*
* FIXME: check if the the address is multicast,
* only SOCK_DGRAM can do this.
*/
memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
laddr.lsap = addr->sllc_sap;
rc = -EADDRINUSE; /* mac + sap clash. */
ask = llc_lookup_established(sap, &daddr, &laddr);
if (ask) {
......@@ -300,11 +282,9 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
goto out;
}
}
llc->laddr.lsap = addr->sllc_ssap;
llc->laddr.lsap = addr->sllc_sap;
if (llc->dev)
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));
/* assign new connection to its SAP */
llc_sap_add_socket(sap, sk);
......@@ -337,7 +317,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
struct sock *sk = sock->sk;
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))
goto out;
rc = -EAFNOSUPPORT;
......@@ -416,6 +396,8 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
rc = llc_ui_autobind(sock, addr);
if (rc)
goto out;
llc->daddr.lsap = addr->sllc_sap;
memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
}
if (!llc->dev) {
rc = -ENODEV;
......@@ -435,7 +417,7 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
sk->sk_state = TCP_SYN_SENT;
llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap);
rc = llc_establish_connection(sk, dev->dev_addr,
addr->sllc_dmac, addr->sllc_dsap);
addr->sllc_mac, addr->sllc_sap);
if (rc) {
dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
sock->state = SS_UNCONNECTED;
......@@ -628,7 +610,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
int rc = -EOPNOTSUPP;
dprintk("%s: accepting on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_ssap);
llc_sk(sk)->addr.sllc_sap);
lock_sock(sk);
if (sk->sk_type != SOCK_STREAM)
goto out;
......@@ -640,7 +622,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
if (rc)
goto out;
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);
rc = -EINVAL;
if (!skb->sk)
......@@ -656,8 +638,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
llc = llc_sk(sk);
newllc = llc_sk(newsk);
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);
/* 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)
sk->sk_ack_backlog--;
skb->sk = NULL;
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:
kfree_skb(skb);
out:
......@@ -792,18 +772,18 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
if (rc)
goto out;
if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_dmac,
addr->sllc_dsap);
llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_sap);
goto out;
}
if (addr->sllc_test) {
llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_dmac,
addr->sllc_dsap);
llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_sap);
goto out;
}
if (addr->sllc_xid) {
llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_dmac,
addr->sllc_dsap);
llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_sap);
goto out;
}
rc = -ENOPROTOOPT;
......@@ -851,17 +831,17 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
goto out;
if(llc->dev)
sllc.sllc_arphrd = llc->dev->type;
sllc.sllc_dsap = llc->daddr.lsap;
memcpy(&sllc.sllc_dmac, &llc->daddr.mac, IFHWADDRLEN);
sllc.sllc_sap = llc->daddr.lsap;
memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
} else {
rc = -EINVAL;
if (!llc->sap)
goto out;
sllc.sllc_ssap = llc->sap->laddr.lsap;
sllc.sllc_sap = llc->sap->laddr.lsap;
if (llc->dev) {
sllc.sllc_arphrd = llc->dev->type;
memcpy(&sllc.sllc_smac, &llc->dev->dev_addr,
memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
IFHWADDRLEN);
}
}
......
......@@ -125,18 +125,16 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)
sk = v;
llc = llc_sk(sk);
seq_printf(seq, "%2X %2X ", sk->sk_type,
!llc_mac_null(llc->addr.sllc_mmac));
/* FIXME: check if the address is multicast */
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);
else if (!llc_mac_null(llc->addr.sllc_mmac))
llc_ui_format_mac(seq, llc->addr.sllc_mmac);
else
seq_printf(seq, "00:00:00:00:00:00");
seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
llc_ui_format_mac(seq, llc->addr.sllc_dmac);
seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->addr.sllc_dsap,
llc_ui_format_mac(seq, llc->daddr.mac);
seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
atomic_read(&sk->sk_wmem_alloc),
atomic_read(&sk->sk_rmem_alloc),
sk->sk_state,
......
......@@ -54,10 +54,8 @@ void llc_save_primitive(struct sk_buff* skb, u8 prim)
addr->sllc_test = prim == LLC_TEST_PRIM;
addr->sllc_xid = prim == LLC_XID_PRIM;
addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
llc_pdu_decode_sa(skb, addr->sllc_smac);
llc_pdu_decode_da(skb, addr->sllc_dmac);
llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
llc_pdu_decode_sa(skb, addr->sllc_mac);
llc_pdu_decode_ssap(skb, &addr->sllc_sap);
}
/**
......
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