Separate out DHCP processing

So we can later call it on UDP datagrams obtained from UDP socket.
This commit is contained in:
Samuel Thibault 2023-05-17 23:42:08 +02:00
parent e53fccd36c
commit c3eb1be0b4
5 changed files with 44 additions and 17 deletions

53
dhcp6.c
View file

@ -29,7 +29,7 @@ static struct dhcp6_in_option list_option;
static int dhcpv6_format_dns_search_name(const char *strdns, uint8_t *buffer); static int dhcpv6_format_dns_search_name(const char *strdns, uint8_t *buffer);
static void dhcp6_send_reply(sessionidt s, tunnelidt t, struct in6_addr *ip6_src) static void dhcp6_send_reply(sessionidt s, tunnelidt t, const struct in6_addr *ip6_src)
{ {
struct ip6_hdr *p_ip6_hdr; struct ip6_hdr *p_ip6_hdr;
struct udphdr *p_udp; struct udphdr *p_udp;
@ -309,26 +309,22 @@ static char * get_msg_type(uint8_t type)
} }
} }
void dhcpv6_process(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) void dhcpv6_process(sessionidt s, tunnelidt t, const struct in6_addr *addr, uint8_t *p, uint16_t l)
{ {
struct ip6_hdr *p_ip6_hdr_in; struct dhcp6_mess_hdr *p_mess_hdr = (struct dhcp6_mess_hdr *) p;
struct dhcp6_mess_hdr *p_mess_hdr;
struct dhcp6_opt_h *p_opt; struct dhcp6_opt_h *p_opt;
uint8_t *p_end; uint8_t *p_end;
uint16_t len; uint16_t len;
CSTAT(dhcpv6_process); CSTAT(dhcpv6_process);
p_ip6_hdr_in = (struct ip6_hdr *) p;
p_mess_hdr = (struct dhcp6_mess_hdr *) (p + 48);
LOG(3, s, t, "Got DHCPv6 message Type: %s(%d)\n", get_msg_type(p_mess_hdr->type), p_mess_hdr->type); LOG(3, s, t, "Got DHCPv6 message Type: %s(%d)\n", get_msg_type(p_mess_hdr->type), p_mess_hdr->type);
if (!session[s].route6[0].ipv6route.s6_addr[0] || !session[s].route6[0].ipv6prefixlen) if (!session[s].route6[0].ipv6route.s6_addr[0] || !session[s].route6[0].ipv6prefixlen)
return; return;
p_opt = (struct dhcp6_opt_h *) &p_mess_hdr[1]; p_opt = (struct dhcp6_opt_h *) &p_mess_hdr[1];
p_end = ((uint8_t *)p_ip6_hdr_in) + ntohs(p_ip6_hdr_in->ip6_plen) + sizeof(*p_ip6_hdr_in); p_end = p + l;
memset(&list_option, 0, sizeof(list_option)); memset(&list_option, 0, sizeof(list_option));
list_option.p_mess_hdr = p_mess_hdr; list_option.p_mess_hdr = p_mess_hdr;
while (((uint8_t *)p_opt) < p_end) while (((uint8_t *)p_opt) < p_end)
@ -413,7 +409,7 @@ void dhcpv6_process(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
return; return;
} }
dhcp6_send_reply(s, t, &p_ip6_hdr_in->ip6_src); dhcp6_send_reply(s, t, addr);
} }
break; break;
@ -458,8 +454,8 @@ void dhcpv6_process(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
return; return;
} }
dhcp6_send_reply(s, t, &p_ip6_hdr_in->ip6_src); dhcp6_send_reply(s, t, addr);
send_ipv6_ra(s, t, &p_ip6_hdr_in->ip6_src); // send a RA send_ipv6_ra(s, t, addr); // send a RA
} }
break; break;
@ -489,7 +485,7 @@ void dhcpv6_process(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
return; return;
} }
dhcp6_send_reply(s, t, &p_ip6_hdr_in->ip6_src); dhcp6_send_reply(s, t, addr);
} }
break; break;
@ -501,7 +497,7 @@ void dhcpv6_process(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
return; return;
} }
dhcp6_send_reply(s, t, &p_ip6_hdr_in->ip6_src); dhcp6_send_reply(s, t, addr);
} }
break; break;
@ -527,6 +523,37 @@ void dhcpv6_process(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
return; return;
} }
void dhcpv6_process_from_ipv6(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
{
struct ip6_hdr *p_ip6_hdr_in = (struct ip6_hdr *) p;
struct in6_addr *addr = &p_ip6_hdr_in->ip6_src;
uint16_t ipv6_len = ntohs(p_ip6_hdr_in->ip6_plen);
l -= sizeof(*p_ip6_hdr_in);
p += sizeof(*p_ip6_hdr_in);
if (ipv6_len > l)
{
LOG(5, 0, 0, "bogus IPv6 packet size??\n");
return;
}
if (p_ip6_hdr_in->ip6_nxt != 17)
{
LOG(5, 0, 0, "not UDP DHCP packet??\n");
return;
}
if (ipv6_len < sizeof(struct udphdr))
{
LOG(5, 0, 0, "bogus IPv6 packet size for UDP??\n");
return;
}
ipv6_len -= sizeof(struct udphdr);
p += sizeof(struct udphdr);
dhcpv6_process(s, t, addr, p, ipv6_len);
}
static int dhcpv6_format_dns_search_name(const char *strdns, uint8_t *buffer) static int dhcpv6_format_dns_search_name(const char *strdns, uint8_t *buffer)
{ {
int n = strlen(strdns); int n = strlen(strdns);

View file

@ -212,7 +212,7 @@ struct dhcp6_opt_ia_prefix {
} __attribute__((packed)); } __attribute__((packed));
// dhcp6.c // dhcp6.c
void dhcpv6_process(uint16_t s, uint16_t t, uint8_t *p, uint16_t l); void dhcpv6_process_from_ipv6(uint16_t s, uint16_t t, uint8_t *p, uint16_t l);
void dhcpv6_init(void); void dhcpv6_init(void);
#endif /* __DHCP6_H__ */ #endif /* __DHCP6_H__ */

2
icmp.c
View file

@ -96,7 +96,7 @@ struct nd_opt_rdnss_info_l2tpns
struct in6_addr nd_opt_rdnssi[0]; struct in6_addr nd_opt_rdnssi[0];
}; };
void send_ipv6_ra(sessionidt s, tunnelidt t, struct in6_addr *ip) void send_ipv6_ra(sessionidt s, tunnelidt t, const struct in6_addr *ip)
{ {
struct nd_opt_prefix_info *pinfo; struct nd_opt_prefix_info *pinfo;
struct ip6_hdr *p_ip6_hdr; struct ip6_hdr *p_ip6_hdr;

View file

@ -960,7 +960,7 @@ int rad_tunnel_pwdecode(uint8_t *pl2tpsecret, size_t *pl2tpsecretlen, const char
// l2tpns.c // l2tpns.c
clockt backoff(uint8_t try); clockt backoff(uint8_t try);
void send_ipv6_ra(sessionidt s, tunnelidt t, struct in6_addr *ip); void send_ipv6_ra(sessionidt s, tunnelidt t, const struct in6_addr *ip);
void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add); void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add);
void routes6set(sessionidt s, sessiont *sp, int add); void routes6set(sessionidt s, sessiont *sp, int add);
sessionidt sessionbyip(in_addr_t ip); sessionidt sessionbyip(in_addr_t ip);

2
ppp.c
View file

@ -2286,7 +2286,7 @@ void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
*(uint16_t *)(p + 34) == 0 && *(p + 36) == 0 && *(p + 37) == 1 && *(p + 38) == 0 && *(p + 39) == 2 && *(uint16_t *)(p + 34) == 0 && *(p + 36) == 0 && *(p + 37) == 1 && *(p + 38) == 0 && *(p + 39) == 2 &&
*(p + 40) == 2 && *(p + 41) == 0x22 && *(p + 42) == 2 && *(p + 43) == 0x23) *(p + 40) == 2 && *(p + 41) == 0x22 && *(p + 42) == 2 && *(p + 43) == 0x23)
{ {
dhcpv6_process(s, t, p, l); dhcpv6_process_from_ipv6(s, t, p, l);
return; return;
} }