Text   |  XML   |  ReML   |   Visible Warnings:

Format String  at packet-dns.c:2285

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

dissect_dns_answer

(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-dns.c)expand/collapse
Show more  
 1094  dissect_dns_answer(tvbuff_t *tvb, int offsetx, int dns_data_offset,
 1095    column_info *cinfo, proto_tree *dns_tree, packet_info *pinfo,
 1096    gboolean is_mdns)
 1097  {
 1098    int len;
 1099    const guchar *name;
 1100    gchar *name_out;
 1101    int name_len;
 1102    int type;
 1103    int class;
 1104    int flush;
 1105    const char *class_name;
 1106    const char *type_name;
 1107    int data_offset;
 1108    int cur_offset;
 1109    int data_start;
 1110    guint ttl;
 1111    gushort data_len;
 1112    proto_tree *rr_tree = NULL;
 1113    proto_item *trr = NULL;
 1114   
 1115    data_start = data_offset = offsetx;
 1116    cur_offset = offsetx;
 1117   
 1118    len = get_dns_name_type_class(tvb, offsetx, dns_data_offset, &name, &name_len,
 1119      &type, &class);
 1120    data_offset += len;
 1121    cur_offset += len;
 1122    if (is_mdns) {
 1123      /* Split the FLUSH flag and the class */
 1124      flush = class & C_FLUSH;
 1125      class &= ~C_FLUSH;
 1126    } else 
 1127      flush = 0;
 1128   
 1129    type_name = dns_type_name(type);
 1130    class_name = dns_class_name(class);
 1131   
 1132    ttl = tvb_get_ntohl(tvb, data_offset);
 1133    data_offset += 4;
 1134    cur_offset += 4;
 1135   
 1136    data_len = tvb_get_ntohs(tvb, data_offset);
 1137    data_offset += 2;
 1138    cur_offset += 2;
 1139   
 1140    if (cinfo != NULL) {
 1141      col_append_fstr(cinfo, COL_INFO, " %s", type_name);
 1142      if (is_mdns && flush)
 1143        col_append_str(cinfo, COL_INFO, ", cache flush");
 1144    }
 1145    if (dns_tree != NULL) {
 1146      /*
 1147       * The name might contain octets that aren't printable characters,
 1148       * format it for display.
 1149       */
 1150      name_out = format_text(name, strlen(name));
 1151      if (type != T_OPT) {
 1152        trr = proto_tree_add_text(dns_tree, tvb, offsetx,
 1153                      (data_offset - data_start) + data_len,
 1154                      "%s: type %s, class %s",
 1155                      name_out, type_name, class_name);
 1156        rr_tree = add_rr_to_tree(trr, ett_dns_rr, tvb, offsetx, name, name_len,
 1157                       type, class, flush, ttl, data_len, is_mdns);
 1158      } else  {
 1159        trr = proto_tree_add_text(dns_tree, tvb, offsetx,
 1160                      (data_offset - data_start) + data_len,
 1161                      "%s: type %s", name_out, type_name);
 1162        rr_tree = add_opt_rr_to_tree(trr, ett_dns_rr, tvb, offsetx, name, name_len,
 1163                       type, class, flush, ttl, data_len, is_mdns);
 1164      }
 1165      if (is_mdns && flush)
 1166        proto_item_append_text(trr, ", cache flush");
 1167    }
 1168   
 1169    if (data_len == 0)
 1170      return data_offset - data_start;
 1171   
 1172    switch (type) {
 1173   
 1174    case T_A:
 1175      {
 1176        const guint8 *addr;
 1177        guint32 addr_int;
 1178   
 1179        addr = tvb_get_ptr(tvb, cur_offset, 4);
 1180        if (cinfo != NULL)
 1181          col_append_fstr(cinfo, COL_INFO, " %s", ip_to_str(addr));
 1182        if (dns_tree != NULL) {
 1183          proto_item_append_text(trr, ", addr %s", ip_to_str(addr));
 1184          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Addr: %s",
 1185                       ip_to_str(addr));
 1186        }
 1187        if ((class & 0x7f) == C_IN) {
 1188          memcpy(&addr_int, addr, sizeof(addr_int));
 1189          add_ipv4_name(addr_int, name);
 1190        }
 1191      }
 1192      break;
 1193   
 1194    case T_NS:
 1195      {
 1196        const guchar *ns_name;
 1197        int ns_name_len;
 1198   
 1199        /* XXX Fix data length */
 1200        ns_name_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &ns_name);
 1201        name_out = format_text(ns_name, strlen(ns_name));
 1202        if (cinfo != NULL)
 1203          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1204        if (dns_tree != NULL) {
 1205          proto_item_append_text(trr, ", ns %s", name_out);
 1206          proto_tree_add_text(rr_tree, tvb, cur_offset, ns_name_len, "Name server: %s",
 1207                          name_out);
 1208        }
 1209      }
 1210      break;
 1211   
 1212    case T_CNAME:
 1213      {
 1214        const guchar *cname;
 1215        int cname_len;
 1216   
 1217        /* XXX Fix data length */
 1218        cname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &cname);
 1219        name_out = format_text(cname, strlen(cname));
 1220        if (cinfo != NULL)
 1221          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1222        if (dns_tree != NULL) {
 1223          proto_item_append_text(trr, ", cname %s", name_out);
 1224          proto_tree_add_text(rr_tree, tvb, cur_offset, cname_len, "Primary name: %s",
 1225                          name_out);
 1226        }
 1227      }
 1228      break;
 1229   
 1230    case T_SOA:
 1231      {
 1232        const guchar *mname;
 1233        int mname_len;
 1234        const guchar *rname;
 1235        int rname_len;
 1236        guint32 serial;
 1237        guint32 refresh;
 1238        guint32 retry;
 1239        guint32 expire;
 1240        guint32 minimum;
 1241   
 1242        /* XXX Fix data length */
 1243        mname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &mname);
 1244        name_out = format_text(mname, strlen(mname));
 1245        if (cinfo != NULL)
 1246          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1247        if (dns_tree != NULL) {
 1248          proto_item_append_text(trr, ", mname %s", name_out);
 1249          proto_tree_add_text(rr_tree, tvb, cur_offset, mname_len, "Primary name server: %s",
 1250                         name_out);
 1251          cur_offset += mname_len;
 1252   
 1253          /* XXX Fix data length */
 1254          rname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &rname);
 1255          name_out = format_text(rname, strlen(rname));
 1256          proto_tree_add_text(rr_tree, tvb, cur_offset, rname_len, "Responsible authority's mailbox: %s",
 1257                         name_out);
 1258          cur_offset += rname_len;
 1259   
 1260          serial = tvb_get_ntohl(tvb, cur_offset);
 1261          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Serial number: %u",
 1262                         serial);
 1263          cur_offset += 4;
 1264   
 1265          refresh = tvb_get_ntohl(tvb, cur_offset);
 1266          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Refresh interval: %s",
 1267                         time_secs_to_str(refresh));
 1268          cur_offset += 4;
 1269   
 1270          retry = tvb_get_ntohl(tvb, cur_offset);
 1271          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Retry interval: %s",
 1272                         time_secs_to_str(retry));
 1273          cur_offset += 4;
 1274   
 1275          expire = tvb_get_ntohl(tvb, cur_offset);
 1276          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Expiration limit: %s",
 1277                         time_secs_to_str(expire));
 1278          cur_offset += 4;
 1279   
 1280          minimum = tvb_get_ntohl(tvb, cur_offset);
 1281          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Minimum TTL: %s",
 1282                         time_secs_to_str(minimum));
 1283        }
 1284      }
 1285      break;
 1286   
 1287    case T_PTR:
 1288      {
 1289        const guchar *pname;
 1290        int pname_len;
 1291   
 1292        /* XXX Fix data length */
 1293        pname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &pname);
 1294        name_out = format_text(pname, strlen(pname));
 1295        if (cinfo != NULL)
 1296          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1297        if (dns_tree != NULL) {
 1298          proto_item_append_text(trr, ", %s", name_out);
 1299          proto_tree_add_text(rr_tree, tvb, cur_offset, pname_len, "Domain name: %s",
 1300                          name_out);
 1301        }
 1302      }
 1303      break;
 1304   
 1305    case T_WKS:
 1306      {
 1307        int rr_len = data_len;
 1308        const guint8 *wks_addr;
 1309        guint8 protocol;
 1310        guint8 bits;
 1311        int mask;
 1312        int port_num;
 1313        int i;
 1314        emem_strbuf_t *bitnames = ep_strbuf_new_label(NULL);
 1315   
 1316        if (rr_len < 4) {
 1317          if (dns_tree != NULL)
 1318            goto bad_rr;
 1319          break;
 1320        }
 1321        wks_addr = tvb_get_ptr(tvb, cur_offset, 4);
 1322        if (cinfo != NULL)
 1323          col_append_fstr(cinfo, COL_INFO, " %s", ip_to_str(wks_addr));
 1324        if (dns_tree != NULL) {
 1325          proto_item_append_text(trr, ", addr %s", ip_to_str(wks_addr));
 1326          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Addr: %s",
 1327                       ip_to_str(wks_addr));
 1328          cur_offset += 4;
 1329          rr_len -= 4;
 1330   
 1331          if (rr_len < 1)
 1332            goto bad_rr;
 1333          protocol = tvb_get_guint8(tvb, cur_offset);
 1334          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Protocol: %s",
 1335                       ipprotostr(protocol));
 1336          cur_offset += 1;
 1337          rr_len -= 1;
 1338   
 1339          port_num = 0;
 1340          while (rr_len != 0) {
 1341            bits = tvb_get_guint8(tvb, cur_offset);
 1342            if (bits != 0) {
 1343              mask = 1<<7;
 1344              ep_strbuf_truncate(bitnames, 0);
 1345              for (i = 0; i < 8; i++) {
 1346                if (bits & mask) {
 1347                  if (bitnames->len > 0) {
 1348                    ep_strbuf_append(bitnames, ", ");
 1349                  }
 1350                  switch (protocol) {
 1351   
 1352                  case IP_PROTO_TCP:
 1353                    ep_strbuf_append(bitnames, get_tcp_port(port_num));
 1354                    break;
 1355   
 1356                  case IP_PROTO_UDP:
 1357                    ep_strbuf_append(bitnames, get_udp_port(port_num));
 1358                    break;
 1359   
 1360                  default:
 1361                    ep_strbuf_append_printf(bitnames, "%u", port_num);
 1362                    break;
 1363                  }
 1364                }
 1365                mask >>= 1;
 1366                port_num++;
 1367              }
 1368              proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
 1369                  "Bits: 0x%02x (%s)", bits, bitnames->str);
 1370            } else 
 1371              port_num += 8;
 1372            cur_offset += 1;
 1373            rr_len -= 1;
 1374          }
 1375        }
 1376      }
 1377      break;
 1378   
 1379    case T_HINFO:
 1380      {
 1381        int cpu_offset;
 1382        int cpu_len;
 1383        const guint8 *cpu;
 1384        int os_offset;
 1385        int os_len;
 1386        const guint8 *os;
 1387   
 1388        cpu_offset = cur_offset;
 1389        cpu_len = tvb_get_guint8(tvb, cpu_offset);
 1390        cpu = tvb_get_ptr(tvb, cpu_offset + 1, cpu_len);
 1391        os_offset = cpu_offset + 1 + cpu_len;
 1392        os_len = tvb_get_guint8(tvb, os_offset);
 1393        os = tvb_get_ptr(tvb, os_offset + 1, os_len);
 1394        if (cinfo != NULL)
 1395          col_append_fstr(cinfo, COL_INFO, " %.*s %.*s", cpu_len, cpu,
 1396              os_len, os);
 1397        if (dns_tree != NULL) {
 1398          proto_item_append_text(trr, ", CPU %.*s, OS %.*s",
 1399                       cpu_len, cpu, os_len, os);
 1400          proto_tree_add_text(rr_tree, tvb, cpu_offset, 1 + cpu_len, "CPU: %.*s",
 1401                          cpu_len, cpu);
 1402          proto_tree_add_text(rr_tree, tvb, os_offset, 1 + os_len, "OS: %.*s",
 1403                          os_len, os);
 1404        }
 1405      }
 1406      break;
 1407   
 1408    case T_MX:
 1409      {
 1410        guint16 preference = 0;
 1411        const guchar *mx_name;
 1412        int mx_name_len;
 1413   
 1414        preference = tvb_get_ntohs(tvb, cur_offset);
 1415        /* XXX Fix data length */
 1416        mx_name_len = get_dns_name(tvb, cur_offset + 2, 0, dns_data_offset, &mx_name);
 1417        name_out = format_text(mx_name, strlen(mx_name));
 1418        if (cinfo != NULL)
 1419          col_append_fstr(cinfo, COL_INFO, " %u %s", preference, name_out);
 1420        if (dns_tree != NULL) {
 1421          proto_item_append_text(trr, ", preference %u, mx %s",
 1422                         preference, name_out);
 1423          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Preference: %u", preference);
 1424          proto_tree_add_text(rr_tree, tvb, cur_offset + 2, mx_name_len, "Mail exchange: %s",
 1425                          name_out);
 1426        }
 1427      }
 1428      break;
 1429   
 1430    case T_TXT:
 1431      {
 1432        int rr_len = data_len;
 1433        int txt_offset;
 1434        int txt_len;
 1435   
 1436        if (dns_tree != NULL) {
 1437          txt_offset = cur_offset;
 1438          while (rr_len != 0) {
 1439            txt_len = tvb_get_guint8(tvb, txt_offset);
 1440            proto_tree_add_text(rr_tree, tvb, txt_offset, 1 + txt_len,
 1441             "Text: %.*s", txt_len, tvb_get_ptr(tvb, txt_offset + 1, txt_len));
 1442            txt_offset += 1 + txt_len;
 1443            rr_len -= 1 + txt_len;
 1444          }
 1445        }
 1446      }
 1447      break;
 1448   
 1449    case T_RRSIG:
 1450    case T_SIG:
 1451      {
 1452        int rr_len = data_len;
 1453        guint16 type_covered;
 1454        nstime_t nstime;
 1455        const guchar *signer_name;
 1456        int signer_name_len;
 1457   
 1458        if (dns_tree != NULL) {
 1459          if (rr_len < 2)
 1460            goto bad_rr;
 1461          type_covered = tvb_get_ntohs(tvb, cur_offset);
 1462          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Type covered: %s",
 1463                  dns_type_description(type_covered));
 1464          cur_offset += 2;
 1465          rr_len -= 2;
 1466   
 1467          if (rr_len < 1)
 1468            goto bad_rr;
 1469          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
 1470                  val_to_str(tvb_get_guint8(tvb, cur_offset), algo_vals,
 1471                      "Unknown (0x%02X)"));
 1472          cur_offset += 1;
 1473          rr_len -= 1;
 1474   
 1475          if (rr_len < 1)
 1476            goto bad_rr;
 1477          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Labels: %u",
 1478                  tvb_get_guint8(tvb, cur_offset));
 1479          cur_offset += 1;
 1480          rr_len -= 1;
 1481   
 1482          if (rr_len < 4)
 1483            goto bad_rr;
 1484          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Original TTL: %s",
 1485                  time_secs_to_str(tvb_get_ntohl(tvb, cur_offset)));
 1486          cur_offset += 4;
 1487          rr_len -= 4;
 1488   
 1489          if (rr_len < 4)
 1490            goto bad_rr;
 1491          nstime.secs = tvb_get_ntohl(tvb, cur_offset);
 1492          nstime.nsecs = 0;
 1493          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Signature expiration: %s",
 1494                  abs_time_to_str(&nstime));
 1495          cur_offset += 4;
 1496          rr_len -= 4;
 1497   
 1498          if (rr_len < 4)
 1499            goto bad_rr;
 1500          nstime.secs = tvb_get_ntohl(tvb, cur_offset);
 1501          nstime.nsecs = 0;
 1502          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Time signed: %s",
 1503                  abs_time_to_str(&nstime));
 1504          cur_offset += 4;
 1505          rr_len -= 4;
 1506   
 1507          if (rr_len < 2)
 1508            goto bad_rr;
 1509          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Id of signing key(footprint): %u",
 1510                  tvb_get_ntohs(tvb, cur_offset));
 1511          cur_offset += 2;
 1512          rr_len -= 2;
 1513   
 1514          /* XXX Fix data length */
 1515          signer_name_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &signer_name);
 1516          proto_tree_add_text(rr_tree, tvb, cur_offset, signer_name_len,
 1517                  "Signer's name: %s",
 1518                  format_text(signer_name, strlen(signer_name)));
 1519          cur_offset += signer_name_len;
 1520          rr_len -= signer_name_len;
 1521   
 1522          if (rr_len != 0)
 1523            proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Signature");
 1524        }
 1525      }
 1526      break;
 1527   
 1528    case T_DNSKEY:
 1529      {
 1530        int rr_len = data_len;
 1531        guint16 flags;
 1532        proto_item *tf;
 1533        proto_tree *flags_tree;
 1534        guint8 algo;
 1535        guint16 key_id;
 1536   
 1537        if (dns_tree != NULL) {
 1538          if (rr_len < 2)
 1539            goto bad_rr;
 1540          flags = tvb_get_ntohs(tvb, cur_offset);
 1541          tf = proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Flags: 0x%04X", flags);
 1542          flags_tree = proto_item_add_subtree(tf, ett_t_key_flags);
 1543          proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1544                  decode_boolean_bitfield(flags, 0x0100,
 1545                    2*8, "This is the zone key for the specified zone",
 1546                         "This is not a zone key"));
 1547          proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1548                  decode_boolean_bitfield(flags, 0x0080,
 1549                    2*8, "Key is revoked",
 1550                         "Key is not revoked"));
 1551          proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1552                  decode_boolean_bitfield(flags, 0x0001,
 1553                    2*8, "Key is a Key Signing Key",
 1554                         "Key is a Zone Signing Key"));
 1555   
 1556          cur_offset += 2;
 1557          rr_len -= 2;
 1558   
 1559          if (rr_len < 1)
 1560            goto bad_rr;
 1561          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Protocol: %u",
 1562                  tvb_get_guint8(tvb, cur_offset));
 1563          cur_offset += 1;
 1564          rr_len -= 1;
 1565   
 1566          if (rr_len < 1)
 1567            goto bad_rr;
 1568          algo = tvb_get_guint8(tvb, cur_offset);
 1569          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
 1570                  val_to_str(algo, algo_vals, "Unknown (0x%02X)"));
 1571          cur_offset += 1;
 1572          rr_len -= 1;
 1573   
 1574          key_id = compute_key_id(tvb, cur_offset-4, rr_len+4, algo);
 1575          proto_tree_add_text(rr_tree, tvb, 0, 0, "Key id: %u", key_id);
 1576   
 1577          if (rr_len != 0)
 1578            proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Public key");
 1579        }
 1580      }
 1581      break;
 1582   
 1583    case T_KEY:
 1584      {
 1585        int rr_len = data_len;
 1586        guint16 flags;
 1587        proto_item *tf;
 1588        proto_tree *flags_tree;
 1589        guint8 algo;
 1590        guint16 key_id;
 1591   
 1592        if (dns_tree != NULL) {
 1593          if (rr_len < 2)
 1594            goto bad_rr;
 1595          flags = tvb_get_ntohs(tvb, cur_offset);
 1596          tf = proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Flags: 0x%04X", flags);
 1597          flags_tree = proto_item_add_subtree(tf, ett_t_key_flags);
 1598          proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1599                  decode_boolean_bitfield(flags, 0x8000,
 1600                    2*8, "Key prohibited for authentication",
 1601                         "Key allowed for authentication"));
 1602          proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1603                  decode_boolean_bitfield(flags, 0x4000,
 1604                    2*8, "Key prohibited for confidentiality",
 1605                         "Key allowed for confidentiality"));
 1606          if ((flags & 0xC000) != 0xC000) {
 1607            /* We have a key */
 1608            proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1609                  decode_boolean_bitfield(flags, 0x2000,
 1610                    2*8, "Key is experimental or optional",
 1611                         "Key is required"));
 1612            proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1613                  decode_boolean_bitfield(flags, 0x0400,
 1614                    2*8, "Key is associated with a user",
 1615                         "Key is not associated with a user"));
 1616            proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1617                  decode_boolean_bitfield(flags, 0x0200,
 1618                    2*8, "Key is associated with the named entity",
 1619                         "Key is not associated with the named entity"));
 1620            proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1621                  decode_boolean_bitfield(flags, 0x0080,
 1622                    2*8, "Key is valid for use with IPSEC",
 1623                         "Key is not valid for use with IPSEC"));
 1624            proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1625                  decode_boolean_bitfield(flags, 0x0040,
 1626                    2*8, "Key is valid for use with MIME security multiparts",
 1627                         "Key is not valid for use with MIME security multiparts"));
 1628            proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
 1629                  decode_numeric_bitfield(flags, 0x000F,
 1630                    2*8, "Signatory = %u"));
 1631          }
 1632          cur_offset += 2;
 1633          rr_len -= 2;
 1634   
 1635          if (rr_len < 1)
 1636            goto bad_rr;
 1637          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Protocol: %u",
 1638                  tvb_get_guint8(tvb, cur_offset));
 1639          cur_offset += 1;
 1640          rr_len -= 1;
 1641   
 1642          if (rr_len < 1)
 1643            goto bad_rr;
 1644          algo = tvb_get_guint8(tvb, cur_offset);
 1645          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
 1646                  val_to_str(algo, algo_vals, "Unknown (0x%02X)"));
 1647          cur_offset += 1;
 1648          rr_len -= 1;
 1649   
 1650          key_id = compute_key_id(tvb, cur_offset-4, rr_len+4, algo);
 1651          proto_tree_add_text(rr_tree, tvb, 0, 0, "Key id: %u", key_id);
 1652   
 1653          if (rr_len != 0)
 1654            proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Public key");
 1655        }
 1656      }
 1657      break;
 1658    case T_IPSECKEY:
 1659      {
 1660        int rr_len = data_len;
 1661        guint8 gw_type, algo;
 1662        const guint8 *addr;
 1663        const guchar *gw;
 1664        int gw_name_len;
 1665        static const value_string gw_algo[] = {
 1666            { 1,     "DSA" },
 1667            { 2,     "RSA" },
 1668            { 0,      NULL }
 1669        };
 1670   
 1671   
 1672        if( dns_tree != NULL ) {
 1673          if(rr_len < 3)
 1674            goto bad_rr;
 1675   
 1676          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Gateway precedence: %u",
 1677                  tvb_get_guint8(tvb, cur_offset));
 1678          cur_offset += 1;
 1679          rr_len -= 1;
 1680   
 1681          gw_type = tvb_get_guint8(tvb, cur_offset);
 1682          cur_offset += 1;
 1683          rr_len -= 1;
 1684   
 1685          algo = tvb_get_guint8(tvb, cur_offset);
 1686          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
 1687                  val_to_str(algo, gw_algo, "Unknown (0x%02X)"));
 1688          cur_offset += 1;
 1689          rr_len -= 1;
 1690          switch( gw_type ) {
 1691             case 0:
 1692               proto_tree_add_text(rr_tree, tvb, cur_offset, 0, "Gateway: no gateway");
 1693               break;
 1694             case 1:
 1695               addr = tvb_get_ptr(tvb, cur_offset, 4);
 1696               proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Gateway: %s",
 1697                                   ip_to_str(addr) );
 1698   
 1699               cur_offset += 4;
 1700               rr_len -= 4;
 1701               break;
 1702             case 2:
 1703               addr = tvb_get_ptr(tvb, cur_offset, 16);
 1704               proto_tree_add_text(rr_tree, tvb, cur_offset, 16, "Gateway: %s",
 1705                                   ip6_to_str((const struct e_in6_addr *)addr));
 1706   
 1707               cur_offset += 16;
 1708               rr_len -= 16;
 1709               break;
 1710             case 3:
 1711               /* XXX Fix data length */
 1712               gw_name_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &gw);
 1713               proto_tree_add_text(rr_tree, tvb, cur_offset, gw_name_len,
 1714                                   "Gateway: %s", format_text(gw, strlen(gw)));
 1715   
 1716               cur_offset += gw_name_len;
 1717               rr_len -= gw_name_len;
 1718               break;
 1719             default:
 1720               proto_tree_add_text(rr_tree, tvb, cur_offset, 0, "Gateway: Unknown gateway type(%u)", gw_type);
 1721               break;
 1722          }
 1723          if (rr_len != 0)
 1724            proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Public key");
 1725        }
 1726      }
 1727      break;
 1728   
 1729    case T_AAAA:
 1730      {
 1731        const guint8 *addr6;
 1732        struct e_in6_addr addr_in6;
 1733   
 1734        addr6 = tvb_get_ptr(tvb, cur_offset, 16);
 1735        if (cinfo != NULL) {
 1736          col_append_fstr(cinfo, COL_INFO, " %s",
 1737                          ip6_to_str((const struct e_in6_addr *)addr6));
 1738        }
 1739        if (dns_tree != NULL) {
 1740          proto_item_append_text(trr, ", addr %s",
 1741                       ip6_to_str((const struct e_in6_addr *)addr6));
 1742          proto_tree_add_text(rr_tree, tvb, cur_offset, 16, "Addr: %s",
 1743                       ip6_to_str((const struct e_in6_addr *)addr6));
 1744        }
 1745        if ((class & 0x7f) == C_IN) {
 1746          memcpy(&addr_in6, addr6, sizeof(addr_in6));
 1747          add_ipv6_name(&addr_in6, name);
 1748        }
 1749      }
 1750      break;
 1751   
 1752    case T_A6:
 1753      {
 1754        unsigned short pre_len;
 1755        unsigned short suf_len;
 1756        unsigned short suf_octet_count;
 1757        const guchar *pname;
 1758        int pname_len;
 1759        int a6_offset;
 1760        int suf_offset;
 1761        struct e_in6_addr suffix;
 1762   
 1763        a6_offset = cur_offset;
 1764        pre_len = tvb_get_guint8(tvb, cur_offset);
 1765        cur_offset++;
 1766        suf_len = 128 - pre_len;
 1767        suf_octet_count = suf_len ? (suf_len - 1) / 8 + 1 : 0;
 1768        /* Pad prefix */
 1769        for (suf_offset = 0; suf_offset < 16 - suf_octet_count; suf_offset++) {
 1770          suffix.bytes[suf_offset] = 0;
 1771        }
 1772        for (; suf_offset < 16; suf_offset++) {
 1773          suffix.bytes[suf_offset] = tvb_get_guint8(tvb, cur_offset);
 1774          cur_offset++;
 1775        }
 1776   
 1777        if (pre_len > 0) {
 1778          /* XXX Fix data length */
 1779          pname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset,
 1780                                   &pname);
 1781        } else {
 1782          pname="";
 1783          pname_len = 0;
 1784        }
 1785        name_out = format_text(pname, strlen(pname));
 1786   
 1787        if (cinfo != NULL) {
 1788          col_append_fstr(cinfo, COL_INFO, " %d %s %s",
 1789                          pre_len,
 1790                          ip6_to_str(&suffix),
 1791                          name_out);
 1792        }
 1793        if (dns_tree != NULL) {
 1794          proto_tree_add_text(rr_tree, tvb, a6_offset, 1,
 1795                              "Prefix len: %u", pre_len);
 1796          a6_offset++;
 1797          if (suf_len) {
 1798            proto_tree_add_text(rr_tree, tvb, a6_offset, suf_octet_count,
 1799                                "Address suffix: %s",
 1800                                ip6_to_str(&suffix));
 1801            a6_offset += suf_octet_count;
 1802          }
 1803          if (pre_len > 0) {
 1804            proto_tree_add_text(rr_tree, tvb, a6_offset, pname_len,
 1805                                "Prefix name: %s", name_out);
 1806          }
 1807          proto_item_append_text(trr, ", addr %d %s %s",
 1808                              pre_len,
 1809                              ip6_to_str(&suffix),
 1810                              name_out);
 1811        }
 1812      }
 1813      break;
 1814   
 1815    case T_DNAME:
 1816      {
 1817        const guchar *dname;
 1818        int dname_len;
 1819   
 1820        /* XXX Fix data length */
 1821        dname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset,
 1822                                 &dname);
 1823        name_out = format_text(dname, strlen(dname));
 1824        if (cinfo != NULL)
 1825          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1826        if (dns_tree != NULL) {
 1827          proto_item_append_text(trr, ", dname %s", name_out);
 1828          proto_tree_add_text(rr_tree, tvb, cur_offset,
 1829                              dname_len, "Target name: %s", name_out);
 1830        }
 1831      }
 1832      break;
 1833   
 1834    case T_LOC:
 1835      {
 1836        guint8 version;
 1837   
 1838        if (dns_tree != NULL) {
 1839          version = tvb_get_guint8(tvb, cur_offset);
 1840          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Version: %u", version);
 1841          if (version == 0) {
 1842            /* Version 0, the only version RFC 1876 discusses. */
 1843            cur_offset++;
 1844   
 1845            proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Size: %g m",
 1846                                  rfc1867_size(tvb, cur_offset));
 1847            cur_offset++;
 1848   
 1849            proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Horizontal precision: %g m",
 1850                                  rfc1867_size(tvb, cur_offset));
 1851            cur_offset++;
 1852   
 1853            proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Vertical precision: %g m",
 1854                                  rfc1867_size(tvb, cur_offset));
 1855            cur_offset++;
 1856   
 1857            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Latitude: %s",
 1858                                  rfc1867_angle(tvb, cur_offset, "NS"));
 1859            cur_offset += 4;
 1860   
 1861            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Longitude: %s",
 1862                                  rfc1867_angle(tvb, cur_offset, "EW"));
 1863            cur_offset += 4;
 1864   
 1865            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Altitude: %g m",
 1866                                  ((gint32)tvb_get_ntohl(tvb, cur_offset) - 10000000)/100.0);
 1867          } else 
 1868            proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
 1869        }
 1870      }
 1871      break;
 1872   
 1873    case T_NSEC:
 1874      {
 1875        int rr_len = data_len;
 1876        const guchar *next_domain_name;
 1877        int next_domain_name_len;
 1878   
 1879        /* XXX Fix data length */
 1880        next_domain_name_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset,
 1881                          &next_domain_name);
 1882        name_out = format_text(next_domain_name, strlen(next_domain_name));
 1883        if (cinfo != NULL)
 1884          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1885        if (dns_tree != NULL) {
 1886          proto_item_append_text(trr, ", next domain name %s", name_out);
 1887          proto_tree_add_text(rr_tree, tvb, cur_offset, next_domain_name_len,
 1888                          "Next domain name: %s", name_out);
 1889          cur_offset += next_domain_name_len;
 1890          rr_len -= next_domain_name_len;
 1891          cur_offset += dissect_type_bitmap(rr_tree, tvb, cur_offset, rr_len);
 1892        }
 1893      }
 1894      break;
 1895   
 1896    case T_NSEC3:
 1897      {
 1898        int rr_len, initial_offset = cur_offset;
 1899        guint8 salt_len, hash_len;
 1900        proto_item *flags_item;
 1901        proto_tree *flags_tree;
 1902   
 1903        if (dns_tree != NULL) {
 1904          proto_tree_add_item(rr_tree, hf_dns_nsec3_algo, tvb, cur_offset++, 1, FALSE);
 1905          flags_item = proto_tree_add_item(rr_tree, hf_dns_nsec3_flags, tvb, cur_offset, 1, FALSE);
 1906          flags_tree = proto_item_add_subtree(flags_item, ett_nsec3_flags);
 1907          proto_tree_add_item(flags_tree, hf_dns_nsec3_flag_optout, tvb, cur_offset, 1, FALSE);
 1908          cur_offset++;
 1909          proto_tree_add_item(rr_tree, hf_dns_nsec3_iterations, tvb, cur_offset, 2, FALSE);
 1910          cur_offset += 2;
 1911          salt_len = tvb_get_guint8(tvb, cur_offset);
 1912          proto_tree_add_item(rr_tree, hf_dns_nsec3_salt_length, tvb, cur_offset++, 1, FALSE);
 1913          proto_tree_add_item(rr_tree, hf_dns_nsec3_salt_value, tvb, cur_offset, salt_len, FALSE);
 1914          cur_offset += salt_len;
 1915          hash_len = tvb_get_guint8(tvb, cur_offset);
 1916          proto_tree_add_item(rr_tree, hf_dns_nsec3_hash_length, tvb, cur_offset++, 1, FALSE);
 1917          proto_tree_add_item(rr_tree, hf_dns_nsec3_hash_value, tvb, cur_offset, hash_len, FALSE);
 1918          cur_offset += hash_len;
 1919          rr_len = data_len - (cur_offset - initial_offset);
 1920          cur_offset += dissect_type_bitmap(rr_tree, tvb, cur_offset, rr_len);
 1921        }
 1922      }
 1923      break;
 1924   
 1925    case T_NXT:
 1926      {
 1927        int rr_len = data_len;
 1928        const guchar *next_domain_name;
 1929        int next_domain_name_len;
 1930        int rr_type;
 1931        guint8 bits;
 1932        int mask;
 1933        int i;
 1934   
 1935        /* XXX Fix data length */
 1936        next_domain_name_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset,
 1937                          &next_domain_name);
 1938        name_out = format_text(next_domain_name, strlen(next_domain_name));
 1939        if (cinfo != NULL)
 1940          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 1941        if (dns_tree != NULL) {
 1942          proto_item_append_text(trr, ", next domain name %s", name_out);
 1943          proto_tree_add_text(rr_tree, tvb, cur_offset, next_domain_name_len,
 1944                          "Next domain name: %s", name_out);
 1945          cur_offset += next_domain_name_len;
 1946          rr_len -= next_domain_name_len;
 1947          rr_type = 0;
 1948          while (rr_len != 0) {
 1949            bits = tvb_get_guint8(tvb, cur_offset);
 1950            mask = 1<<7;
 1951            for (i = 0; i < 8; i++) {
 1952              if (bits & mask) {
 1953                proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
 1954                          "RR type in bit map: %s",
 1955                          dns_type_description(rr_type));
 1956              }
 1957              mask >>= 1;
 1958              rr_type++;
 1959            }
 1960            cur_offset += 1;
 1961            rr_len -= 1;
 1962          }
 1963        }
 1964      }
 1965      break;
 1966   
 1967    case T_KX:
 1968      {
 1969        guint16 preference = 0;
 1970        const guchar *kx_name;
 1971        int kx_name_len;
 1972   
 1973        /* XXX Fix data length */
 1974        kx_name_len = get_dns_name(tvb, cur_offset + 2, 0, dns_data_offset, &kx_name);
 1975        name_out = format_text(kx_name, strlen(kx_name));
 1976        if (cinfo != NULL)
 1977          col_append_fstr(cinfo, COL_INFO, " %u %s", preference, name_out);
 1978        if (dns_tree != NULL) {
 1979          proto_item_append_text(trr, ", preference %u, kx %s",
 1980                         preference, name_out);
 1981          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Preference: %u", preference);
 1982          proto_tree_add_text(rr_tree, tvb, cur_offset + 2, kx_name_len, "Key exchange: %s",
 1983                          name_out);
 1984        }
 1985      }
 1986      break;
 1987   
 1988    case T_CERT:
 1989      {
 1990        guint16 cert_type, cert_keytag;
 1991        guint8 cert_keyalg;
 1992        int rr_len = data_len;
 1993   
 1994        if (dns_tree != NULL) {
 1995          if (rr_len < 2)
 1996            goto bad_rr;
 1997          cert_type = tvb_get_ntohs(tvb, cur_offset);
 1998          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Type: %s",
 1999                  val_to_str(cert_type, cert_vals,
 2000                      "Unknown (0x%02X)"));
 2001          cur_offset += 2;
 2002          rr_len -= 2;
 2003   
 2004          if (rr_len < 2)
 2005            goto bad_rr;
 2006          cert_keytag = tvb_get_ntohs(tvb, cur_offset);
 2007          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Key footprint: 0x%04x",
 2008                  cert_keytag);
 2009          cur_offset += 2;
 2010          rr_len -= 2;
 2011   
 2012          if (rr_len < 1)
 2013            goto bad_rr;
 2014          cert_keyalg = tvb_get_guint8(tvb, cur_offset);
 2015          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
 2016                  val_to_str(cert_keyalg, algo_vals,
 2017                      "Unknown (0x%02X)"));
 2018          cur_offset += 1;
 2019          rr_len -= 1;
 2020   
 2021          if (rr_len != 0)
 2022            proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Public key");
 2023        }
 2024      }
 2025      break;
 2026   
 2027    case T_OPT:
 2028      if (dns_tree != NULL)
 2029        proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
 2030      break;
 2031   
 2032    case T_DS:
 2033      {
 2034        guint16 keytag, digest_data_size;
 2035        guint8  ds_algorithm, ds_digest;
 2036        int rr_len = data_len;
 2037   
 2038        static const value_string tds_digests[] = {
 2039          { TDSDIGEST_RESERVED, "Reserved digest" },
 2040          { TDSDIGEST_SHA1,     "SHA-1" },
 2041          { 0, NULL }
 2042        };
 2043   
 2044        if (dns_tree != NULL) {
 2045          if (rr_len < 2)
 2046            goto bad_rr;
 2047          keytag = tvb_get_ntohs(tvb, cur_offset);
 2048          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Key id: %04u", keytag);
 2049          cur_offset += 2;
 2050          rr_len -= 2;
 2051   
 2052          if (rr_len < 1)
 2053            goto bad_rr;
 2054          ds_algorithm = tvb_get_guint8(tvb, cur_offset);
 2055          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s", val_to_str(ds_algorithm, algo_vals,"Unknown (0x%02X)") );
 2056          cur_offset += 1;
 2057          rr_len -= 1;
 2058   
 2059          if (rr_len < 1)
 2060            goto bad_rr;
 2061          ds_digest = tvb_get_guint8(tvb, cur_offset);
 2062          proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Digest type: %s", val_to_str(ds_digest, tds_digests, "Unknown (0x%02X)"));
 2063          cur_offset += 1;
 2064          rr_len -= 1;
 2065   
 2066          if (ds_digest == TDSDIGEST_SHA1) {
 2067            digest_data_size = 20; /* SHA1 key is always 20 bytes long */
 2068            if (rr_len < digest_data_size)
 2069              goto bad_rr;
 2070            proto_tree_add_text(rr_tree, tvb, cur_offset, digest_data_size, "Public key");
 2071          }
 2072        }
 2073      }
 2074      break;
 2075   
 2076    case T_TKEY:
 2077      {
 2078        const guchar *tkey_algname;
 2079        int tkey_algname_len;
 2080        guint16 tkey_mode, tkey_error, tkey_keylen, tkey_otherlen;
 2081        int rr_len = data_len;
 2082        nstime_t nstime;
 2083        static const value_string tkey_modes[] = {
 2084                    { TKEYMODE_SERVERASSIGNED,   "Server assigned"   },
 2085                    { TKEYMODE_DIFFIEHELLMAN,    "Diffie Hellman"    },
 2086                    { TKEYMODE_GSSAPI,           "GSSAPI"            },
 2087                    { TKEYMODE_RESOLVERASSIGNED, "Resolver assigned" },
 2088                    { TKEYMODE_DELETE,           "Delete"            },
 2089                    { 0,                         NULL                } };
 2090   
 2091        if (dns_tree != NULL) {
 2092          proto_tree *key_tree;
 2093          proto_item *key_item;
 2094   
 2095          /* XXX Fix data length */
 2096          tkey_algname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &tkey_algname);
 2097          proto_tree_add_text(rr_tree, tvb, cur_offset, tkey_algname_len,
 2098                  "Algorithm name: %s",
 2099                  format_text(tkey_algname, strlen(tkey_algname)));
 2100          cur_offset += tkey_algname_len;
 2101          rr_len -= tkey_algname_len;
 2102   
 2103          if (rr_len < 4)
 2104            goto bad_rr;
 2105          nstime.secs = tvb_get_ntohl(tvb, cur_offset);
 2106          nstime.nsecs = 0;
 2107          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Signature inception: %s",
 2108                  abs_time_to_str(&nstime));
 2109          cur_offset += 4;
 2110          rr_len -= 4;
 2111   
 2112          if (rr_len < 4)
 2113            goto bad_rr;
 2114          nstime.secs = tvb_get_ntohl(tvb, cur_offset);
 2115          nstime.nsecs = 0;
 2116          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Signature expiration: %s",
 2117                  abs_time_to_str(&nstime));
 2118          cur_offset += 4;
 2119          rr_len -= 4;
 2120   
 2121          if (rr_len < 2)
 2122            goto bad_rr;
 2123          tkey_mode = tvb_get_ntohs(tvb, cur_offset);
 2124          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Mode: %s",
 2125                  val_to_str(tkey_mode, tkey_modes,
 2126                      "Unknown (0x%04X)"));
 2127          cur_offset += 2;
 2128          rr_len -= 2;
 2129   
 2130          if (rr_len < 2)
 2131            goto bad_rr;
 2132          tkey_error = tvb_get_ntohs(tvb, cur_offset);
 2133          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Error: %s",
 2134                  val_to_str(tkey_error, rcode_vals,
 2135                  val_to_str(tkey_error, tsigerror_vals, "Unknown error (%x)")));
 2136          cur_offset += 2;
 2137          rr_len -= 2;
 2138   
 2139          tkey_keylen = tvb_get_ntohs(tvb, cur_offset);
 2140          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Key Size: %u",
 2141              tkey_keylen);
 2142          cur_offset += 2;
 2143          rr_len -= 2;
 2144   
 2145          if (tkey_keylen != 0) {
 2146                  key_item = proto_tree_add_text(
 2147                          rr_tree, tvb, cur_offset, tkey_keylen, "Key Data");
 2148   
 2149                  key_tree = proto_item_add_subtree(key_item, ett_t_key);
 2150   
 2151                  switch(tkey_mode) {
 2152                  case TKEYMODE_GSSAPI: {
 2153                          tvbuff_t *gssapi_tvb;
 2154   
 2155                          /*
 2156                           * XXX - in at least one capture, this appears to 
 2157                           * be an NTLMSSP blob, with no ASN.1 in it, in 
 2158                           * a query.
 2159                           *
 2160                           * See RFC 3645 which might indicate what's going 
 2161                           * on here.  (The key is an output_token from 
 2162                           * GSS_Init_sec_context.)
 2163                           *
 2164                           * How the heck do we know what method is being
 2165                           * used, so we know how to decode the key?  Do we 
 2166                           * have to look at the algorithm name, e.g.
 2167                           * "gss.microsoft.com"?  We currently do as the
 2168                           * the SMB dissector does in some cases, and check
 2169                           * whether the security blob begins with "NTLMSSP".
 2170                           */
 2171                          gssapi_tvb = tvb_new_subset(
 2172                                  tvb, cur_offset, tkey_keylen, tkey_keylen);
 2173                          if(tvb_strneql(gssapi_tvb, 0, "NTLMSSP", 7) == 0)
 2174                                  call_dissector(ntlmssp_handle, gssapi_tvb, pinfo, key_tree);
 2175                          else 
 2176                                  call_dissector(gssapi_handle, gssapi_tvb, pinfo,
 2177                                  key_tree);
 2178   
 2179                          break;
 2180                  }
 2181                  default:
 2182   
 2183                          /* No dissector for this key mode */
 2184   
 2185                          break;
 2186                  }
 2187   
 2188                  cur_offset += tkey_keylen;
 2189                  rr_len -= tkey_keylen;
 2190          }
 2191   
 2192          if (rr_len < 2)
 2193            goto bad_rr;
 2194          tkey_otherlen = tvb_get_ntohs(tvb, cur_offset);
 2195          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Other Size: %u",
 2196              tkey_otherlen);
 2197          cur_offset += 2;
 2198          rr_len -= 2;
 2199   
 2200          if (tkey_otherlen != 0) {
 2201            if (rr_len < tkey_otherlen)
 2202              goto bad_rr;
 2203            proto_tree_add_text(rr_tree, tvb, cur_offset, tkey_otherlen, "Other Data");
 2204            cur_offset += tkey_otherlen;
 2205            rr_len -= tkey_otherlen;
 2206          }
 2207        }
 2208      }
 2209      break;
 2210   
 2211    case T_TSIG:
 2212      {
 2213        guint16 tsig_error, tsig_timehi, tsig_siglen, tsig_otherlen;
 2214        guint32 tsig_timelo;
 2215        const guchar *tsig_raw_algname;
 2216        char *tsig_algname;
 2217        int tsig_algname_len;
 2218        nstime_t nstime;
 2219        int rr_len = data_len;
 2220   
 2221        if (dns_tree != NULL) {
 2222          /* XXX Fix data length */
 2223          tsig_algname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &tsig_raw_algname);
 2224          tsig_algname=format_text(tsig_raw_algname, strlen(tsig_raw_algname));
 2225          proto_tree_add_string(rr_tree, hf_dns_tsig_algorithm_name, tvb, cur_offset, tsig_algname_len, tsig_algname);
 2226          cur_offset += tsig_algname_len;
 2227          rr_len -= tsig_algname_len;
 2228   
 2229          if (rr_len < 6)
 2230            goto bad_rr;
 2231          tsig_timehi = tvb_get_ntohs(tvb, cur_offset);
 2232          tsig_timelo = tvb_get_ntohl(tvb, cur_offset + 2);
 2233          nstime.secs = tsig_timelo;
 2234          nstime.nsecs = 0;
 2235          proto_tree_add_text(rr_tree, tvb, cur_offset, 6, "Time signed: %s%s",
 2236                  abs_time_to_str(&nstime), tsig_timehi == 0 ? "" : "(high bits set)");
 2237          cur_offset += 6;
 2238          rr_len -= 6;
 2239   
 2240          if (rr_len < 2)
 2241            goto bad_rr;
 2242   
 2243          proto_tree_add_item(rr_tree, hf_dns_tsig_fudge, tvb, cur_offset, 2, FALSE);
 2244          cur_offset += 2;
 2245          rr_len -= 2;
 2246   
 2247          if (rr_len < 2)
 2248            goto bad_rr;
 2249          tsig_siglen = tvb_get_ntohs(tvb, cur_offset);
 2250          proto_tree_add_item(rr_tree, hf_dns_tsig_mac_size, tvb, cur_offset, 2, FALSE);
 2251          cur_offset += 2;
 2252          rr_len -= 2;
 2253   
 2254          if (tsig_siglen != 0) {
 2255            proto_item *mac_item;
 2256            proto_tree *mac_tree;
 2257            tvbuff_t *sub_tvb;
 2258   
 2259            if (rr_len < tsig_siglen)
 2260              goto bad_rr;
 2261   
 2262            mac_item = proto_tree_add_item(rr_tree, hf_dns_tsig_mac, tvb, cur_offset, tsig_siglen, FALSE);
 2263            mac_tree = proto_item_add_subtree(mac_item, ett_dns_mac);
 2264   
 2265            sub_tvb=tvb_new_subset(tvb, cur_offset, tsig_siglen, tsig_siglen);
 2266   
 2267            if(!dissector_try_string(dns_tsig_dissector_table, tsig_algname, sub_tvb, pinfo, mac_tree)){
 2268                  proto_tree_add_text(mac_tree, sub_tvb, 0, tvb_length(sub_tvb), "No dissector for algorithm:%s", tsig_algname);
 2269            }
 2270   
 2271            cur_offset += tsig_siglen;
 2272            rr_len -= tsig_siglen;
 2273          }
 2274   
 2275          if (rr_len < 2)
 2276            goto bad_rr;
 2277          proto_tree_add_item(rr_tree, hf_dns_tsig_original_id, tvb, cur_offset, 2, FALSE);
 2278          cur_offset += 2;
 2279          rr_len -= 2;
 2280   
 2281          if (rr_len < 2)
 2282            goto bad_rr;
 2283          tsig_error = tvb_get_ntohs(tvb, cur_offset);
 2284          proto_tree_add_uint_format(rr_tree, hf_dns_tsig_error, tvb, cur_offset, 2, tsig_error, "Error: %s (%d)",
 2285                  val_to_str(tsig_error, rcode_vals,val_to_str(tsig_error, tsigerror_vals, "Unknown error")),
 2286                  tsig_error);
 2287          cur_offset += 2;
 2288          rr_len -= 2;
 2289   
 2290          if (rr_len < 2)
 2291            goto bad_rr;
 2292          tsig_otherlen = tvb_get_ntohs(tvb, cur_offset);
 2293          proto_tree_add_item(rr_tree, hf_dns_tsig_other_len, tvb, cur_offset, 2, FALSE);
 2294          cur_offset += 2;
 2295          rr_len -= 2;
 2296   
 2297          if (tsig_otherlen != 0) {
 2298            if (rr_len < tsig_otherlen)
 2299              goto bad_rr;
 2300            proto_tree_add_item(rr_tree, hf_dns_tsig_other_data, tvb, cur_offset, tsig_otherlen, FALSE);
 2301            cur_offset += tsig_otherlen;
 2302            rr_len -= tsig_otherlen;
 2303          }
 2304        }
 2305      }
 2306      break;
 2307   
 2308    case T_WINS:
 2309      {
 2310        int rr_len = data_len;
 2311        guint32 local_flag;
 2312        guint32 lookup_timeout;
 2313        guint32 cache_timeout;
 2314        guint32 nservers;
 2315   
 2316        if (dns_tree != NULL) {
 2317          if (rr_len < 4)
 2318            goto bad_rr;
 2319          local_flag = tvb_get_ntohl(tvb, cur_offset);
 2320          if (dns_tree != NULL) {
 2321            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Local flag: %s",
 2322                         local_flag ? "true" : "false");
 2323          }
 2324          cur_offset += 4;
 2325          rr_len -= 4;
 2326   
 2327          if (rr_len < 4)
 2328            goto bad_rr;
 2329          lookup_timeout = tvb_get_ntohl(tvb, cur_offset);
 2330          if (dns_tree != NULL) {
 2331            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Lookup timeout: %u seconds",
 2332                         lookup_timeout);
 2333          }
 2334          cur_offset += 4;
 2335          rr_len -= 4;
 2336   
 2337          if (rr_len < 4)
 2338            goto bad_rr;
 2339          cache_timeout = tvb_get_ntohl(tvb, cur_offset);
 2340          if (dns_tree != NULL) {
 2341            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Cache timeout: %u seconds",
 2342                         cache_timeout);
 2343          }
 2344          cur_offset += 4;
 2345          rr_len -= 4;
 2346   
 2347          if (rr_len < 4)
 2348            goto bad_rr;
 2349          nservers = tvb_get_ntohl(tvb, cur_offset);
 2350          if (dns_tree != NULL) {
 2351            proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Number of WINS servers: %u",
 2352                         nservers);
 2353          }
 2354          cur_offset += 4;
 2355          rr_len -= 4;
 2356   
 2357          while (rr_len != 0 && nservers != 0) {
 2358            if (rr_len < 4)
 2359              goto bad_rr;
 2360            if (dns_tree != NULL) {
 2361              proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "WINS server address: %s",
 2362                       ip_to_str(tvb_get_ptr(tvb, cur_offset, 4)));
 2363            }
 2364            cur_offset += 4;
 2365            rr_len -= 4;
 2366            nservers--;
 2367          }
 2368        }
 2369      }
 2370      break;
 2371   
 2372    case T_WINS_R:
 2373      {
 2374        int rr_len = data_len;
 2375        guint32 local_flag;
 2376        guint32 lookup_timeout;
 2377        guint32 cache_timeout;
 2378        const guchar *dname;
 2379        int dname_len;
 2380   
 2381        if (rr_len < 4)
 2382          goto bad_rr;
 2383        local_flag = tvb_get_ntohl(tvb, cur_offset);
 2384        if (dns_tree != NULL) {
 2385          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Local flag: %s",
 2386                         local_flag ? "true" : "false");
 2387        }
 2388        cur_offset += 4;
 2389        rr_len -= 4;
 2390   
 2391        if (rr_len < 4)
 2392          goto bad_rr;
 2393        lookup_timeout = tvb_get_ntohl(tvb, cur_offset);
 2394        if (dns_tree != NULL) {
 2395          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Lookup timeout: %u seconds",
 2396                         lookup_timeout);
 2397        }
 2398        cur_offset += 4;
 2399        rr_len -= 4;
 2400   
 2401        if (rr_len < 4)
 2402          goto bad_rr;
 2403        cache_timeout = tvb_get_ntohl(tvb, cur_offset);
 2404        if (dns_tree != NULL) {
 2405          proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Cache timeout: %u seconds",
 2406                         cache_timeout);
 2407        }
 2408        cur_offset += 4;
 2409        rr_len -= 4;
 2410   
 2411        /* XXX Fix data length */
 2412        dname_len = get_dns_name(tvb, cur_offset, 0, dns_data_offset, &dname);
 2413        name_out = format_text(dname, strlen(dname));
 2414        if (cinfo != NULL)
 2415          col_append_fstr(cinfo, COL_INFO, " %s", name_out);
 2416        if (dns_tree != NULL) {
 2417          proto_item_append_text(trr, ", name result domain %s", name_out);
 2418          proto_tree_add_text(rr_tree, tvb, cur_offset, dname_len, "Name result domain: %s",
 2419                          name_out);
 2420        }
 2421      }
 2422      break;
 2423   
 2424    case T_SRV:
 2425      {
 2426        guint16 priority = 0;
 2427        guint16 weight = 0;
 2428        guint16 port = 0;
 2429        const guchar *target;
 2430        int target_len;
 2431   
 2432        priority = tvb_get_ntohs(tvb, cur_offset);
 2433        weight = tvb_get_ntohs(tvb, cur_offset+2);
 2434        port = tvb_get_ntohs(tvb, cur_offset+4);
 2435   
 2436        /* XXX Fix data length */
 2437        target_len = get_dns_name(tvb, cur_offset + 6, 0, dns_data_offset, &target);
 2438        name_out = format_text(target, strlen(target));
 2439        if (cinfo != NULL)
 2440          col_append_fstr(cinfo, COL_INFO, " %u %u %u %s", priority, weight, port, name_out);
 2441        if (dns_tree != NULL) {
 2442          proto_item_append_text(trr,
 2443                         ", priority %u, weight %u, port %u, target %s",
 2444                         priority, weight, port, name_out);
 2445          proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Priority: %u", priority);
 2446          proto_tree_add_text(rr_tree, tvb, cur_offset + 2, 2, "Weight: %u", weight);
 2447          proto_tree_add_text(rr_tree, tvb, cur_offset + 4, 2, "Port: %u", port);
 2448          proto_tree_add_text(rr_tree, tvb, cur_offset + 6, target_len, "Target: %s",
 2449                          name_out);
 2450        }
 2451      }
 2452      break;
 2453   
 2454      case T_NAPTR:
 2455      {
 2456        int offset = cur_offset;
 2457        guint16 order;
 2458        guint16 preference;
 2459        gchar *flags;
 2460        guint8 flags_len;
 2461        guchar *service;
 2462        guint8 service_len;
 2463        guchar *regex;
 2464        guint8 regex_len;
 2465        guchar *replacement;
 2466        guint8 replacement_len;
 2467   
 2468        order = tvb_get_ntohs(tvb, offset);
 2469        offset += 2;
 2470        preference = tvb_get_ntohs(tvb, offset);
 2471        offset += 2;
 2472        flags_len = tvb_get_guint8(tvb, offset);
 2473        offset++;
 2474        flags = tvb_get_ephemeral_string(tvb, offset, flags_len);
 2475        offset += flags_len;
 2476        service_len = tvb_get_guint8(tvb, offset);
 2477        offset++;
 2478        service = tvb_get_ephemeral_string(tvb, offset, service_len);
 2479        offset += service_len;
 2480        regex_len = tvb_get_guint8(tvb, offset);
 2481        offset++;
 2482        regex = tvb_get_ephemeral_string(tvb, offset, regex_len);
 2483        offset += regex_len;
 2484        replacement_len = tvb_get_guint8(tvb, offset);
 2485        offset++;
 2486        replacement = tvb_get_ephemeral_string(tvb, offset, replacement_len);
 2487   
 2488        if (cinfo != NULL)
 2489          col_append_fstr(cinfo, COL_INFO, " %u %u %s", order, preference, flags);
 2490   
 2491        if (dns_tree != NULL) {
 2492          proto_item_append_text(trr, ", order %u, preference %u, flags %s",
 2493                  order, preference, flags);
 2494          offset = cur_offset;
 2495          proto_tree_add_text(rr_tree, tvb, offset, 2, "Order: %u", order);
 2496          offset += 2;
 2497          proto_tree_add_text(rr_tree, tvb, offset, 2, "Preference: %u", preference);
 2498          offset += 2;
 2499          proto_tree_add_text(rr_tree, tvb, offset, 1, "Flags length: %u", flags_len);
 2500          offset++;
 2501          proto_tree_add_text(rr_tree, tvb, offset, flags_len, "Flags: \"%s\"", flags);
 2502          offset += flags_len;
 2503          proto_tree_add_text(rr_tree, tvb, offset, 1, "Service length: %u", service_len);
 2504          offset++;
 2505          proto_tree_add_text(rr_tree, tvb, offset, service_len, "Service: \"%s\"", service);
 2506          offset += service_len;
 2507          proto_tree_add_text(rr_tree, tvb, offset, 1, "Regex length: %u", regex_len);
 2508          offset++;
 2509          proto_tree_add_text(rr_tree, tvb, offset, regex_len, "Regex: \"%s\"", regex);
 2510          offset += regex_len;
 2511          proto_tree_add_text(rr_tree, tvb, offset, 1, "Replacement length: %u", replacement_len);
 2512          offset++;
 2513          proto_tree_add_text(rr_tree, tvb, offset, replacement_len, "Replacement: \"%s\"", replacement);
 2514        }
 2515      }
 2516      break;
 2517   
 2518      /* TODO: parse more record types */
 2519   
 2520    default:
 2521      if (dns_tree != NULL)
 2522        proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
 2523      break;
 2524    }
 2525   
 2526    data_offset += data_len;
 2527   
 2528    return data_offset - data_start;
 2529   
 2530  bad_rr:
 2531    if (dns_tree != NULL) {
 2532      proto_item_append_text(trr, ", bad RR length %d, too short",
 2533                          data_len);
 2534    }
 2535   
 2536    data_offset += data_len;
 2537   
 2538    return data_offset - data_start;
 2539  }
Show more  




Change Warning 5592.35899 : Format String

Priority:
State:
Finding:
Owner:
Note: