openflow: Change ofp_phy_port's 'name' member from uint8_t[] to char[].
[sliver-openvswitch.git] / lib / ofp-print.c
1 /*
2  * Copyright (c) 2008, 2009, 2010 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "ofp-print.h"
19
20 #include <errno.h>
21 #include <inttypes.h>
22 #include <sys/types.h>
23 #include <netinet/in.h>
24 #include <sys/wait.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <ctype.h>
28
29 #include "byte-order.h"
30 #include "compiler.h"
31 #include "dynamic-string.h"
32 #include "flow.h"
33 #include "ofp-util.h"
34 #include "ofpbuf.h"
35 #include "openflow/openflow.h"
36 #include "openflow/nicira-ext.h"
37 #include "packets.h"
38 #include "pcap.h"
39 #include "util.h"
40
41 static void ofp_print_port_name(struct ds *string, uint16_t port);
42 static void ofp_print_queue_name(struct ds *string, uint32_t port);
43
44 /* Returns a string that represents the contents of the Ethernet frame in the
45  * 'len' bytes starting at 'data' to 'stream' as output by tcpdump.
46  * 'total_len' specifies the full length of the Ethernet frame (of which 'len'
47  * bytes were captured).
48  *
49  * The caller must free the returned string.
50  *
51  * This starts and kills a tcpdump subprocess so it's quite expensive. */
52 char *
53 ofp_packet_to_string(const void *data, size_t len, size_t total_len OVS_UNUSED)
54 {
55     struct ds ds = DS_EMPTY_INITIALIZER;
56     struct ofpbuf buf;
57
58     char command[128];
59     FILE *pcap;
60     FILE *tcpdump;
61     int status;
62     int c;
63
64     buf.data = (void *) data;
65     buf.size = len;
66
67     pcap = tmpfile();
68     if (!pcap) {
69         ovs_error(errno, "tmpfile");
70         return xstrdup("<error>");
71     }
72     pcap_write_header(pcap);
73     pcap_write(pcap, &buf);
74     fflush(pcap);
75     if (ferror(pcap)) {
76         ovs_error(errno, "error writing temporary file");
77     }
78     rewind(pcap);
79
80     snprintf(command, sizeof command, "/usr/sbin/tcpdump -e -n -r /dev/fd/%d 2>/dev/null",
81              fileno(pcap));
82     tcpdump = popen(command, "r");
83     fclose(pcap);
84     if (!tcpdump) {
85         ovs_error(errno, "exec(\"%s\")", command);
86         return xstrdup("<error>");
87     }
88
89     while ((c = getc(tcpdump)) != EOF) {
90         ds_put_char(&ds, c);
91     }
92
93     status = pclose(tcpdump);
94     if (WIFEXITED(status)) {
95         if (WEXITSTATUS(status))
96             ovs_error(0, "tcpdump exited with status %d", WEXITSTATUS(status));
97     } else if (WIFSIGNALED(status)) {
98         ovs_error(0, "tcpdump exited with signal %d", WTERMSIG(status));
99     }
100     return ds_cstr(&ds);
101 }
102
103 /* Pretty-print the OFPT_PACKET_IN packet of 'len' bytes at 'oh' to 'stream'
104  * at the given 'verbosity' level. */
105 static void
106 ofp_packet_in(struct ds *string, const void *oh, size_t len, int verbosity)
107 {
108     const struct ofp_packet_in *op = oh;
109     size_t data_len;
110
111     ds_put_format(string, " total_len=%"PRIu16" in_port=",
112                   ntohs(op->total_len));
113     ofp_print_port_name(string, ntohs(op->in_port));
114
115     if (op->reason == OFPR_ACTION)
116         ds_put_cstr(string, " (via action)");
117     else if (op->reason != OFPR_NO_MATCH)
118         ds_put_format(string, " (***reason %"PRIu8"***)", op->reason);
119
120     data_len = len - offsetof(struct ofp_packet_in, data);
121     ds_put_format(string, " data_len=%zu", data_len);
122     if (htonl(op->buffer_id) == UINT32_MAX) {
123         ds_put_format(string, " (unbuffered)");
124         if (ntohs(op->total_len) != data_len)
125             ds_put_format(string, " (***total_len != data_len***)");
126     } else {
127         ds_put_format(string, " buffer=0x%08"PRIx32, ntohl(op->buffer_id));
128         if (ntohs(op->total_len) < data_len)
129             ds_put_format(string, " (***total_len < data_len***)");
130     }
131     ds_put_char(string, '\n');
132
133     if (verbosity > 0) {
134         struct flow flow;
135         struct ofpbuf packet;
136
137         packet.data = (void *) op->data;
138         packet.size = data_len;
139         flow_extract(&packet, 0, ntohs(op->in_port), &flow);
140         flow_format(string, &flow);
141         ds_put_char(string, '\n');
142     }
143     if (verbosity > 1) {
144         char *packet = ofp_packet_to_string(op->data, data_len,
145                                             ntohs(op->total_len));
146         ds_put_cstr(string, packet);
147         free(packet);
148     }
149 }
150
151 static void ofp_print_port_name(struct ds *string, uint16_t port)
152 {
153     const char *name;
154     switch (port) {
155     case OFPP_IN_PORT:
156         name = "IN_PORT";
157         break;
158     case OFPP_TABLE:
159         name = "TABLE";
160         break;
161     case OFPP_NORMAL:
162         name = "NORMAL";
163         break;
164     case OFPP_FLOOD:
165         name = "FLOOD";
166         break;
167     case OFPP_ALL:
168         name = "ALL";
169         break;
170     case OFPP_CONTROLLER:
171         name = "CONTROLLER";
172         break;
173     case OFPP_LOCAL:
174         name = "LOCAL";
175         break;
176     case OFPP_NONE:
177         name = "NONE";
178         break;
179     default:
180         ds_put_format(string, "%"PRIu16, port);
181         return;
182     }
183     ds_put_cstr(string, name);
184 }
185
186 static void
187 print_note(struct ds *string, const struct nx_action_note *nan)
188 {
189     size_t len;
190     size_t i;
191
192     ds_put_cstr(string, "note:");
193     len = ntohs(nan->len) - offsetof(struct nx_action_note, note);
194     for (i = 0; i < len; i++) {
195         if (i) {
196             ds_put_char(string, '.');
197         }
198         ds_put_format(string, "%02"PRIx8, nan->note[i]);
199     }
200 }
201
202 static void
203 ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
204 {
205     switch (ntohs(nah->subtype)) {
206     case NXAST_RESUBMIT: {
207         const struct nx_action_resubmit *nar = (struct nx_action_resubmit *)nah;
208         ds_put_format(string, "resubmit:");
209         ofp_print_port_name(string, ntohs(nar->in_port));
210         break;
211     }
212
213     case NXAST_SET_TUNNEL: {
214         const struct nx_action_set_tunnel *nast =
215                                             (struct nx_action_set_tunnel *)nah;
216         ds_put_format(string, "set_tunnel:0x%08"PRIx32, ntohl(nast->tun_id));
217         break;
218     }
219
220     case NXAST_DROP_SPOOFED_ARP:
221         ds_put_cstr(string, "drop_spoofed_arp");
222         break;
223
224     case NXAST_SET_QUEUE: {
225         const struct nx_action_set_queue *nasq =
226                                             (struct nx_action_set_queue *)nah;
227         ds_put_format(string, "set_queue:%u", ntohl(nasq->queue_id));
228         break;
229     }
230
231     case NXAST_POP_QUEUE:
232         ds_put_cstr(string, "pop_queue");
233         break;
234
235     case NXAST_NOTE:
236         print_note(string, (const struct nx_action_note *) nah);
237         break;
238
239     default:
240         ds_put_format(string, "***unknown Nicira action:%d***",
241                       ntohs(nah->subtype));
242     }
243 }
244
245 static int
246 ofp_print_action(struct ds *string, const struct ofp_action_header *ah,
247         size_t actions_len)
248 {
249     uint16_t type;
250     size_t len;
251
252     struct openflow_action {
253         size_t min_size;
254         size_t max_size;
255     };
256
257     const struct openflow_action of_actions[] = {
258         [OFPAT_OUTPUT] = {
259             sizeof(struct ofp_action_output),
260             sizeof(struct ofp_action_output),
261         },
262         [OFPAT_SET_VLAN_VID] = {
263             sizeof(struct ofp_action_vlan_vid),
264             sizeof(struct ofp_action_vlan_vid),
265         },
266         [OFPAT_SET_VLAN_PCP] = {
267             sizeof(struct ofp_action_vlan_pcp),
268             sizeof(struct ofp_action_vlan_pcp),
269         },
270         [OFPAT_STRIP_VLAN] = {
271             sizeof(struct ofp_action_header),
272             sizeof(struct ofp_action_header),
273         },
274         [OFPAT_SET_DL_SRC] = {
275             sizeof(struct ofp_action_dl_addr),
276             sizeof(struct ofp_action_dl_addr),
277         },
278         [OFPAT_SET_DL_DST] = {
279             sizeof(struct ofp_action_dl_addr),
280             sizeof(struct ofp_action_dl_addr),
281         },
282         [OFPAT_SET_NW_SRC] = {
283             sizeof(struct ofp_action_nw_addr),
284             sizeof(struct ofp_action_nw_addr),
285         },
286         [OFPAT_SET_NW_DST] = {
287             sizeof(struct ofp_action_nw_addr),
288             sizeof(struct ofp_action_nw_addr),
289         },
290         [OFPAT_SET_NW_TOS] = {
291             sizeof(struct ofp_action_nw_tos),
292             sizeof(struct ofp_action_nw_tos),
293         },
294         [OFPAT_SET_TP_SRC] = {
295             sizeof(struct ofp_action_tp_port),
296             sizeof(struct ofp_action_tp_port),
297         },
298         [OFPAT_SET_TP_DST] = {
299             sizeof(struct ofp_action_tp_port),
300             sizeof(struct ofp_action_tp_port),
301         }
302         /* OFPAT_VENDOR is not here, since it would blow up the array size. */
303     };
304
305     if (actions_len < sizeof *ah) {
306         ds_put_format(string, "***action array too short for next action***\n");
307         return -1;
308     }
309
310     type = ntohs(ah->type);
311     len = ntohs(ah->len);
312     if (actions_len < len) {
313         ds_put_format(string, "***truncated action %"PRIu16"***\n", type);
314         return -1;
315     }
316
317     if ((len % OFP_ACTION_ALIGN) != 0) {
318         ds_put_format(string,
319                       "***action %"PRIu16" length not a multiple of %d***\n",
320                       type, OFP_ACTION_ALIGN);
321         return -1;
322     }
323
324     if (type < ARRAY_SIZE(of_actions)) {
325         const struct openflow_action *act = &of_actions[type];
326         if ((len < act->min_size) || (len > act->max_size)) {
327             ds_put_format(string,
328                     "***action %"PRIu16" wrong length: %zu***\n", type, len);
329             return -1;
330         }
331     }
332
333     switch (type) {
334     case OFPAT_OUTPUT: {
335         struct ofp_action_output *oa = (struct ofp_action_output *)ah;
336         uint16_t port = ntohs(oa->port);
337         if (port < OFPP_MAX) {
338             ds_put_format(string, "output:%"PRIu16, port);
339         } else {
340             ofp_print_port_name(string, port);
341             if (port == OFPP_CONTROLLER) {
342                 if (oa->max_len) {
343                     ds_put_format(string, ":%"PRIu16, ntohs(oa->max_len));
344                 } else {
345                     ds_put_cstr(string, ":all");
346                 }
347             }
348         }
349         break;
350     }
351
352     case OFPAT_ENQUEUE: {
353         struct ofp_action_enqueue *ea = (struct ofp_action_enqueue *)ah;
354         unsigned int port = ntohs(ea->port);
355         unsigned int queue_id = ntohl(ea->queue_id);
356         ds_put_format(string, "enqueue:");
357         if (port != OFPP_IN_PORT) {
358             ds_put_format(string, "%u", port);
359         } else {
360             ds_put_cstr(string, "IN_PORT");
361         }
362         ds_put_format(string, "q%u", queue_id);
363         break;
364     }
365
366     case OFPAT_SET_VLAN_VID: {
367         struct ofp_action_vlan_vid *va = (struct ofp_action_vlan_vid *)ah;
368         ds_put_format(string, "mod_vlan_vid:%"PRIu16, ntohs(va->vlan_vid));
369         break;
370     }
371
372     case OFPAT_SET_VLAN_PCP: {
373         struct ofp_action_vlan_pcp *va = (struct ofp_action_vlan_pcp *)ah;
374         ds_put_format(string, "mod_vlan_pcp:%"PRIu8, va->vlan_pcp);
375         break;
376     }
377
378     case OFPAT_STRIP_VLAN:
379         ds_put_cstr(string, "strip_vlan");
380         break;
381
382     case OFPAT_SET_DL_SRC: {
383         struct ofp_action_dl_addr *da = (struct ofp_action_dl_addr *)ah;
384         ds_put_format(string, "mod_dl_src:"ETH_ADDR_FMT,
385                 ETH_ADDR_ARGS(da->dl_addr));
386         break;
387     }
388
389     case OFPAT_SET_DL_DST: {
390         struct ofp_action_dl_addr *da = (struct ofp_action_dl_addr *)ah;
391         ds_put_format(string, "mod_dl_dst:"ETH_ADDR_FMT,
392                 ETH_ADDR_ARGS(da->dl_addr));
393         break;
394     }
395
396     case OFPAT_SET_NW_SRC: {
397         struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
398         ds_put_format(string, "mod_nw_src:"IP_FMT, IP_ARGS(&na->nw_addr));
399         break;
400     }
401
402     case OFPAT_SET_NW_DST: {
403         struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
404         ds_put_format(string, "mod_nw_dst:"IP_FMT, IP_ARGS(&na->nw_addr));
405         break;
406     }
407
408     case OFPAT_SET_NW_TOS: {
409         struct ofp_action_nw_tos *nt = (struct ofp_action_nw_tos *)ah;
410         ds_put_format(string, "mod_nw_tos:%d", nt->nw_tos);
411         break;
412     }
413
414     case OFPAT_SET_TP_SRC: {
415         struct ofp_action_tp_port *ta = (struct ofp_action_tp_port *)ah;
416         ds_put_format(string, "mod_tp_src:%d", ntohs(ta->tp_port));
417         break;
418     }
419
420     case OFPAT_SET_TP_DST: {
421         struct ofp_action_tp_port *ta = (struct ofp_action_tp_port *)ah;
422         ds_put_format(string, "mod_tp_dst:%d", ntohs(ta->tp_port));
423         break;
424     }
425
426     case OFPAT_VENDOR: {
427         struct ofp_action_vendor_header *avh
428                 = (struct ofp_action_vendor_header *)ah;
429         if (len < sizeof *avh) {
430             ds_put_format(string, "***ofpat_vendor truncated***\n");
431             return -1;
432         }
433         if (avh->vendor == htonl(NX_VENDOR_ID)) {
434             ofp_print_nx_action(string, (struct nx_action_header *)avh);
435         } else {
436             ds_put_format(string, "vendor action:0x%x", ntohl(avh->vendor));
437         }
438         break;
439     }
440
441     default:
442         ds_put_format(string, "(decoder %"PRIu16" not implemented)", type);
443         break;
444     }
445
446     return len;
447 }
448
449 void
450 ofp_print_actions(struct ds *string, const struct ofp_action_header *action,
451                   size_t actions_len)
452 {
453     uint8_t *p = (uint8_t *)action;
454     int len = 0;
455
456     ds_put_cstr(string, "actions=");
457     if (!actions_len) {
458         ds_put_cstr(string, "drop");
459     }
460     while (actions_len > 0) {
461         if (len) {
462             ds_put_cstr(string, ",");
463         }
464         len = ofp_print_action(string, (struct ofp_action_header *)p,
465                 actions_len);
466         if (len < 0) {
467             return;
468         }
469         p += len;
470         actions_len -= len;
471     }
472 }
473
474 /* Pretty-print the OFPT_PACKET_OUT packet of 'len' bytes at 'oh' to 'string'
475  * at the given 'verbosity' level. */
476 static void ofp_packet_out(struct ds *string, const void *oh, size_t len,
477                            int verbosity)
478 {
479     const struct ofp_packet_out *opo = oh;
480     size_t actions_len = ntohs(opo->actions_len);
481
482     ds_put_cstr(string, " in_port=");
483     ofp_print_port_name(string, ntohs(opo->in_port));
484
485     ds_put_format(string, " actions_len=%zu ", actions_len);
486     if (actions_len > (ntohs(opo->header.length) - sizeof *opo)) {
487         ds_put_format(string, "***packet too short for action length***\n");
488         return;
489     }
490     ofp_print_actions(string, opo->actions, actions_len);
491
492     if (ntohl(opo->buffer_id) == UINT32_MAX) {
493         int data_len = len - sizeof *opo - actions_len;
494         ds_put_format(string, " data_len=%d", data_len);
495         if (verbosity > 0 && len > sizeof *opo) {
496             char *packet = ofp_packet_to_string(
497                     (uint8_t *)opo->actions + actions_len, data_len, data_len);
498             ds_put_char(string, '\n');
499             ds_put_cstr(string, packet);
500             free(packet);
501         }
502     } else {
503         ds_put_format(string, " buffer=0x%08"PRIx32, ntohl(opo->buffer_id));
504     }
505     ds_put_char(string, '\n');
506 }
507
508 /* qsort comparison function. */
509 static int
510 compare_ports(const void *a_, const void *b_)
511 {
512     const struct ofp_phy_port *a = a_;
513     const struct ofp_phy_port *b = b_;
514     uint16_t ap = ntohs(a->port_no);
515     uint16_t bp = ntohs(b->port_no);
516
517     return ap < bp ? -1 : ap > bp;
518 }
519
520 static void ofp_print_port_features(struct ds *string, uint32_t features)
521 {
522     if (features == 0) {
523         ds_put_cstr(string, "Unsupported\n");
524         return;
525     }
526     if (features & OFPPF_10MB_HD) {
527         ds_put_cstr(string, "10MB-HD ");
528     }
529     if (features & OFPPF_10MB_FD) {
530         ds_put_cstr(string, "10MB-FD ");
531     }
532     if (features & OFPPF_100MB_HD) {
533         ds_put_cstr(string, "100MB-HD ");
534     }
535     if (features & OFPPF_100MB_FD) {
536         ds_put_cstr(string, "100MB-FD ");
537     }
538     if (features & OFPPF_1GB_HD) {
539         ds_put_cstr(string, "1GB-HD ");
540     }
541     if (features & OFPPF_1GB_FD) {
542         ds_put_cstr(string, "1GB-FD ");
543     }
544     if (features & OFPPF_10GB_FD) {
545         ds_put_cstr(string, "10GB-FD ");
546     }
547     if (features & OFPPF_COPPER) {
548         ds_put_cstr(string, "COPPER ");
549     }
550     if (features & OFPPF_FIBER) {
551         ds_put_cstr(string, "FIBER ");
552     }
553     if (features & OFPPF_AUTONEG) {
554         ds_put_cstr(string, "AUTO_NEG ");
555     }
556     if (features & OFPPF_PAUSE) {
557         ds_put_cstr(string, "AUTO_PAUSE ");
558     }
559     if (features & OFPPF_PAUSE_ASYM) {
560         ds_put_cstr(string, "AUTO_PAUSE_ASYM ");
561     }
562     ds_put_char(string, '\n');
563 }
564
565 static void
566 ofp_print_phy_port(struct ds *string, const struct ofp_phy_port *port)
567 {
568     char name[OFP_MAX_PORT_NAME_LEN];
569     int j;
570
571     memcpy(name, port->name, sizeof name);
572     for (j = 0; j < sizeof name - 1; j++) {
573         if (!isprint(name[j])) {
574             break;
575         }
576     }
577     name[j] = '\0';
578
579     ds_put_char(string, ' ');
580     ofp_print_port_name(string, ntohs(port->port_no));
581     ds_put_format(string, "(%s): addr:"ETH_ADDR_FMT", config: %#x, state:%#x\n",
582             name, ETH_ADDR_ARGS(port->hw_addr), ntohl(port->config),
583             ntohl(port->state));
584     if (port->curr) {
585         ds_put_format(string, "     current:    ");
586         ofp_print_port_features(string, ntohl(port->curr));
587     }
588     if (port->advertised) {
589         ds_put_format(string, "     advertised: ");
590         ofp_print_port_features(string, ntohl(port->advertised));
591     }
592     if (port->supported) {
593         ds_put_format(string, "     supported:  ");
594         ofp_print_port_features(string, ntohl(port->supported));
595     }
596     if (port->peer) {
597         ds_put_format(string, "     peer:       ");
598         ofp_print_port_features(string, ntohl(port->peer));
599     }
600 }
601
602 /* Pretty-print the struct ofp_switch_features of 'len' bytes at 'oh' to
603  * 'string' at the given 'verbosity' level. */
604 static void
605 ofp_print_switch_features(struct ds *string, const void *oh, size_t len,
606                           int verbosity OVS_UNUSED)
607 {
608     const struct ofp_switch_features *osf = oh;
609     struct ofp_phy_port *port_list;
610     int n_ports;
611     int i;
612
613     ds_put_format(string, " ver:0x%x, dpid:%016"PRIx64"\n",
614             osf->header.version, ntohll(osf->datapath_id));
615     ds_put_format(string, "n_tables:%d, n_buffers:%d\n", osf->n_tables,
616             ntohl(osf->n_buffers));
617     ds_put_format(string, "features: capabilities:%#x, actions:%#x\n",
618            ntohl(osf->capabilities), ntohl(osf->actions));
619
620     if (ntohs(osf->header.length) >= sizeof *osf) {
621         len = MIN(len, ntohs(osf->header.length));
622     }
623     n_ports = (len - sizeof *osf) / sizeof *osf->ports;
624
625     port_list = xmemdup(osf->ports, len - sizeof *osf);
626     qsort(port_list, n_ports, sizeof *port_list, compare_ports);
627     for (i = 0; i < n_ports; i++) {
628         ofp_print_phy_port(string, &port_list[i]);
629     }
630     free(port_list);
631 }
632
633 /* Pretty-print the struct ofp_switch_config of 'len' bytes at 'oh' to 'string'
634  * at the given 'verbosity' level. */
635 static void
636 ofp_print_switch_config(struct ds *string, const void *oh,
637                         size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
638 {
639     const struct ofp_switch_config *osc = oh;
640     uint16_t flags;
641
642     flags = ntohs(osc->flags);
643     if (flags) {
644         ds_put_format(string, " ***unknown flags 0x%04"PRIx16"***", flags);
645     }
646
647     ds_put_format(string, " miss_send_len=%"PRIu16"\n", ntohs(osc->miss_send_len));
648 }
649
650 static void print_wild(struct ds *string, const char *leader, int is_wild,
651             int verbosity, const char *format, ...)
652             __attribute__((format(printf, 5, 6)));
653
654 static void print_wild(struct ds *string, const char *leader, int is_wild,
655                        int verbosity, const char *format, ...)
656 {
657     if (is_wild && verbosity < 2) {
658         return;
659     }
660     ds_put_cstr(string, leader);
661     if (!is_wild) {
662         va_list args;
663
664         va_start(args, format);
665         ds_put_format_valist(string, format, args);
666         va_end(args);
667     } else {
668         ds_put_char(string, '*');
669     }
670     ds_put_char(string, ',');
671 }
672
673 static void
674 print_ip_netmask(struct ds *string, const char *leader, uint32_t ip,
675                  uint32_t wild_bits, int verbosity)
676 {
677     if (wild_bits >= 32 && verbosity < 2) {
678         return;
679     }
680     ds_put_cstr(string, leader);
681     if (wild_bits < 32) {
682         ds_put_format(string, IP_FMT, IP_ARGS(&ip));
683         if (wild_bits) {
684             ds_put_format(string, "/%d", 32 - wild_bits);
685         }
686     } else {
687         ds_put_char(string, '*');
688     }
689     ds_put_char(string, ',');
690 }
691
692 void
693 ofp_print_match(struct ds *f, const struct ofp_match *om, int verbosity)
694 {
695     char *s = ofp_match_to_string(om, verbosity);
696     ds_put_cstr(f, s);
697     free(s);
698 }
699
700 char *
701 ofp_match_to_string(const struct ofp_match *om, int verbosity)
702 {
703     struct ds f = DS_EMPTY_INITIALIZER;
704     uint32_t w = ntohl(om->wildcards);
705     bool skip_type = false;
706     bool skip_proto = false;
707
708     if (!(w & OFPFW_DL_TYPE)) {
709         skip_type = true;
710         if (om->dl_type == htons(ETH_TYPE_IP)) {
711             if (!(w & OFPFW_NW_PROTO)) {
712                 skip_proto = true;
713                 if (om->nw_proto == IP_TYPE_ICMP) {
714                     ds_put_cstr(&f, "icmp,");
715                 } else if (om->nw_proto == IP_TYPE_TCP) {
716                     ds_put_cstr(&f, "tcp,");
717                 } else if (om->nw_proto == IP_TYPE_UDP) {
718                     ds_put_cstr(&f, "udp,");
719                 } else {
720                     ds_put_cstr(&f, "ip,");
721                     skip_proto = false;
722                 }
723             } else {
724                 ds_put_cstr(&f, "ip,");
725             }
726         } else if (om->dl_type == htons(ETH_TYPE_ARP)) {
727             ds_put_cstr(&f, "arp,");
728         } else {
729             skip_type = false;
730         }
731     }
732     if (w & NXFW_TUN_ID) {
733         ds_put_cstr(&f, "tun_id_wild,");
734     }
735     print_wild(&f, "in_port=", w & OFPFW_IN_PORT, verbosity,
736                "%d", ntohs(om->in_port));
737     print_wild(&f, "dl_vlan=", w & OFPFW_DL_VLAN, verbosity,
738                "%d", ntohs(om->dl_vlan));
739     print_wild(&f, "dl_vlan_pcp=", w & OFPFW_DL_VLAN_PCP, verbosity,
740                "%d", om->dl_vlan_pcp);
741     print_wild(&f, "dl_src=", w & OFPFW_DL_SRC, verbosity,
742                ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_src));
743     print_wild(&f, "dl_dst=", w & OFPFW_DL_DST, verbosity,
744                ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_dst));
745     if (!skip_type) {
746         print_wild(&f, "dl_type=", w & OFPFW_DL_TYPE, verbosity,
747                    "0x%04x", ntohs(om->dl_type));
748     }
749     print_ip_netmask(&f, "nw_src=", om->nw_src,
750                      (w & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT, verbosity);
751     print_ip_netmask(&f, "nw_dst=", om->nw_dst,
752                      (w & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT, verbosity);
753     if (!skip_proto) {
754         if (om->dl_type == htons(ETH_TYPE_ARP)) {
755             print_wild(&f, "opcode=", w & OFPFW_NW_PROTO, verbosity,
756                        "%u", om->nw_proto);
757         } else {
758             print_wild(&f, "nw_proto=", w & OFPFW_NW_PROTO, verbosity,
759                        "%u", om->nw_proto);
760         }
761     }
762     print_wild(&f, "nw_tos=", w & OFPFW_NW_TOS, verbosity,
763                "%u", om->nw_tos);
764     if (om->nw_proto == IP_TYPE_ICMP) {
765         print_wild(&f, "icmp_type=", w & OFPFW_ICMP_TYPE, verbosity,
766                    "%d", ntohs(om->icmp_type));
767         print_wild(&f, "icmp_code=", w & OFPFW_ICMP_CODE, verbosity,
768                    "%d", ntohs(om->icmp_code));
769     } else {
770         print_wild(&f, "tp_src=", w & OFPFW_TP_SRC, verbosity,
771                    "%d", ntohs(om->tp_src));
772         print_wild(&f, "tp_dst=", w & OFPFW_TP_DST, verbosity,
773                    "%d", ntohs(om->tp_dst));
774     }
775     return ds_cstr(&f);
776 }
777
778 /* Pretty-print the OFPT_FLOW_MOD packet of 'len' bytes at 'oh' to 'string'
779  * at the given 'verbosity' level. */
780 static void
781 ofp_print_flow_mod(struct ds *string, const void *oh, size_t len,
782                    int verbosity)
783 {
784     const struct ofp_flow_mod *ofm = oh;
785
786     ds_put_char(string, ' ');
787     ofp_print_match(string, &ofm->match, verbosity);
788     if (ds_last(string) != ' ') {
789         ds_put_char(string, ' ');
790     }
791
792     switch (ntohs(ofm->command)) {
793     case OFPFC_ADD:
794         ds_put_cstr(string, "ADD:");
795         break;
796     case OFPFC_MODIFY:
797         ds_put_cstr(string, "MOD:");
798         break;
799     case OFPFC_MODIFY_STRICT:
800         ds_put_cstr(string, "MOD_STRICT:");
801         break;
802     case OFPFC_DELETE:
803         ds_put_cstr(string, "DEL:");
804         break;
805     case OFPFC_DELETE_STRICT:
806         ds_put_cstr(string, "DEL_STRICT:");
807         break;
808     default:
809         ds_put_format(string, "cmd:%d", ntohs(ofm->command));
810     }
811     if (ofm->cookie != htonll(0)) {
812         ds_put_format(string, " cookie:0x%"PRIx64, ntohll(ofm->cookie));
813     }
814     if (ofm->idle_timeout != htons(OFP_FLOW_PERMANENT)) {
815         ds_put_format(string, " idle:%d", ntohs(ofm->idle_timeout));
816     }
817     if (ofm->hard_timeout != htons(OFP_FLOW_PERMANENT)) {
818         ds_put_format(string, " hard:%d", ntohs(ofm->hard_timeout));
819     }
820     if (ofm->priority != htons(32768)) {
821         ds_put_format(string, " pri:%"PRIu16, ntohs(ofm->priority));
822     }
823     if (ofm->buffer_id != htonl(UINT32_MAX)) {
824         ds_put_format(string, " buf:%#"PRIx32, ntohl(ofm->buffer_id));
825     }
826     if (ofm->flags != htons(0)) {
827         ds_put_format(string, " flags:%"PRIx16, ntohs(ofm->flags));
828     }
829     ds_put_cstr(string, " ");
830     ofp_print_actions(string, ofm->actions,
831                       len - offsetof(struct ofp_flow_mod, actions));
832     ds_put_char(string, '\n');
833 }
834
835 /* Pretty-print the OFPT_FLOW_REMOVED packet of 'len' bytes at 'oh' to 'string'
836  * at the given 'verbosity' level. */
837 static void
838 ofp_print_flow_removed(struct ds *string, const void *oh,
839                        size_t len OVS_UNUSED, int verbosity)
840 {
841     const struct ofp_flow_removed *ofr = oh;
842
843     ofp_print_match(string, &ofr->match, verbosity);
844     ds_put_cstr(string, " reason=");
845     switch (ofr->reason) {
846     case OFPRR_IDLE_TIMEOUT:
847         ds_put_cstr(string, "idle");
848         break;
849     case OFPRR_HARD_TIMEOUT:
850         ds_put_cstr(string, "hard");
851         break;
852     case OFPRR_DELETE:
853         ds_put_cstr(string, "delete");
854         break;
855     default:
856         ds_put_format(string, "**%"PRIu8"**", ofr->reason);
857         break;
858     }
859
860     if (ofr->cookie != htonll(0)) {
861         ds_put_format(string, " cookie:0x%"PRIx64, ntohll(ofr->cookie));
862     }
863     if (ofr->priority != htons(32768)) {
864         ds_put_format(string, " pri:%"PRIu16, ntohs(ofr->priority));
865     }
866     ds_put_format(string, " secs%"PRIu32" nsecs%"PRIu32
867          " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
868          ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec),
869          ntohs(ofr->idle_timeout), ntohll(ofr->packet_count),
870          ntohll(ofr->byte_count));
871 }
872
873 static void
874 ofp_print_port_mod(struct ds *string, const void *oh, size_t len OVS_UNUSED,
875                    int verbosity OVS_UNUSED)
876 {
877     const struct ofp_port_mod *opm = oh;
878
879     ds_put_format(string, "port: %d: addr:"ETH_ADDR_FMT", config: %#x, mask:%#x\n",
880             ntohs(opm->port_no), ETH_ADDR_ARGS(opm->hw_addr),
881             ntohl(opm->config), ntohl(opm->mask));
882     ds_put_format(string, "     advertise: ");
883     if (opm->advertise) {
884         ofp_print_port_features(string, ntohl(opm->advertise));
885     } else {
886         ds_put_format(string, "UNCHANGED\n");
887     }
888 }
889
890 struct error_type {
891     int type;
892     int code;
893     const char *name;
894 };
895
896 static const struct error_type error_types[] = {
897 #define ERROR_TYPE(TYPE) {TYPE, -1, #TYPE}
898 #define ERROR_CODE(TYPE, CODE) {TYPE, CODE, #CODE}
899     ERROR_TYPE(OFPET_HELLO_FAILED),
900     ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_INCOMPATIBLE),
901     ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_EPERM),
902
903     ERROR_TYPE(OFPET_BAD_REQUEST),
904     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION),
905     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE),
906     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_STAT),
907     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR),
908     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE),
909     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_EPERM),
910     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN),
911     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_EMPTY),
912     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_UNKNOWN),
913
914     ERROR_TYPE(OFPET_BAD_ACTION),
915     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE),
916     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_LEN),
917     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR),
918     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE),
919     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT),
920     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT),
921     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_EPERM),
922     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_TOO_MANY),
923
924     ERROR_TYPE(OFPET_FLOW_MOD_FAILED),
925     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL),
926     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_OVERLAP),
927     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM),
928     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_EMERG_TIMEOUT),
929     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND),
930
931     ERROR_TYPE(OFPET_PORT_MOD_FAILED),
932     ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_PORT),
933     ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_HW_ADDR)
934 };
935 #define N_ERROR_TYPES ARRAY_SIZE(error_types)
936
937 static const char *
938 lookup_error_type(int type)
939 {
940     const struct error_type *t;
941
942     for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
943         if (t->type == type && t->code == -1) {
944             return t->name;
945         }
946     }
947     return "?";
948 }
949
950 static const char *
951 lookup_error_code(int type, int code)
952 {
953     const struct error_type *t;
954
955     for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
956         if (t->type == type && t->code == code) {
957             return t->name;
958         }
959     }
960     return "?";
961 }
962
963 /* Pretty-print the OFPT_ERROR packet of 'len' bytes at 'oh' to 'string'
964  * at the given 'verbosity' level. */
965 static void
966 ofp_print_error_msg(struct ds *string, const void *oh, size_t len,
967                        int verbosity OVS_UNUSED)
968 {
969     const struct ofp_error_msg *oem = oh;
970     int type = ntohs(oem->type);
971     int code = ntohs(oem->code);
972     char *s;
973
974     ds_put_format(string, " type%d(%s) code%d(%s) payload:\n",
975                   type, lookup_error_type(type),
976                   code, lookup_error_code(type, code));
977
978     switch (type) {
979     case OFPET_HELLO_FAILED:
980         ds_put_printable(string, (char *) oem->data, len - sizeof *oem);
981         break;
982
983     case OFPET_BAD_REQUEST:
984         s = ofp_to_string(oem->data, len - sizeof *oem, 1);
985         ds_put_cstr(string, s);
986         free(s);
987         break;
988
989     default:
990         ds_put_hex_dump(string, oem->data, len - sizeof *oem, 0, true);
991         break;
992     }
993 }
994
995 /* Pretty-print the OFPT_PORT_STATUS packet of 'len' bytes at 'oh' to 'string'
996  * at the given 'verbosity' level. */
997 static void
998 ofp_print_port_status(struct ds *string, const void *oh, size_t len OVS_UNUSED,
999                       int verbosity OVS_UNUSED)
1000 {
1001     const struct ofp_port_status *ops = oh;
1002
1003     if (ops->reason == OFPPR_ADD) {
1004         ds_put_format(string, " ADD:");
1005     } else if (ops->reason == OFPPR_DELETE) {
1006         ds_put_format(string, " DEL:");
1007     } else if (ops->reason == OFPPR_MODIFY) {
1008         ds_put_format(string, " MOD:");
1009     }
1010
1011     ofp_print_phy_port(string, &ops->desc);
1012 }
1013
1014 static void
1015 ofp_desc_stats_reply(struct ds *string, const void *body,
1016                      size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1017 {
1018     const struct ofp_desc_stats *ods = body;
1019
1020     ds_put_format(string, "Manufacturer: %.*s\n",
1021             (int) sizeof ods->mfr_desc, ods->mfr_desc);
1022     ds_put_format(string, "Hardware: %.*s\n",
1023             (int) sizeof ods->hw_desc, ods->hw_desc);
1024     ds_put_format(string, "Software: %.*s\n",
1025             (int) sizeof ods->sw_desc, ods->sw_desc);
1026     ds_put_format(string, "Serial Num: %.*s\n",
1027             (int) sizeof ods->serial_num, ods->serial_num);
1028     ds_put_format(string, "DP Description: %.*s\n",
1029             (int) sizeof ods->dp_desc, ods->dp_desc);
1030 }
1031
1032 static void
1033 ofp_flow_stats_request(struct ds *string, const void *oh,
1034                        size_t len OVS_UNUSED, int verbosity)
1035 {
1036     const struct ofp_flow_stats_request *fsr = oh;
1037
1038     if (fsr->table_id == 0xff) {
1039         ds_put_format(string, " table_id=any, ");
1040     } else {
1041         ds_put_format(string, " table_id=%"PRIu8", ", fsr->table_id);
1042     }
1043
1044     ofp_print_match(string, &fsr->match, verbosity);
1045 }
1046
1047 static void
1048 ofp_flow_stats_reply(struct ds *string, const void *body_, size_t len,
1049                      int verbosity)
1050 {
1051     const char *body = body_;
1052     const char *pos = body;
1053     for (;;) {
1054         const struct ofp_flow_stats *fs;
1055         ptrdiff_t bytes_left = body + len - pos;
1056         size_t length;
1057
1058         if (bytes_left < sizeof *fs) {
1059             if (bytes_left != 0) {
1060                 ds_put_format(string, " ***%td leftover bytes at end***",
1061                               bytes_left);
1062             }
1063             break;
1064         }
1065
1066         fs = (const void *) pos;
1067         length = ntohs(fs->length);
1068         if (length < sizeof *fs) {
1069             ds_put_format(string, " ***length=%zu shorter than minimum %zu***",
1070                           length, sizeof *fs);
1071             break;
1072         } else if (length > bytes_left) {
1073             ds_put_format(string,
1074                           " ***length=%zu but only %td bytes left***",
1075                           length, bytes_left);
1076             break;
1077         } else if ((length - sizeof *fs) % sizeof fs->actions[0]) {
1078             ds_put_format(string,
1079                           " ***length=%zu has %zu bytes leftover in "
1080                           "final action***",
1081                           length,
1082                           (length - sizeof *fs) % sizeof fs->actions[0]);
1083             break;
1084         }
1085
1086         ds_put_format(string, "  cookie=0x%"PRIx64", ", ntohll(fs->cookie));
1087         ds_put_format(string, "duration_sec=%"PRIu32"s, ",
1088                     ntohl(fs->duration_sec));
1089         ds_put_format(string, "duration_nsec=%"PRIu32"ns, ",
1090                     ntohl(fs->duration_nsec));
1091         ds_put_format(string, "table_id=%"PRIu8", ", fs->table_id);
1092         ds_put_format(string, "priority=%"PRIu16", ",
1093                     fs->match.wildcards ? ntohs(fs->priority) : (uint16_t)-1);
1094         ds_put_format(string, "n_packets=%"PRIu64", ",
1095                     ntohll(fs->packet_count));
1096         ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count));
1097         if (fs->idle_timeout != htons(OFP_FLOW_PERMANENT)) {
1098             ds_put_format(string, "idle_timeout=%"PRIu16",",
1099                           ntohs(fs->idle_timeout));
1100         }
1101         if (fs->hard_timeout != htons(OFP_FLOW_PERMANENT)) {
1102             ds_put_format(string, "hard_timeout=%"PRIu16",",
1103                           ntohs(fs->hard_timeout));
1104         }
1105         ofp_print_match(string, &fs->match, verbosity);
1106         ofp_print_actions(string, fs->actions, length - sizeof *fs);
1107         ds_put_char(string, '\n');
1108
1109         pos += length;
1110      }
1111 }
1112
1113 static void
1114 ofp_aggregate_stats_request(struct ds *string, const void *oh,
1115                             size_t len OVS_UNUSED, int verbosity)
1116 {
1117     const struct ofp_aggregate_stats_request *asr = oh;
1118
1119     if (asr->table_id == 0xff) {
1120         ds_put_format(string, " table_id=any, ");
1121     } else {
1122         ds_put_format(string, " table_id=%"PRIu8", ", asr->table_id);
1123     }
1124
1125     ofp_print_match(string, &asr->match, verbosity);
1126 }
1127
1128 static void
1129 ofp_aggregate_stats_reply(struct ds *string, const void *body_,
1130                           size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1131 {
1132     const struct ofp_aggregate_stats_reply *asr = body_;
1133
1134     ds_put_format(string, " packet_count=%"PRIu64, ntohll(asr->packet_count));
1135     ds_put_format(string, " byte_count=%"PRIu64, ntohll(asr->byte_count));
1136     ds_put_format(string, " flow_count=%"PRIu32, ntohl(asr->flow_count));
1137 }
1138
1139 static void print_port_stat(struct ds *string, const char *leader,
1140                             uint64_t stat, int more)
1141 {
1142     ds_put_cstr(string, leader);
1143     if (stat != -1) {
1144         ds_put_format(string, "%"PRIu64, stat);
1145     } else {
1146         ds_put_char(string, '?');
1147     }
1148     if (more) {
1149         ds_put_cstr(string, ", ");
1150     } else {
1151         ds_put_cstr(string, "\n");
1152     }
1153 }
1154
1155 static void
1156 ofp_port_stats_request(struct ds *string, const void *body_,
1157                        size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1158 {
1159     const struct ofp_port_stats_request *psr = body_;
1160     ds_put_format(string, "port_no=%"PRIu16, ntohs(psr->port_no));
1161 }
1162
1163 static void
1164 ofp_port_stats_reply(struct ds *string, const void *body, size_t len,
1165                      int verbosity)
1166 {
1167     const struct ofp_port_stats *ps = body;
1168     size_t n = len / sizeof *ps;
1169     ds_put_format(string, " %zu ports\n", n);
1170     if (verbosity < 1) {
1171         return;
1172     }
1173
1174     for (; n--; ps++) {
1175         ds_put_format(string, "  port %2"PRIu16": ", ntohs(ps->port_no));
1176
1177         ds_put_cstr(string, "rx ");
1178         print_port_stat(string, "pkts=", ntohll(ps->rx_packets), 1);
1179         print_port_stat(string, "bytes=", ntohll(ps->rx_bytes), 1);
1180         print_port_stat(string, "drop=", ntohll(ps->rx_dropped), 1);
1181         print_port_stat(string, "errs=", ntohll(ps->rx_errors), 1);
1182         print_port_stat(string, "frame=", ntohll(ps->rx_frame_err), 1);
1183         print_port_stat(string, "over=", ntohll(ps->rx_over_err), 1);
1184         print_port_stat(string, "crc=", ntohll(ps->rx_crc_err), 0);
1185
1186         ds_put_cstr(string, "           tx ");
1187         print_port_stat(string, "pkts=", ntohll(ps->tx_packets), 1);
1188         print_port_stat(string, "bytes=", ntohll(ps->tx_bytes), 1);
1189         print_port_stat(string, "drop=", ntohll(ps->tx_dropped), 1);
1190         print_port_stat(string, "errs=", ntohll(ps->tx_errors), 1);
1191         print_port_stat(string, "coll=", ntohll(ps->collisions), 0);
1192     }
1193 }
1194
1195 static void
1196 ofp_table_stats_reply(struct ds *string, const void *body, size_t len,
1197                      int verbosity)
1198 {
1199     const struct ofp_table_stats *ts = body;
1200     size_t n = len / sizeof *ts;
1201     ds_put_format(string, " %zu tables\n", n);
1202     if (verbosity < 1) {
1203         return;
1204     }
1205
1206     for (; n--; ts++) {
1207         char name[OFP_MAX_TABLE_NAME_LEN + 1];
1208         strncpy(name, ts->name, sizeof name);
1209         name[OFP_MAX_TABLE_NAME_LEN] = '\0';
1210
1211         ds_put_format(string, "  %d: %-8s: ", ts->table_id, name);
1212         ds_put_format(string, "wild=0x%05"PRIx32", ", ntohl(ts->wildcards));
1213         ds_put_format(string, "max=%6"PRIu32", ", ntohl(ts->max_entries));
1214         ds_put_format(string, "active=%"PRIu32"\n", ntohl(ts->active_count));
1215         ds_put_cstr(string, "               ");
1216         ds_put_format(string, "lookup=%"PRIu64", ",
1217                     ntohll(ts->lookup_count));
1218         ds_put_format(string, "matched=%"PRIu64"\n",
1219                     ntohll(ts->matched_count));
1220      }
1221 }
1222
1223 static void
1224 ofp_print_queue_name(struct ds *string, uint32_t queue_id)
1225 {
1226     if (queue_id == OFPQ_ALL) {
1227         ds_put_cstr(string, "ALL");
1228     } else {
1229         ds_put_format(string, "%"PRIu32, queue_id);
1230     }
1231 }
1232
1233 static void
1234 ofp_queue_stats_request(struct ds *string, const void *body_,
1235                        size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1236 {
1237     const struct ofp_queue_stats_request *qsr = body_;
1238
1239     ds_put_cstr(string, "port=");
1240     ofp_print_port_name(string, ntohs(qsr->port_no));
1241
1242     ds_put_cstr(string, " queue=");
1243     ofp_print_queue_name(string, ntohl(qsr->queue_id));
1244 }
1245
1246 static void
1247 ofp_queue_stats_reply(struct ds *string, const void *body, size_t len,
1248                      int verbosity)
1249 {
1250     const struct ofp_queue_stats *qs = body;
1251     size_t n = len / sizeof *qs;
1252     ds_put_format(string, " %zu queues\n", n);
1253     if (verbosity < 1) {
1254         return;
1255     }
1256
1257     for (; n--; qs++) {
1258         ds_put_cstr(string, "  port ");
1259         ofp_print_port_name(string, ntohs(qs->port_no));
1260         ds_put_cstr(string, " queue ");
1261         ofp_print_queue_name(string, ntohl(qs->queue_id));
1262         ds_put_cstr(string, ": ");
1263
1264         print_port_stat(string, "bytes=", ntohll(qs->tx_bytes), 1);
1265         print_port_stat(string, "pkts=", ntohll(qs->tx_packets), 1);
1266         print_port_stat(string, "errors=", ntohll(qs->tx_errors), 0);
1267     }
1268 }
1269
1270 static void
1271 vendor_stat(struct ds *string, const void *body, size_t len,
1272             int verbosity OVS_UNUSED)
1273 {
1274     ds_put_format(string, " vendor=%08"PRIx32, ntohl(*(uint32_t *) body));
1275     ds_put_format(string, " %zu bytes additional data",
1276                   len - sizeof(uint32_t));
1277 }
1278
1279 enum stats_direction {
1280     REQUEST,
1281     REPLY
1282 };
1283
1284 static void
1285 print_stats(struct ds *string, int type, const void *body, size_t body_len,
1286             int verbosity, enum stats_direction direction)
1287 {
1288     struct stats_msg {
1289         size_t min_body, max_body;
1290         void (*printer)(struct ds *, const void *, size_t len, int verbosity);
1291     };
1292
1293     struct stats_type {
1294         int type;
1295         const char *name;
1296         struct stats_msg request;
1297         struct stats_msg reply;
1298     };
1299
1300     static const struct stats_type stats_types[] = {
1301         {
1302             OFPST_DESC,
1303             "description",
1304             { 0, 0, NULL },
1305             { 0, SIZE_MAX, ofp_desc_stats_reply },
1306         },
1307         {
1308             OFPST_FLOW,
1309             "flow",
1310             { sizeof(struct ofp_flow_stats_request),
1311               sizeof(struct ofp_flow_stats_request),
1312               ofp_flow_stats_request },
1313             { 0, SIZE_MAX, ofp_flow_stats_reply },
1314         },
1315         {
1316             OFPST_AGGREGATE,
1317             "aggregate",
1318             { sizeof(struct ofp_aggregate_stats_request),
1319               sizeof(struct ofp_aggregate_stats_request),
1320               ofp_aggregate_stats_request },
1321             { sizeof(struct ofp_aggregate_stats_reply),
1322               sizeof(struct ofp_aggregate_stats_reply),
1323               ofp_aggregate_stats_reply },
1324         },
1325         {
1326             OFPST_TABLE,
1327             "table",
1328             { 0, 0, NULL },
1329             { 0, SIZE_MAX, ofp_table_stats_reply },
1330         },
1331         {
1332             OFPST_PORT,
1333             "port",
1334             { sizeof(struct ofp_port_stats_request),
1335               sizeof(struct ofp_port_stats_request),
1336               ofp_port_stats_request },
1337             { 0, SIZE_MAX, ofp_port_stats_reply },
1338         },
1339         {
1340             OFPST_QUEUE,
1341             "queue",
1342             { sizeof(struct ofp_queue_stats_request),
1343               sizeof(struct ofp_queue_stats_request),
1344               ofp_queue_stats_request },
1345             { 0, SIZE_MAX, ofp_queue_stats_reply },
1346         },
1347         {
1348             OFPST_VENDOR,
1349             "vendor-specific",
1350             { sizeof(uint32_t), SIZE_MAX, vendor_stat },
1351             { sizeof(uint32_t), SIZE_MAX, vendor_stat },
1352         },
1353         {
1354             -1,
1355             "unknown",
1356             { 0, 0, NULL, },
1357             { 0, 0, NULL, },
1358         },
1359     };
1360
1361     const struct stats_type *s;
1362     const struct stats_msg *m;
1363
1364     if (type >= ARRAY_SIZE(stats_types) || !stats_types[type].name) {
1365         ds_put_format(string, " ***unknown type %d***", type);
1366         return;
1367     }
1368     for (s = stats_types; s->type >= 0; s++) {
1369         if (s->type == type) {
1370             break;
1371         }
1372     }
1373     ds_put_format(string, " type=%d(%s)\n", type, s->name);
1374
1375     m = direction == REQUEST ? &s->request : &s->reply;
1376     if (body_len < m->min_body || body_len > m->max_body) {
1377         ds_put_format(string, " ***body_len=%zu not in %zu...%zu***",
1378                       body_len, m->min_body, m->max_body);
1379         return;
1380     }
1381     if (m->printer) {
1382         m->printer(string, body, body_len, verbosity);
1383     }
1384 }
1385
1386 static void
1387 ofp_stats_request(struct ds *string, const void *oh, size_t len, int verbosity)
1388 {
1389     const struct ofp_stats_request *srq = oh;
1390
1391     if (srq->flags) {
1392         ds_put_format(string, " ***unknown flags 0x%04"PRIx16"***",
1393                       ntohs(srq->flags));
1394     }
1395
1396     print_stats(string, ntohs(srq->type), srq->body,
1397                 len - offsetof(struct ofp_stats_request, body),
1398                 verbosity, REQUEST);
1399 }
1400
1401 static void
1402 ofp_stats_reply(struct ds *string, const void *oh, size_t len, int verbosity)
1403 {
1404     const struct ofp_stats_reply *srp = oh;
1405
1406     ds_put_cstr(string, " flags=");
1407     if (!srp->flags) {
1408         ds_put_cstr(string, "none");
1409     } else {
1410         uint16_t flags = ntohs(srp->flags);
1411         if (flags & OFPSF_REPLY_MORE) {
1412             ds_put_cstr(string, "[more]");
1413             flags &= ~OFPSF_REPLY_MORE;
1414         }
1415         if (flags) {
1416             ds_put_format(string, "[***unknown flags 0x%04"PRIx16"***]", flags);
1417         }
1418     }
1419
1420     print_stats(string, ntohs(srp->type), srp->body,
1421                 len - offsetof(struct ofp_stats_reply, body),
1422                 verbosity, REPLY);
1423 }
1424
1425 static void
1426 ofp_echo(struct ds *string, const void *oh, size_t len, int verbosity)
1427 {
1428     const struct ofp_header *hdr = oh;
1429
1430     ds_put_format(string, " %zu bytes of payload\n", len - sizeof *hdr);
1431     if (verbosity > 1) {
1432         ds_put_hex_dump(string, hdr, len - sizeof *hdr, 0, true);
1433     }
1434 }
1435
1436 struct openflow_packet {
1437     uint8_t type;
1438     const char *name;
1439     size_t min_size;
1440     void (*printer)(struct ds *, const void *, size_t len, int verbosity);
1441 };
1442
1443 static const struct openflow_packet packets[] = {
1444     {
1445         OFPT_HELLO,
1446         "hello",
1447         sizeof (struct ofp_header),
1448         NULL,
1449     },
1450     {
1451         OFPT_FEATURES_REQUEST,
1452         "features_request",
1453         sizeof (struct ofp_header),
1454         NULL,
1455     },
1456     {
1457         OFPT_FEATURES_REPLY,
1458         "features_reply",
1459         sizeof (struct ofp_switch_features),
1460         ofp_print_switch_features,
1461     },
1462     {
1463         OFPT_GET_CONFIG_REQUEST,
1464         "get_config_request",
1465         sizeof (struct ofp_header),
1466         NULL,
1467     },
1468     {
1469         OFPT_GET_CONFIG_REPLY,
1470         "get_config_reply",
1471         sizeof (struct ofp_switch_config),
1472         ofp_print_switch_config,
1473     },
1474     {
1475         OFPT_SET_CONFIG,
1476         "set_config",
1477         sizeof (struct ofp_switch_config),
1478         ofp_print_switch_config,
1479     },
1480     {
1481         OFPT_PACKET_IN,
1482         "packet_in",
1483         offsetof(struct ofp_packet_in, data),
1484         ofp_packet_in,
1485     },
1486     {
1487         OFPT_PACKET_OUT,
1488         "packet_out",
1489         sizeof (struct ofp_packet_out),
1490         ofp_packet_out,
1491     },
1492     {
1493         OFPT_FLOW_MOD,
1494         "flow_mod",
1495         sizeof (struct ofp_flow_mod),
1496         ofp_print_flow_mod,
1497     },
1498     {
1499         OFPT_FLOW_REMOVED,
1500         "flow_removed",
1501         sizeof (struct ofp_flow_removed),
1502         ofp_print_flow_removed,
1503     },
1504     {
1505         OFPT_PORT_MOD,
1506         "port_mod",
1507         sizeof (struct ofp_port_mod),
1508         ofp_print_port_mod,
1509     },
1510     {
1511         OFPT_PORT_STATUS,
1512         "port_status",
1513         sizeof (struct ofp_port_status),
1514         ofp_print_port_status
1515     },
1516     {
1517         OFPT_ERROR,
1518         "error_msg",
1519         sizeof (struct ofp_error_msg),
1520         ofp_print_error_msg,
1521     },
1522     {
1523         OFPT_STATS_REQUEST,
1524         "stats_request",
1525         sizeof (struct ofp_stats_request),
1526         ofp_stats_request,
1527     },
1528     {
1529         OFPT_STATS_REPLY,
1530         "stats_reply",
1531         sizeof (struct ofp_stats_reply),
1532         ofp_stats_reply,
1533     },
1534     {
1535         OFPT_ECHO_REQUEST,
1536         "echo_request",
1537         sizeof (struct ofp_header),
1538         ofp_echo,
1539     },
1540     {
1541         OFPT_ECHO_REPLY,
1542         "echo_reply",
1543         sizeof (struct ofp_header),
1544         ofp_echo,
1545     },
1546     {
1547         OFPT_VENDOR,
1548         "vendor",
1549         sizeof (struct ofp_vendor_header),
1550         NULL,
1551     },
1552     {
1553         OFPT_BARRIER_REQUEST,
1554         "barrier_request",
1555         sizeof (struct ofp_header),
1556         NULL,
1557     },
1558     {
1559         OFPT_BARRIER_REPLY,
1560         "barrier_reply",
1561         sizeof (struct ofp_header),
1562         NULL,
1563     }
1564 };
1565
1566 /* Composes and returns a string representing the OpenFlow packet of 'len'
1567  * bytes at 'oh' at the given 'verbosity' level.  0 is a minimal amount of
1568  * verbosity and higher numbers increase verbosity.  The caller is responsible
1569  * for freeing the string. */
1570 char *
1571 ofp_to_string(const void *oh_, size_t len, int verbosity)
1572 {
1573     struct ds string = DS_EMPTY_INITIALIZER;
1574     const struct ofp_header *oh = oh_;
1575     const struct openflow_packet *pkt;
1576
1577     if (len < sizeof(struct ofp_header)) {
1578         ds_put_cstr(&string, "OpenFlow packet too short:\n");
1579         ds_put_hex_dump(&string, oh, len, 0, true);
1580         return ds_cstr(&string);
1581     } else if (oh->version != OFP_VERSION) {
1582         ds_put_format(&string, "Bad OpenFlow version %"PRIu8":\n", oh->version);
1583         ds_put_hex_dump(&string, oh, len, 0, true);
1584         return ds_cstr(&string);
1585     }
1586
1587     for (pkt = packets; ; pkt++) {
1588         if (pkt >= &packets[ARRAY_SIZE(packets)]) {
1589             ds_put_format(&string, "Unknown OpenFlow packet type %"PRIu8":\n",
1590                           oh->type);
1591             ds_put_hex_dump(&string, oh, len, 0, true);
1592             return ds_cstr(&string);
1593         } else if (oh->type == pkt->type) {
1594             break;
1595         }
1596     }
1597
1598     ds_put_format(&string, "%s (xid=0x%"PRIx32"):", pkt->name, ntohl(oh->xid));
1599
1600     if (ntohs(oh->length) > len)
1601         ds_put_format(&string, " (***truncated to %zu bytes from %"PRIu16"***)",
1602                 len, ntohs(oh->length));
1603     else if (ntohs(oh->length) < len) {
1604         ds_put_format(&string, " (***only uses %"PRIu16" bytes out of %zu***)\n",
1605                 ntohs(oh->length), len);
1606         len = ntohs(oh->length);
1607     }
1608
1609     if (len < pkt->min_size) {
1610         ds_put_format(&string, " (***length=%zu < min_size=%zu***)\n",
1611                 len, pkt->min_size);
1612     } else if (!pkt->printer) {
1613         if (len > sizeof *oh) {
1614             ds_put_format(&string, " length=%"PRIu16" (decoder not implemented)\n",
1615                           ntohs(oh->length));
1616         }
1617     } else {
1618         pkt->printer(&string, oh, len, verbosity);
1619     }
1620     if (verbosity >= 3) {
1621         ds_put_hex_dump(&string, oh, len, 0, true);
1622     }
1623     if (string.string[string.length - 1] != '\n') {
1624         ds_put_char(&string, '\n');
1625     }
1626     return ds_cstr(&string);
1627 }
1628
1629 /* Returns the name for the specified OpenFlow message type as a string,
1630  * e.g. "OFPT_FEATURES_REPLY".  If no name is known, the string returned is a
1631  * hex number, e.g. "0x55".
1632  *
1633  * The caller must free the returned string when it is no longer needed. */
1634 char *
1635 ofp_message_type_to_string(uint8_t type)
1636 {
1637     struct ds s = DS_EMPTY_INITIALIZER;
1638     const struct openflow_packet *pkt;
1639     for (pkt = packets; ; pkt++) {
1640         if (pkt >= &packets[ARRAY_SIZE(packets)]) {
1641             ds_put_format(&s, "0x%02"PRIx8, type);
1642             break;
1643         } else if (type == pkt->type) {
1644             const char *p;
1645
1646             ds_put_cstr(&s, "OFPT_");
1647             for (p = pkt->name; *p; p++) {
1648                 ds_put_char(&s, toupper((unsigned char) *p));
1649             }
1650             break;
1651         }
1652     }
1653     return ds_cstr(&s);
1654 }
1655 \f
1656 static void
1657 print_and_free(FILE *stream, char *string)
1658 {
1659     fputs(string, stream);
1660     free(string);
1661 }
1662
1663 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
1664  * given 'verbosity' level.  0 is a minimal amount of verbosity and higher
1665  * numbers increase verbosity. */
1666 void
1667 ofp_print(FILE *stream, const void *oh, size_t len, int verbosity)
1668 {
1669     print_and_free(stream, ofp_to_string(oh, len, verbosity));
1670 }
1671
1672 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
1673  * 'data' to 'stream' using tcpdump.  'total_len' specifies the full length of
1674  * the Ethernet frame (of which 'len' bytes were captured).
1675  *
1676  * This starts and kills a tcpdump subprocess so it's quite expensive. */
1677 void
1678 ofp_print_packet(FILE *stream, const void *data, size_t len, size_t total_len)
1679 {
1680     print_and_free(stream, ofp_packet_to_string(data, len, total_len));
1681 }