Commit 0039920a authored by Simon Kelley's avatar Simon Kelley

Severely fix code formating of contrib/lease-tools/dhcp_release6.c

parent 39d8550a
...@@ -46,7 +46,8 @@ typedef unsigned char u8; ...@@ -46,7 +46,8 @@ typedef unsigned char u8;
typedef unsigned short u16; typedef unsigned short u16;
typedef unsigned int u32; typedef unsigned int u32;
enum DHCP6_TYPES{ enum DHCP6_TYPES
{
SOLICIT = 1, SOLICIT = 1,
ADVERTISE = 2, ADVERTISE = 2,
REQUEST = 3, REQUEST = 3,
...@@ -61,8 +62,10 @@ enum DHCP6_TYPES{ ...@@ -61,8 +62,10 @@ enum DHCP6_TYPES{
RELAY_FORW = 12, RELAY_FORW = 12,
RELAY_REPL = 13 RELAY_REPL = 13
}; };
enum DHCP6_OPTIONS{
enum DHCP6_OPTIONS
{
CLIENTID = 1, CLIENTID = 1,
SERVERID = 2, SERVERID = 2,
IA_NA = 3, IA_NA = 3,
...@@ -82,25 +85,27 @@ enum DHCP6_OPTIONS{ ...@@ -82,25 +85,27 @@ enum DHCP6_OPTIONS{
INTERFACE_ID = 18, INTERFACE_ID = 18,
RECONF_MSG = 19, RECONF_MSG = 19,
RECONF_ACCEPT = 20, RECONF_ACCEPT = 20,
}; };
enum DHCP6_STATUSES{ enum DHCP6_STATUSES
{
SUCCESS = 0, SUCCESS = 0,
UNSPEC_FAIL = 1, UNSPEC_FAIL = 1,
NOADDR_AVAIL=2, NOADDR_AVAIL=2,
NO_BINDING = 3, NO_BINDING = 3,
NOT_ON_LINK = 4, NOT_ON_LINK = 4,
USE_MULTICAST =5 USE_MULTICAST =5
}; };
static struct option longopts[] = { static struct option longopts[] = {
{"ip", required_argument, 0, 'a'}, {"ip", required_argument, 0, 'a' },
{"server-id", required_argument, 0, 's'}, {"server-id", required_argument, 0, 's' },
{"client-id", required_argument, 0, 'c'}, {"client-id", required_argument, 0, 'c' },
{"iface", required_argument, 0, 'n'}, {"iface", required_argument, 0, 'n' },
{"iaid", required_argument, 0, 'i'}, {"iaid", required_argument, 0, 'i' },
{"dry-run", no_argument, 0, 'd'}, {"dry-run", no_argument, 0, 'd' },
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h' },
{0, 0, 0, 0} {0, 0, 0, 0 }
}; };
const short DHCP6_CLIENT_PORT = 546; const short DHCP6_CLIENT_PORT = 546;
...@@ -108,23 +113,21 @@ const short DHCP6_SERVER_PORT = 547; ...@@ -108,23 +113,21 @@ const short DHCP6_SERVER_PORT = 547;
const char* DHCP6_MULTICAST_ADDRESS = "ff02::1:2"; const char* DHCP6_MULTICAST_ADDRESS = "ff02::1:2";
struct dhcp6_option{ struct dhcp6_option {
uint16_t type; uint16_t type;
uint16_t len; uint16_t len;
char value[1024]; char value[1024];
}; };
struct dhcp6_iaaddr_option{ struct dhcp6_iaaddr_option {
uint16_t type; uint16_t type;
uint16_t len; uint16_t len;
struct in6_addr ip; struct in6_addr ip;
uint32_t preferred_lifetime; uint32_t preferred_lifetime;
uint32_t valid_lifetime; uint32_t valid_lifetime;
}; };
struct dhcp6_iana_option{ struct dhcp6_iana_option {
uint16_t type; uint16_t type;
uint16_t len; uint16_t len;
uint32_t iaid; uint32_t iaid;
...@@ -134,29 +137,30 @@ struct dhcp6_iana_option{ ...@@ -134,29 +137,30 @@ struct dhcp6_iana_option{
}; };
struct dhcp6_packet{ struct dhcp6_packet {
size_t len; size_t len;
char buf[2048]; char buf[2048];
};
} ; size_t pack_duid(const char* str, char* dst)
{
size_t pack_duid(const char* str, char* dst){
char* tmp = strdup(str); char* tmp = strdup(str);
char* tmp_to_free = tmp; char* tmp_to_free = tmp;
char *ptr; char *ptr;
uint8_t write_pos = 0; uint8_t write_pos = 0;
while ((ptr = strtok (tmp, ":"))) { while ((ptr = strtok (tmp, ":")))
{
dst[write_pos] = (uint8_t) strtol(ptr, NULL, 16); dst[write_pos] = (uint8_t) strtol(ptr, NULL, 16);
write_pos += 1; write_pos += 1;
tmp = NULL; tmp = NULL;
} }
free(tmp_to_free); free(tmp_to_free);
return write_pos; return write_pos;
} }
struct dhcp6_option create_client_id_option(const char* duid){ struct dhcp6_option create_client_id_option(const char* duid)
{
struct dhcp6_option option; struct dhcp6_option option;
option.type = htons(CLIENTID); option.type = htons(CLIENTID);
bzero(option.value, sizeof(option.value)); bzero(option.value, sizeof(option.value));
...@@ -164,7 +168,8 @@ struct dhcp6_option create_client_id_option(const char* duid){ ...@@ -164,7 +168,8 @@ struct dhcp6_option create_client_id_option(const char* duid){
return option; return option;
} }
struct dhcp6_option create_server_id_option(const char* duid){ struct dhcp6_option create_server_id_option(const char* duid)
{
struct dhcp6_option option; struct dhcp6_option option;
option.type = htons(SERVERID); option.type = htons(SERVERID);
bzero(option.value, sizeof(option.value)); bzero(option.value, sizeof(option.value));
...@@ -172,7 +177,8 @@ struct dhcp6_option create_server_id_option(const char* duid){ ...@@ -172,7 +177,8 @@ struct dhcp6_option create_server_id_option(const char* duid){
return option; return option;
} }
struct dhcp6_iaaddr_option create_iaadr_option(const char* ip){ struct dhcp6_iaaddr_option create_iaadr_option(const char* ip)
{
struct dhcp6_iaaddr_option result; struct dhcp6_iaaddr_option result;
result.type =htons(IAADDR); result.type =htons(IAADDR);
/* no suboptions needed here, so length is 24 */ /* no suboptions needed here, so length is 24 */
...@@ -187,9 +193,12 @@ struct dhcp6_iaaddr_option create_iaadr_option(const char* ip){ ...@@ -187,9 +193,12 @@ struct dhcp6_iaaddr_option create_iaadr_option(const char* ip){
perror("inet_pton"); perror("inet_pton");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
return result; return result;
} }
struct dhcp6_iana_option create_iana_option(const char * iaid, struct dhcp6_iaaddr_option ia_addr){
struct dhcp6_iana_option create_iana_option(const char * iaid, struct dhcp6_iaaddr_option ia_addr)
{
struct dhcp6_iana_option result; struct dhcp6_iana_option result;
result.type = htons(IA_NA); result.type = htons(IA_NA);
result.iaid = htonl(atoi(iaid)); result.iaid = htonl(atoi(iaid));
...@@ -200,7 +209,8 @@ struct dhcp6_iana_option create_iana_option(const char * iaid, struct dhcp6_iaa ...@@ -200,7 +209,8 @@ struct dhcp6_iana_option create_iana_option(const char * iaid, struct dhcp6_iaa
return result; return result;
} }
struct dhcp6_packet create_release_packet(const char* iaid, const char* ip, const char* client_id, const char* server_id){ struct dhcp6_packet create_release_packet(const char* iaid, const char* ip, const char* client_id, const char* server_id)
{
struct dhcp6_packet result; struct dhcp6_packet result;
bzero(result.buf, sizeof(result.buf)); bzero(result.buf, sizeof(result.buf));
/* message_type */ /* message_type */
...@@ -223,21 +233,25 @@ struct dhcp6_packet create_release_packet(const char* iaid, const char* ip, cons ...@@ -223,21 +233,25 @@ struct dhcp6_packet create_release_packet(const char* iaid, const char* ip, cons
return result; return result;
} }
uint16_t parse_iana_suboption(char* buf, size_t len){ uint16_t parse_iana_suboption(char* buf, size_t len)
{
size_t current_pos = 0; size_t current_pos = 0;
char option_value[1024]; char option_value[1024];
while (current_pos < len) { while (current_pos < len)
{
uint16_t option_type, option_len; uint16_t option_type, option_len;
memcpy(&option_type,buf + current_pos, sizeof(uint16_t)); memcpy(&option_type,buf + current_pos, sizeof(uint16_t));
memcpy(&option_len,buf + current_pos + sizeof(uint16_t), sizeof(uint16_t)); memcpy(&option_len,buf + current_pos + sizeof(uint16_t), sizeof(uint16_t));
option_type = ntohs(option_type); option_type = ntohs(option_type);
option_len = ntohs(option_len); option_len = ntohs(option_len);
current_pos += 2 * sizeof(uint16_t); current_pos += 2 * sizeof(uint16_t);
if (option_type == STATUS_CODE){ if (option_type == STATUS_CODE)
{
uint16_t status; uint16_t status;
memcpy(&status, buf + current_pos, sizeof(uint16_t)); memcpy(&status, buf + current_pos, sizeof(uint16_t));
status = ntohs(status); status = ntohs(status);
if (status != SUCCESS){ if (status != SUCCESS)
{
memcpy(option_value, buf + current_pos + sizeof(uint16_t) , option_len - sizeof(uint16_t)); memcpy(option_value, buf + current_pos + sizeof(uint16_t) , option_len - sizeof(uint16_t));
option_value[option_len-sizeof(uint16_t)] ='\0'; option_value[option_len-sizeof(uint16_t)] ='\0';
fprintf(stderr, "Error: %s\n", option_value); fprintf(stderr, "Error: %s\n", option_value);
...@@ -245,70 +259,81 @@ uint16_t parse_iana_suboption(char* buf, size_t len){ ...@@ -245,70 +259,81 @@ uint16_t parse_iana_suboption(char* buf, size_t len){
return status; return status;
} }
} }
return -2; return -2;
} }
int16_t parse_packet(char* buf, size_t len){ int16_t parse_packet(char* buf, size_t len)
{
uint8_t type = buf[0]; uint8_t type = buf[0];
/*skipping tx id. you need it, uncomment following line /*skipping tx id. you need it, uncomment following line
uint16_t tx_id = ntohs((buf[1] <<16) + (buf[2] <<8) + buf[3]); uint16_t tx_id = ntohs((buf[1] <<16) + (buf[2] <<8) + buf[3]);
*/ */
size_t current_pos = 4; size_t current_pos = 4;
if (type != REPLY ){ if (type != REPLY )
return NOT_REPLY_CODE; return NOT_REPLY_CODE;
}
char option_value[1024]; char option_value[1024];
while (current_pos < len) { while (current_pos < len)
{
uint16_t option_type, option_len; uint16_t option_type, option_len;
memcpy(&option_type,buf + current_pos, sizeof(uint16_t)); memcpy(&option_type,buf + current_pos, sizeof(uint16_t));
memcpy(&option_len,buf + current_pos + sizeof(uint16_t), sizeof(uint16_t)); memcpy(&option_len,buf + current_pos + sizeof(uint16_t), sizeof(uint16_t));
option_type = ntohs(option_type); option_type = ntohs(option_type);
option_len = ntohs(option_len); option_len = ntohs(option_len);
current_pos += 2 * sizeof(uint16_t); current_pos += 2 * sizeof(uint16_t);
if (option_type == STATUS_CODE){ if (option_type == STATUS_CODE)
{
uint16_t status; uint16_t status;
memcpy(&status, buf + current_pos, sizeof(uint16_t)); memcpy(&status, buf + current_pos, sizeof(uint16_t));
status = ntohs(status); status = ntohs(status);
if (status != SUCCESS){ if (status != SUCCESS)
{
memcpy(option_value, buf + current_pos +sizeof(uint16_t) , option_len -sizeof(uint16_t)); memcpy(option_value, buf + current_pos +sizeof(uint16_t) , option_len -sizeof(uint16_t));
fprintf(stderr, "Error: %d %s\n", status, option_value); fprintf(stderr, "Error: %d %s\n", status, option_value);
return status; return status;
} }
} }
if (option_type == IA_NA ){
if (option_type == IA_NA )
{
uint16_t result = parse_iana_suboption(buf + current_pos +24, option_len -24); uint16_t result = parse_iana_suboption(buf + current_pos +24, option_len -24);
if (result){ if (result)
return result; return result;
} }
}
current_pos += option_len;
current_pos += option_len;
} }
return -1; return -1;
} }
void usage(const char* arg, FILE* stream){ void usage(const char* arg, FILE* stream)
{
const char* usage_string ="--ip IPv6 --iface IFACE --server-id SERVER_ID --client-id CLIENT_ID --iaid IAID [--dry-run] | --help"; const char* usage_string ="--ip IPv6 --iface IFACE --server-id SERVER_ID --client-id CLIENT_ID --iaid IAID [--dry-run] | --help";
fprintf (stream, "Usage: %s %s\n", arg, usage_string); fprintf (stream, "Usage: %s %s\n", arg, usage_string);
} }
int send_release_packet(const char* iface, struct dhcp6_packet* packet){ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
{
struct sockaddr_in6 server_addr, client_addr; struct sockaddr_in6 server_addr, client_addr;
char response[1400]; char response[1400];
int sock = socket(PF_INET6, SOCK_DGRAM, 0); int sock = socket(PF_INET6, SOCK_DGRAM, 0);
int i = 0; int i = 0;
if (sock < 0) { if (sock < 0)
{
perror("creating socket"); perror("creating socket");
return -1; return -1;
} }
if (setsockopt(sock, SOL_SOCKET, 25, iface, strlen(iface)) == -1) {
if (setsockopt(sock, SOL_SOCKET, 25, iface, strlen(iface)) == -1)
{
perror("SO_BINDTODEVICE"); perror("SO_BINDTODEVICE");
close(sock); close(sock);
return -1; return -1;
} }
memset(&server_addr, 0, sizeof(server_addr)); memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6; server_addr.sin6_family = AF_INET6;
client_addr.sin6_family = AF_INET6; client_addr.sin6_family = AF_INET6;
...@@ -320,36 +345,44 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet){ ...@@ -320,36 +345,44 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet){
inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr); inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
server_addr.sin6_port = htons(DHCP6_SERVER_PORT); server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
int16_t recv_size = 0; int16_t recv_size = 0;
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++)
if (sendto(sock, packet->buf, packet->len, 0, {
(struct sockaddr *)&server_addr, if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
sizeof(server_addr)) < 0) { {
perror("sendto failed"); perror("sendto failed");
exit(4); exit(4);
} }
recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0); recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0);
if (recv_size == -1){ if (recv_size == -1)
if (errno == EAGAIN){ {
if (errno == EAGAIN)
{
sleep(1); sleep(1);
continue; continue;
}else { }
else
{
perror("recvfrom"); perror("recvfrom");
} }
} }
int16_t result = parse_packet(response, recv_size); int16_t result = parse_packet(response, recv_size);
if (result == NOT_REPLY_CODE){ if (result == NOT_REPLY_CODE)
{
sleep(1); sleep(1);
continue; continue;
} }
return result; return result;
} }
fprintf(stderr, "Response timed out\n"); fprintf(stderr, "Response timed out\n");
return -1; return -1;
} }
int main(int argc, char * const argv[]) { int main(int argc, char * const argv[])
{
const char* UNINITIALIZED = ""; const char* UNINITIALIZED = "";
const char* iface = UNINITIALIZED; const char* iface = UNINITIALIZED;
const char* ip = UNINITIALIZED; const char* ip = UNINITIALIZED;
...@@ -357,22 +390,25 @@ int main(int argc, char * const argv[]) { ...@@ -357,22 +390,25 @@ int main(int argc, char * const argv[]) {
const char* server_id = UNINITIALIZED; const char* server_id = UNINITIALIZED;
const char* iaid = UNINITIALIZED; const char* iaid = UNINITIALIZED;
int dry_run = 0; int dry_run = 0;
while (1) { while (1)
{
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "a:s:c:n:i:hd", longopts, &option_index); int c = getopt_long(argc, argv, "a:s:c:n:i:hd", longopts, &option_index);
if (c == -1){ if (c == -1)
break; break;
}
switch(c){ switch(c)
{
case 0: case 0:
if (longopts[option_index].flag !=0){ if (longopts[option_index].flag !=0)
break; break;
}
printf ("option %s", longopts[option_index].name); printf ("option %s", longopts[option_index].name);
if (optarg) if (optarg)
printf (" with arg %s", optarg); printf (" with arg %s", optarg);
printf ("\n"); printf ("\n");
break; break;
case 'i': case 'i':
iaid = optarg; iaid = optarg;
break; break;
...@@ -401,29 +437,38 @@ int main(int argc, char * const argv[]) { ...@@ -401,29 +437,38 @@ int main(int argc, char * const argv[]) {
abort(); abort();
} }
} }
if (iaid == UNINITIALIZED){
if (iaid == UNINITIALIZED)
{
fprintf(stderr, "Missing required iaid parameter\n"); fprintf(stderr, "Missing required iaid parameter\n");
usage(argv[0], stderr); usage(argv[0], stderr);
return -1; return -1;
} }
if (server_id == UNINITIALIZED){
if (server_id == UNINITIALIZED)
{
fprintf(stderr, "Missing required server-id parameter\n"); fprintf(stderr, "Missing required server-id parameter\n");
usage(argv[0], stderr); usage(argv[0], stderr);
return -1; return -1;
} }
if (client_id == UNINITIALIZED){
if (client_id == UNINITIALIZED)
{
fprintf(stderr, "Missing required client-id parameter\n"); fprintf(stderr, "Missing required client-id parameter\n");
usage(argv[0], stderr); usage(argv[0], stderr);
return -1; return -1;
} }
if (ip == UNINITIALIZED){
if (ip == UNINITIALIZED)
{
fprintf(stderr, "Missing required ip parameter\n"); fprintf(stderr, "Missing required ip parameter\n");
usage(argv[0], stderr); usage(argv[0], stderr);
return -1; return -1;
} }
if (iface == UNINITIALIZED){
if (iface == UNINITIALIZED)
{
fprintf(stderr, "Missing required iface parameter\n"); fprintf(stderr, "Missing required iface parameter\n");
usage(argv[0], stderr); usage(argv[0], stderr);
return -1; return -1;
...@@ -432,14 +477,17 @@ int main(int argc, char * const argv[]) { ...@@ -432,14 +477,17 @@ int main(int argc, char * const argv[]) {
struct dhcp6_packet packet = create_release_packet(iaid, ip, client_id, server_id); struct dhcp6_packet packet = create_release_packet(iaid, ip, client_id, server_id);
if (dry_run){
if (dry_run)
{
uint16_t i; uint16_t i;
for(i=0;i<packet.len;i++){
for(i=0; i<packet.len; i++)
printf("%hhx", packet.buf[i]); printf("%hhx", packet.buf[i]);
}
printf("\n"); printf("\n");
return 0; return 0;
} }
return send_release_packet(iface, &packet);
return send_release_packet(iface, &packet);
} }
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