diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2013-04-25 17:04:15 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2013-04-25 17:04:15 +0400 |
commit | 41ef1132bc7439ee378eb2d1cff2da3d6f75edc8 (patch) | |
tree | fb60915aeb48592ad02062b47d687e27df42f145 /accel-pppd/ctrl/ipoe/dhcpv4.c | |
parent | 22ecfca77f927d753669e3a1d8247b7b8b790cdc (diff) | |
download | accel-ppp-41ef1132bc7439ee378eb2d1cff2da3d6f75edc8.tar.gz accel-ppp-41ef1132bc7439ee378eb2d1cff2da3d6f75edc8.zip |
ipoe: detect giaddr if not specified
Diffstat (limited to 'accel-pppd/ctrl/ipoe/dhcpv4.c')
-rw-r--r-- | accel-pppd/ctrl/ipoe/dhcpv4.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c index 4f27a47..f5408b0 100644 --- a/accel-pppd/ctrl/ipoe/dhcpv4.c +++ b/accel-pppd/ctrl/ipoe/dhcpv4.c @@ -27,8 +27,7 @@ #define BUF_SIZE 4096 -struct dhcpv4_relay_ctx -{ +struct dhcpv4_relay_ctx { struct list_head entry; struct triton_context_t *ctx; triton_event_func recv; @@ -796,9 +795,10 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, struct dhcpv4_relay *r; in_addr_t addr;// = inet_addr(_addr); int port = DHCP_SERV_PORT; - in_addr_t giaddr = inet_addr(_giaddr); + in_addr_t giaddr;// = inet_addr(_giaddr); struct sockaddr_in raddr; struct sockaddr_in laddr; + socklen_t len = sizeof(laddr); int sock = -1; int f = 1; struct dhcpv4_relay_ctx *c; @@ -811,6 +811,32 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, port = atoi(ptr + 1); } else addr = inet_addr(_addr); + + memset(&raddr, 0, sizeof(raddr)); + raddr.sin_family = AF_INET; + raddr.sin_addr.s_addr = addr; + raddr.sin_port = htons(port); + + if (_giaddr) + giaddr = inet_addr(_giaddr); + else { + sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (connect(sock, &raddr, sizeof(raddr))) { + log_error("dhcpv4: relay: %s: connect: %s\n", _addr, strerror(errno)); + goto out_err; + } + + getsockname(sock, &laddr, &len); + giaddr = laddr.sin_addr.s_addr; + + close(sock); + } + + memset(&laddr, 0, sizeof(laddr)); + laddr.sin_family = AF_INET; + laddr.sin_addr.s_addr = giaddr; + laddr.sin_port = htons(DHCP_SERV_PORT); list_for_each_entry(r, &relay_list, entry) { if (r->addr == addr && r->giaddr == giaddr) @@ -823,16 +849,6 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, r->addr = addr; r->giaddr = giaddr; - memset(&raddr, 0, sizeof(raddr)); - raddr.sin_family = AF_INET; - raddr.sin_addr.s_addr = addr; - raddr.sin_port = htons(port); - - memset(&laddr, 0, sizeof(laddr)); - laddr.sin_family = AF_INET; - laddr.sin_addr.s_addr = giaddr; - laddr.sin_port = htons(DHCP_SERV_PORT); - sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!sock) { log_error("socket: %s\n", strerror(errno)); |