dhcp: fix crash on unicast renewal send
[vpp.git] / src / plugins / dhcp / dhcp4_packet.c
1 /*
2  * dhcp4_packet.c: dhcp packet format functions
3  *
4  * Copyright (c) 2013 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <dhcp/dhcp4_packet.h>
19 #include <vnet/ip/format.h>
20
21 u8 *
22 format_dhcp_packet_type (u8 * s, va_list * args)
23 {
24   dhcp_packet_type_t pt = va_arg (*args, dhcp_packet_type_t);
25
26   switch (pt)
27     {
28     case DHCP_PACKET_DISCOVER:
29       s = format (s, "discover");
30       break;
31     case DHCP_PACKET_OFFER:
32       s = format (s, "offer");
33       break;
34     case DHCP_PACKET_REQUEST:
35       s = format (s, "request");
36       break;
37     case DHCP_PACKET_ACK:
38       s = format (s, "ack");
39       break;
40     case DHCP_PACKET_NAK:
41       s = format (s, "nack");
42       break;
43     }
44   return (s);
45 }
46
47 u8 *
48 format_dhcp_header (u8 * s, va_list * args)
49 {
50   dhcp_header_t *d = va_arg (*args, dhcp_header_t *);
51   u32 max_bytes = va_arg (*args, u32);
52   dhcp_option_t *o;
53   u32 tmp;
54
55   s = format (s, "opcode:%s", (d->opcode == 1 ? "request" : "reply"));
56   s = format (s, " hw[type:%d addr-len:%d addr:%U]",
57               d->hardware_type, d->hardware_address_length,
58               format_hex_bytes, d->client_hardware_address,
59               d->hardware_address_length);
60   s = format (s, " hops%d", d->hops);
61   s = format (s, " transaction-ID:0x%x", d->transaction_identifier);
62   s = format (s, " seconds:%d", d->seconds);
63   s = format (s, " flags:0x%x", d->flags);
64   s = format (s, " client:%U", format_ip4_address, &d->client_ip_address);
65   s = format (s, " your:%U", format_ip4_address, &d->your_ip_address);
66   s = format (s, " server:%U", format_ip4_address, &d->server_ip_address);
67   s = format (s, " gateway:%U", format_ip4_address, &d->gateway_ip_address);
68   s = format (s, " cookie:%U", format_ip4_address, &d->magic_cookie);
69
70   o = (dhcp_option_t *) d->options;
71
72   while (o->option != 0xFF /* end of options */  &&
73          (u8 *) o < (u8 *) d + max_bytes)
74     {
75       switch (o->option)
76         {
77         case 53:                /* dhcp message type */
78           tmp = o->data[0];
79           s =
80             format (s, ", option-53: type:%U", format_dhcp_packet_type, tmp);
81           break;
82         case 54:                /* dhcp server address */
83           s = format (s, ", option-54: server:%U",
84                       format_ip4_address, &o->data_as_u32[0]);
85           break;
86         case 58:                /* lease renew time in seconds */
87           s = format (s, ", option-58: renewal:%d",
88                       clib_host_to_net_u32 (o->data_as_u32[0]));
89           break;
90         case 1:         /* subnet mask */
91           s = format (s, ", option-1: subnet-mask:%d",
92                       clib_host_to_net_u32 (o->data_as_u32[0]));
93           break;
94         case 3:         /* router address */
95           s = format (s, ", option-3: router:%U",
96                       format_ip4_address, &o->data_as_u32[0]);
97           break;
98         case 6:         /* domain server address */
99           s = format (s, ", option-6: domian-server:%U",
100                       format_hex_bytes, o->data, o->length);
101           break;
102         case 12:                /* hostname */
103           s = format (s, ", option-12: hostname:%U",
104                       format_hex_bytes, o->data, o->length);
105           break;
106         default:
107           tmp = o->option;
108           s = format (s, " option-%d: skipped", tmp);
109           break;
110         }
111       o = (dhcp_option_t *) (((u8 *) o) + (o->length + 2));
112     }
113   return (s);
114 }
115
116 /*
117  * fd.io coding-style-patch-verification: ON
118  *
119  * Local Variables:
120  * eval: (c-set-style "gnu")
121  * End:
122  */