Esempio n. 1
0
void skill_editor_menu(Client *conn)
{
    clear_screen(conn);
    set_cursor(conn, 1, 1);
    conn->title(conn, "Skill Editor");
    Skill *skill = (Skill *) conn->editing->data;
    xwritelnf(conn, "   ~CId: ~W%d", skill->id);
    xwritelnf(conn, "~YA) ~CName: ~W%s~x", skill->name);
    xwritelnf(conn, "~YB) ~CDamage: ~W%s~x", skill->damage);
    xwritelnf(conn, "~YC) ~CMsgOff: ~W%s~x", skill->msgOff);
    xwritelnf(conn, "~YD) ~CMsgObj: ~W%s~x", skill->msgObj);
    xwritelnf(conn, "~YE) ~CWait: ~W%d~x", skill->wait);
    xwritelnf(conn, "~YF) ~CMana: ~W%d~x", skill->mana);
    xwritelnf(conn, "~YG) ~CCost: ~W%.2f~x", skill->cost);
    const char *spfun = spellfun_name(skill->spellfun);
    xwritelnf(conn, "~YH) ~CSpell: ~W%s~x", spfun ? spfun : "None");
    const char *gsname = gsn_name(skill->pgsn);
    xwritelnf(conn, "~YI) ~CGSN: ~W%s~x", gsname ? gsname : "None");
    xwritelnf(conn, "~YJ) ~CMinPos: ~W%s~x",
              position_table[skill->minPos].name);
    xwritelnf(conn, "~YK) ~CFlags: ~W%s~x",

              format_flags(&skill->flags, skill_flags));
    xwrite(conn, "~YL) ~CLevels: ~W");

    for (int i = 0; i < max_class; i++)
    {
        xwritef(conn, "%s [%d] ", class_table[i].name, skill->levels[i]);
    }
    xwriteln(conn, "");

}
Esempio n. 2
0
static void
test_pcap(struct ovs_cmdl_context *ctx)
{
    size_t total_count, batch_size_;
    struct pcap_file *pcap;
    int err = 0;

    pcap = ovs_pcap_open(ctx->argv[1], "rb");
    if (!pcap) {
        return;
    }

    batch_size_ = 1;
    if (ctx->argc > 2) {
        batch_size_ = strtoul(ctx->argv[2], NULL, 0);
        if (batch_size_ == 0 || batch_size_ > NETDEV_MAX_BURST) {
            ovs_fatal(0,
                      "batch_size must be between 1 and NETDEV_MAX_BURST(%u)",
                      NETDEV_MAX_BURST);
        }
    }

    fatal_signal_init();

    ct = conntrack_init();
    total_count = 0;
    for (;;) {
        struct dp_packet *packet;
        struct dp_packet_batch pkt_batch_;
        struct dp_packet_batch *batch = &pkt_batch_;

        dp_packet_batch_init(batch);
        for (int i = 0; i < batch_size_; i++) {
            err = ovs_pcap_read(pcap, &packet, NULL);
            if (err) {
                break;
            }
            dp_packet_batch_add(batch, packet);
        }
        if (dp_packet_batch_is_empty(batch)) {
            break;
        }
        pcap_batch_execute_conntrack(ct, batch);

        DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
            struct ds ds = DS_EMPTY_INITIALIZER;

            total_count++;

            format_flags(&ds, ct_state_to_string, packet->md.ct_state, '|');
            printf("%"PRIuSIZE": %s\n", total_count, ds_cstr(&ds));

            ds_destroy(&ds);
        }

        dp_packet_delete_batch(batch, true);
    }
    conntrack_destroy(ct);
    ovs_pcap_close(pcap);
}
Esempio n. 3
0
static void
format_flow_tunnel(struct ds *s, const struct match *match)
{
    const struct flow_wildcards *wc = &match->wc;
    const struct flow_tnl *tnl = &match->flow.tunnel;

    switch (wc->masks.tunnel.tun_id) {
    case 0:
        break;
    case CONSTANT_HTONLL(UINT64_MAX):
        ds_put_format(s, "tun_id=%#"PRIx64",", ntohll(tnl->tun_id));
        break;
    default:
        ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",",
                      ntohll(tnl->tun_id),
                      ntohll(wc->masks.tunnel.tun_id));
        break;
    }
    format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src);
    format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst);

    if (wc->masks.tunnel.ip_tos) {
        ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
    }
    if (wc->masks.tunnel.ip_ttl) {
        ds_put_format(s, "tun_ttl=%"PRIu8",", tnl->ip_ttl);
    }
    if (wc->masks.tunnel.flags) {
        format_flags(s, flow_tun_flag_to_string, tnl->flags, '|');
        ds_put_char(s, ',');
    }
}
Esempio n. 4
0
void area_editor_menu(Client *conn)
{
    clear_screen(conn);
    set_cursor(conn, 1, 1);
    Area *area = (Area *) conn->editing->data;
    conn->titlef(conn, "Area Editor - Area %d", area->id);
    xwritelnf(conn, "~C   Id: ~W%d~x", area->id);
    xwritelnf(conn, "~YA) ~CName: ~W%s~x", area->name);
    xwritelnf(conn, "~YB) ~CFlags: ~W%s~x",

              format_flags(area->flags, area_flags));

}
Esempio n. 5
0
void exit_editor_menu(Client *conn)
{
    clear_screen(conn);
    set_cursor(conn, 1, 1);
    Exit *exit = (Exit *) conn->editing->data;
    conn->titlef(conn, "Exit Editor - Room %d", exit->fromRoom->id);
    xwritelnf(conn, "   ~CId: ~W%d~x", exit->id);
    xwritelnf(conn, "~YA) ~CToRoom: ~W%d~x",
              exit->to.room == 0 ? 0 : exit->to.room->id);
    xwritelnf(conn, "~YB) ~CFlags: ~W%d~x",

              format_flags(exit->flags, exit_flags));

}
Esempio n. 6
0
static void
format_flow_tunnel(struct ds *s, const struct match *match)
{
    const struct flow_wildcards *wc = &match->wc;
    const struct flow_tnl *tnl = &match->flow.tunnel;

    format_be64_masked(s, "tun_id", tnl->tun_id, wc->masks.tunnel.tun_id);
    format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src);
    format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst);

    if (wc->masks.tunnel.ip_tos) {
        ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
    }
    if (wc->masks.tunnel.ip_ttl) {
        ds_put_format(s, "tun_ttl=%"PRIu8",", tnl->ip_ttl);
    }
    if (wc->masks.tunnel.flags) {
        format_flags(s, flow_tun_flag_to_string, tnl->flags, '|');
        ds_put_char(s, ',');
    }
}
Esempio n. 7
0
std::string lavf_get_stream_description(AVStream *pStream)
{
  AVCodecContext *enc = pStream->codec;

  std::string codec_name = get_codec_name(enc);

  const char *lang = get_stream_language(pStream);
  std::string sLanguage;

  if(lang) {
    sLanguage = ProbeLangForLanguage(lang);
    if (sLanguage.empty()) {
      sLanguage = lang;
    }
  }

  char *title = nullptr;
  if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "title", nullptr, 0)) {
    title = dictEntry->value;
  } else if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "handler_name", nullptr, 0)) {
    title = dictEntry->value;
    if (strcmp(title, "GPAC ISO Video Handler") == 0 || strcmp(title, "VideoHandler") == 0|| strcmp(title, "GPAC ISO Audio Handler") == 0 || strcmp(title, "GPAC Streaming Text Handler") == 0)
      title = nullptr;
  }

  // Empty titles are rather useless
  if (title && strlen(title) == 0)
    title = nullptr;

  int bitrate = get_bit_rate(enc);

  std::ostringstream buf;
  switch(enc->codec_type) {
  case AVMEDIA_TYPE_VIDEO:
    buf << "V: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Pixel Format
    if (enc->pix_fmt != AV_PIX_FMT_NONE) {
      buf << ", " << av_get_pix_fmt_name(enc->pix_fmt);
    }
    // Dimensions
    if (enc->width) {
      buf << ", " << enc->width << "x" << enc->height;
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_AUDIO:
    buf << "A: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Sample Rate
    if (enc->sample_rate) {
      buf << ", " << enc->sample_rate << " Hz";
    }
    if (enc->channels) {
      // Get channel layout
      char channel[32];
      av_get_channel_layout_string(channel, 32, enc->channels, enc->channel_layout);
      buf << ", " << channel;
    }
    // Sample Format
    if (show_sample_fmt(enc->codec_id) && get_bits_per_sample(enc, true)) {
      if (enc->sample_fmt == AV_SAMPLE_FMT_FLT || enc->sample_fmt == AV_SAMPLE_FMT_DBL) {
        buf << ", fp";
      } else {
        buf << ", s";
      }
      buf << get_bits_per_sample(enc, true);
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    // Flags
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_SUBTITLE:
    buf << "S: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    if (title || lang) {
      buf << ")";
    }
    // Subtitle flags
    buf << format_flags(pStream->disposition);
    break;
  default:
    buf << "Unknown: Stream #" << pStream->index;
    break;
  }

  return buf.str();
}
Esempio n. 8
0
std::string lavf_get_stream_description(const AVStream *pStream)
{
  AVCodecParameters *par = pStream->codecpar;

  std::string codec_name = get_codec_name(par);

  const char *lang = get_stream_language(pStream);
  std::string sLanguage;

  if(lang) {
    sLanguage = ProbeLangForLanguage(lang);
    if (sLanguage.empty()) {
      sLanguage = lang;
    }
  }

  const char * title = lavf_get_stream_title(pStream);

  // Empty titles are rather useless
  if (title && strlen(title) == 0)
    title = nullptr;

  int64_t bitrate = get_bit_rate(par);

  std::ostringstream buf;
  switch(par->codec_type) {
  case AVMEDIA_TYPE_VIDEO:
    buf << "V: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Pixel Format
    if (const char *pix_fmt = av_get_pix_fmt_name((AVPixelFormat)par->format)) {
      buf << ", " << pix_fmt;
    }
    // Dimensions
    if (par->width) {
      buf << ", " << par->width << "x" << par->height;
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    if (par->codec_id == AV_CODEC_ID_H264 && par->profile == FF_PROFILE_H264_STEREO_HIGH) {
      AVDictionaryEntry *entry = av_dict_get(pStream->metadata, "stereo_mode", nullptr, 0);
      if (entry && strcmp(entry->value, "mvc_lr") == 0)
        buf << ", lr";
      else if (entry && strcmp(entry->value, "mvc_rl") == 0)
        buf << ", rl";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_AUDIO:
    buf << "A: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Sample Rate
    if (par->sample_rate) {
      buf << ", " << par->sample_rate << " Hz";
    }
    if (par->channels) {
      // Get channel layout
      char channel[32];
      av_get_channel_layout_string(channel, 32, par->channels, par->channel_layout);
      buf << ", " << channel;
    }
    // Sample Format
    if (show_sample_fmt(par) && get_bits_per_sample(par, true)) {
      if (par->format == AV_SAMPLE_FMT_FLT || par->format == AV_SAMPLE_FMT_DBL) {
        buf << ", fp";
      } else {
        buf << ", s";
      }
      buf << get_bits_per_sample(par, true);
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    // Flags
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_SUBTITLE:
    buf << "S: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    if (title || lang) {
      buf << ")";
    }
    // Subtitle flags
    buf << format_flags(pStream->disposition);
    break;
  default:
    buf << "Unknown: Stream #" << pStream->index;
    break;
  }

  return buf.str();
}
Esempio n. 9
0
File: match.c Progetto: antypop/ovs
/* Appends a string representation of 'match' to 's'.  If 'priority' is
 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
void
match_format(const struct match *match, struct ds *s, unsigned int priority)
{
    const struct flow_wildcards *wc = &match->wc;
    size_t start_len = s->length;
    const struct flow *f = &match->flow;
    bool skip_type = false;
    bool skip_proto = false;

    int i;

    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);

    if (priority != OFP_DEFAULT_PRIORITY) {
        ds_put_format(s, "priority=%u,", priority);
    }

    format_uint32_masked(s, "pkt_mark", f->pkt_mark, wc->masks.pkt_mark);

    if (wc->masks.recirc_id) {
        format_uint32_masked(s, "recirc_id", f->recirc_id,
                             wc->masks.recirc_id);
    }

    if (f->dp_hash && wc->masks.dp_hash) {
        format_uint32_masked(s, "dp_hash", f->dp_hash,
                             wc->masks.dp_hash);
    }

    if (wc->masks.skb_priority) {
        ds_put_format(s, "skb_priority=%#"PRIx32",", f->skb_priority);
    }

    if (wc->masks.dl_type) {
        skip_type = true;
        if (f->dl_type == htons(ETH_TYPE_IP)) {
            if (wc->masks.nw_proto) {
                skip_proto = true;
                if (f->nw_proto == IPPROTO_ICMP) {
                    ds_put_cstr(s, "icmp,");
                } else if (f->nw_proto == IPPROTO_IGMP) {
                    ds_put_cstr(s, "igmp,");
                } else if (f->nw_proto == IPPROTO_TCP) {
                    ds_put_cstr(s, "tcp,");
                } else if (f->nw_proto == IPPROTO_UDP) {
                    ds_put_cstr(s, "udp,");
                } else if (f->nw_proto == IPPROTO_SCTP) {
                    ds_put_cstr(s, "sctp,");
                } else {
                    ds_put_cstr(s, "ip,");
                    skip_proto = false;
                }
            } else {
                ds_put_cstr(s, "ip,");
            }
        } else if (f->dl_type == htons(ETH_TYPE_IPV6)) {
            if (wc->masks.nw_proto) {
                skip_proto = true;
                if (f->nw_proto == IPPROTO_ICMPV6) {
                    ds_put_cstr(s, "icmp6,");
                } else if (f->nw_proto == IPPROTO_TCP) {
                    ds_put_cstr(s, "tcp6,");
                } else if (f->nw_proto == IPPROTO_UDP) {
                    ds_put_cstr(s, "udp6,");
                } else if (f->nw_proto == IPPROTO_SCTP) {
                    ds_put_cstr(s, "sctp6,");
                } else {
                    ds_put_cstr(s, "ipv6,");
                    skip_proto = false;
                }
            } else {
                ds_put_cstr(s, "ipv6,");
            }
        } else if (f->dl_type == htons(ETH_TYPE_ARP)) {
            ds_put_cstr(s, "arp,");
        } else if (f->dl_type == htons(ETH_TYPE_RARP)) {
            ds_put_cstr(s, "rarp,");
        } else if (f->dl_type == htons(ETH_TYPE_MPLS)) {
            ds_put_cstr(s, "mpls,");
        } else if (f->dl_type == htons(ETH_TYPE_MPLS_MCAST)) {
            ds_put_cstr(s, "mplsm,");
        } else {
            skip_type = false;
        }
    }
    for (i = 0; i < FLOW_N_REGS; i++) {
        #define REGNAME_LEN 20
        char regname[REGNAME_LEN];
        if (snprintf(regname, REGNAME_LEN, "reg%d", i) >= REGNAME_LEN) {
            strcpy(regname, "reg?");
        }
        format_uint32_masked(s, regname, f->regs[i], wc->masks.regs[i]);
    }

    format_flow_tunnel(s, match);

    format_be64_masked(s, "metadata", f->metadata, wc->masks.metadata);

    if (wc->masks.in_port.ofp_port) {
        ds_put_cstr(s, "in_port=");
        ofputil_format_port(f->in_port.ofp_port, s);
        ds_put_char(s, ',');
    }
    if (wc->masks.vlan_tci) {
        ovs_be16 vid_mask = wc->masks.vlan_tci & htons(VLAN_VID_MASK);
        ovs_be16 pcp_mask = wc->masks.vlan_tci & htons(VLAN_PCP_MASK);
        ovs_be16 cfi = wc->masks.vlan_tci & htons(VLAN_CFI);

        if (cfi && f->vlan_tci & htons(VLAN_CFI)
            && (!vid_mask || vid_mask == htons(VLAN_VID_MASK))
            && (!pcp_mask || pcp_mask == htons(VLAN_PCP_MASK))
            && (vid_mask || pcp_mask)) {
            if (vid_mask) {
                ds_put_format(s, "dl_vlan=%"PRIu16",",
                              vlan_tci_to_vid(f->vlan_tci));
            }
            if (pcp_mask) {
                ds_put_format(s, "dl_vlan_pcp=%d,",
                              vlan_tci_to_pcp(f->vlan_tci));
            }
        } else if (wc->masks.vlan_tci == htons(0xffff)) {
            ds_put_format(s, "vlan_tci=0x%04"PRIx16",", ntohs(f->vlan_tci));
        } else {
            ds_put_format(s, "vlan_tci=0x%04"PRIx16"/0x%04"PRIx16",",
                          ntohs(f->vlan_tci), ntohs(wc->masks.vlan_tci));
        }
    }
    format_eth_masked(s, "dl_src", f->dl_src, wc->masks.dl_src);
    format_eth_masked(s, "dl_dst", f->dl_dst, wc->masks.dl_dst);
    if (!skip_type && wc->masks.dl_type) {
        ds_put_format(s, "dl_type=0x%04"PRIx16",", ntohs(f->dl_type));
    }
    if (f->dl_type == htons(ETH_TYPE_IPV6)) {
        format_ipv6_netmask(s, "ipv6_src", &f->ipv6_src, &wc->masks.ipv6_src);
        format_ipv6_netmask(s, "ipv6_dst", &f->ipv6_dst, &wc->masks.ipv6_dst);
        if (wc->masks.ipv6_label) {
            if (wc->masks.ipv6_label == OVS_BE32_MAX) {
                ds_put_format(s, "ipv6_label=0x%05"PRIx32",",
                              ntohl(f->ipv6_label));
            } else {
                ds_put_format(s, "ipv6_label=0x%05"PRIx32"/0x%05"PRIx32",",
                              ntohl(f->ipv6_label),
                              ntohl(wc->masks.ipv6_label));
            }
        }
    } else if (f->dl_type == htons(ETH_TYPE_ARP) ||
               f->dl_type == htons(ETH_TYPE_RARP)) {
        format_ip_netmask(s, "arp_spa", f->nw_src, wc->masks.nw_src);
        format_ip_netmask(s, "arp_tpa", f->nw_dst, wc->masks.nw_dst);
    } else {
        format_ip_netmask(s, "nw_src", f->nw_src, wc->masks.nw_src);
        format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst);
    }
    if (!skip_proto && wc->masks.nw_proto) {
        if (f->dl_type == htons(ETH_TYPE_ARP) ||
            f->dl_type == htons(ETH_TYPE_RARP)) {
            ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto);
        } else {
            ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
        }
    }
    if (f->dl_type == htons(ETH_TYPE_ARP) ||
        f->dl_type == htons(ETH_TYPE_RARP)) {
        format_eth_masked(s, "arp_sha", f->arp_sha, wc->masks.arp_sha);
        format_eth_masked(s, "arp_tha", f->arp_tha, wc->masks.arp_tha);
    }
    if (wc->masks.nw_tos & IP_DSCP_MASK) {
        ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos & IP_DSCP_MASK);
    }
    if (wc->masks.nw_tos & IP_ECN_MASK) {
        ds_put_format(s, "nw_ecn=%"PRIu8",", f->nw_tos & IP_ECN_MASK);
    }
    if (wc->masks.nw_ttl) {
        ds_put_format(s, "nw_ttl=%"PRIu8",", f->nw_ttl);
    }
    if (wc->masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK)) {
        ds_put_format(s, "mpls_label=%"PRIu32",",
                 mpls_lse_to_label(f->mpls_lse[0]));
    }
    if (wc->masks.mpls_lse[0] & htonl(MPLS_TC_MASK)) {
        ds_put_format(s, "mpls_tc=%"PRIu8",",
                 mpls_lse_to_tc(f->mpls_lse[0]));
    }
    if (wc->masks.mpls_lse[0] & htonl(MPLS_TTL_MASK)) {
        ds_put_format(s, "mpls_ttl=%"PRIu8",",
                 mpls_lse_to_ttl(f->mpls_lse[0]));
    }
    if (wc->masks.mpls_lse[0] & htonl(MPLS_BOS_MASK)) {
        ds_put_format(s, "mpls_bos=%"PRIu8",",
                 mpls_lse_to_bos(f->mpls_lse[0]));
    }
    format_be32_masked(s, "mpls_lse1", f->mpls_lse[1], wc->masks.mpls_lse[1]);
    format_be32_masked(s, "mpls_lse2", f->mpls_lse[2], wc->masks.mpls_lse[2]);

    switch (wc->masks.nw_frag) {
    case FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_ANY
                      ? (f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "first")
                      : (f->nw_frag & FLOW_NW_FRAG_LATER ? "<error>" : "no"));
        break;

    case FLOW_NW_FRAG_ANY:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_ANY ? "yes" : "no");
        break;

    case FLOW_NW_FRAG_LATER:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "not_later");
        break;
    }
    if (f->dl_type == htons(ETH_TYPE_IP) &&
        f->nw_proto == IPPROTO_ICMP) {
        format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
    } else if (f->dl_type == htons(ETH_TYPE_IP) &&
               f->nw_proto == IPPROTO_IGMP) {
        format_be16_masked(s, "igmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "igmp_code", f->tp_dst, wc->masks.tp_dst);
    } else if (f->dl_type == htons(ETH_TYPE_IPV6) &&
               f->nw_proto == IPPROTO_ICMPV6) {
        format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
        format_ipv6_netmask(s, "nd_target", &f->nd_target,
                            &wc->masks.nd_target);
        format_eth_masked(s, "nd_sll", f->arp_sha, wc->masks.arp_sha);
        format_eth_masked(s, "nd_tll", f->arp_tha, wc->masks.arp_tha);
    } else {
        format_be16_masked(s, "tp_src", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "tp_dst", f->tp_dst, wc->masks.tp_dst);
    }
    if (is_ip_any(f) && f->nw_proto == IPPROTO_TCP && wc->masks.tcp_flags) {
        uint16_t mask = TCP_FLAGS(wc->masks.tcp_flags);

        if (mask == TCP_FLAGS(OVS_BE16_MAX)) {
            ds_put_cstr(s, "tcp_flags=");
            if (f->tcp_flags) {
                format_flags(s, packet_tcp_flag_to_string, ntohs(f->tcp_flags),
                             '|');
            } else {
                ds_put_cstr(s, "0"); /* Zero flags. */
            }
        } else if (mask) {
            format_flags_masked(s, "tcp_flags", packet_tcp_flag_to_string,
                                ntohs(f->tcp_flags), mask);
        }
    }

    if (s->length > start_len && ds_last(s) == ',') {
        s->length--;
    }
}