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