diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2016-03-18 23:15:20 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-03-18 23:15:20 +0300 |
commit | aa4ed7b9c637b70dc42a180b918fb4adb3e32d74 (patch) | |
tree | 4e8454f4c751db0619faa2e6333d6b90aa841158 /accel-pppd | |
parent | 53eaf7555a5f3f0b60854acf7933484c98ada917 (diff) | |
download | accel-ppp-aa4ed7b9c637b70dc42a180b918fb4adb3e32d74.tar.gz accel-ppp-aa4ed7b9c637b70dc42a180b918fb4adb3e32d74.zip |
ipoe: implemented starting UP session by arp request
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/ctrl/ipoe/arp.c | 12 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 20 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 14 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe_netlink.c | 18 |
4 files changed, 38 insertions, 26 deletions
diff --git a/accel-pppd/ctrl/ipoe/arp.c b/accel-pppd/ctrl/ipoe/arp.c index 9699624..2bf5a95 100644 --- a/accel-pppd/ctrl/ipoe/arp.c +++ b/accel-pppd/ctrl/ipoe/arp.c @@ -26,18 +26,6 @@ #include "memdebug.h" -struct _arphdr { - __be16 ar_hrd; - __be16 ar_pro; - __u8 ar_hln; - __u8 ar_pln; - __be16 ar_op; - __u8 ar_sha[ETH_ALEN]; - __be32 ar_spa; - __u8 ar_tha[ETH_ALEN]; - __be32 ar_tpa; -} __packed; - struct arp_node { struct rb_node node; struct ipoe_serv *ipoe; diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 514e787..e6f142a 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -1748,15 +1748,16 @@ static void ipoe_recv_dhcpv4_relay(struct dhcpv4_packet *pack) } -static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struct ethhdr *eth, struct iphdr *iph) +static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struct ethhdr *eth, struct iphdr *iph, struct _arphdr *arph) { struct ipoe_session *ses; - uint8_t *hwaddr = eth->h_source; + uint8_t *hwaddr = arph ? arph->ar_sha : eth->h_source; + in_addr_t saddr = arph ? arph->ar_spa : iph->saddr; if (ap_shutdown) return NULL; - if (l4_redirect_list_check(iph->saddr)) + if (l4_redirect_list_check(saddr)) return NULL; ses = ipoe_session_alloc(); @@ -1764,8 +1765,8 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc return NULL; ses->serv = serv; - memcpy(ses->hwaddr, eth->h_source, 6); - ses->yiaddr = iph->saddr; + memcpy(ses->hwaddr, hwaddr, ETH_ALEN); + ses->yiaddr = saddr; ses->UP = 1; if (!serv->opt_shared) @@ -1779,7 +1780,7 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); } else { ses->ctrl.calling_station_id = _malloc(17); - u_inet_ntoa(iph->saddr, ses->ctrl.calling_station_id); + u_inet_ntoa(saddr, ses->ctrl.calling_station_id); } if (ses->serv->opt_username == USERNAME_IFNAME) @@ -1881,10 +1882,11 @@ struct ipoe_session *ipoe_session_alloc(void) return ses; } -void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph) +void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph, struct _arphdr *arph) { struct ipoe_serv *serv; struct ipoe_session *ses; + in_addr_t saddr = arph ? arph->ar_spa : iph->saddr; pthread_mutex_lock(&serv_lock); list_for_each_entry(serv, &serv_list, entry) { @@ -1904,14 +1906,14 @@ void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph) } list_for_each_entry(ses, &serv->sessions, entry) { - if (ses->yiaddr == iph->saddr) { + if (ses->yiaddr == saddr) { pthread_mutex_unlock(&serv->lock); pthread_mutex_unlock(&serv_lock); return; } } - ipoe_session_create_up(serv, eth, iph); + ipoe_session_create_up(serv, eth, iph, arph); pthread_mutex_unlock(&serv->lock); diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index 0cf14ea..52b3c8d 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -106,6 +106,18 @@ struct ipoe_session_info { uint32_t peer_addr; }; +struct _arphdr { + __be16 ar_hrd; + __be16 ar_pro; + __u8 ar_hln; + __u8 ar_pln; + __be16 ar_op; + __u8 ar_sha[ETH_ALEN]; + __be32 ar_spa; + __u8 ar_tha[ETH_ALEN]; + __be32 ar_tpa; +} __packed; + #ifdef USE_LUA char *ipoe_lua_get_username(struct ipoe_session *, const char *func); int ipoe_lua_make_vlan_name(const char *func, const char *parent, int svid, int cvid, char *name); @@ -114,7 +126,7 @@ int ipoe_lua_make_vlan_name(const char *func, const char *parent, int svid, int struct iphdr; struct ethhdr; -void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph); +void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph, struct _arphdr *arph); struct ipoe_session *ipoe_session_alloc(void); diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c index 9372a94..8ed4d91 100644 --- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c +++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c @@ -467,6 +467,7 @@ static void ipoe_up_handler(const struct sockaddr_nl *addr, struct nlmsghdr *h) int ifindex; struct iphdr *iph; struct ethhdr *eth; + struct _arphdr *arph; len -= NLMSG_LENGTH(GENL_HDRLEN); @@ -484,14 +485,23 @@ static void ipoe_up_handler(const struct sockaddr_nl *addr, struct nlmsghdr *h) parse_rtattr_nested(tb2, IPOE_ATTR_MAX, tb[i]); - if (!tb2[IPOE_ATTR_ETH_HDR] || !tb2[IPOE_ATTR_IP_HDR] || !tb2[IPOE_ATTR_IFINDEX]) + if (!tb2[IPOE_ATTR_IFINDEX]) continue; ifindex = *(uint32_t *)(RTA_DATA(tb2[IPOE_ATTR_IFINDEX])); - iph = (struct iphdr *)(RTA_DATA(tb2[IPOE_ATTR_IP_HDR])); - eth = (struct ethhdr *)(RTA_DATA(tb2[IPOE_ATTR_ETH_HDR])); - ipoe_recv_up(ifindex, eth, iph); + if (tb2[IPOE_ATTR_ARP_HDR]) { + arph = (struct _arphdr *)(RTA_DATA(tb2[IPOE_ATTR_ARP_HDR])); + iph = NULL; + eth = NULL; + } else if (tb2[IPOE_ATTR_ETH_HDR] && !tb2[IPOE_ATTR_IP_HDR]) { + iph = (struct iphdr *)(RTA_DATA(tb2[IPOE_ATTR_IP_HDR])); + eth = (struct ethhdr *)(RTA_DATA(tb2[IPOE_ATTR_ETH_HDR])); + arph = NULL; + } else + continue; + + ipoe_recv_up(ifindex, eth, iph, arph); } } |