Esempio n. 1
0
  /**
   * Deserializer function for IPv4 packets.
   *
   * @return deserializer function
   */
  public static Deserializer<IGMP> deserializer() {
    return (data, offset, length) -> {
      checkInput(data, offset, length, IGMPv2.HEADER_LENGTH);

      // we will assume that this is IGMPv2 if the length is 8
      boolean isV2 = length == IGMPv2.HEADER_LENGTH;

      IGMP igmp = isV2 ? new IGMPv2() : new IGMPv3();

      final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
      igmp.igmpType = bb.get();
      igmp.resField = bb.get();
      igmp.checksum = bb.getShort();

      if (isV2) {
        igmp.addGroup(new IGMPQuery(IpAddress.valueOf(bb.getInt()), 0));
        if (igmp.validChecksum()) {
          return igmp;
        }
        throw new DeserializationException("invalid checksum");
      }

      // second check for IGMPv3
      checkInput(data, offset, length, IGMPv3.MINIMUM_HEADER_LEN);

      String msg;

      switch (igmp.igmpType) {
        case TYPE_IGMPV3_MEMBERSHIP_QUERY:
          IGMPQuery qgroup = new IGMPQuery();
          qgroup.deserialize(bb);
          igmp.groups.add(qgroup);
          break;

        case TYPE_IGMPV3_MEMBERSHIP_REPORT:
          bb.getShort(); // Ignore resvd
          int ngrps = bb.getShort();

          for (; ngrps > 0; ngrps--) {
            IGMPMembership mgroup = new IGMPMembership();
            mgroup.deserialize(bb);
            igmp.groups.add(mgroup);
          }
          break;

          /*
           * NOTE: according to the IGMPv3 spec. These previous IGMP type fields
           * must be supported.  At this time we are going to <b>assume</b> we run
           * in a modern network where all devices are IGMPv3 capable.
           */
        case TYPE_IGMPV1_MEMBERSHIP_REPORT:
        case TYPE_IGMPV2_MEMBERSHIP_REPORT:
        case TYPE_IGMPV2_LEAVE_GROUP:
          igmp.unsupportTypeData = bb.array(); // Is this the entire array?
          msg = "IGMP message type: " + igmp.igmpType + " is not supported";
          igmp.log.debug(msg);
          break;

        default:
          msg = "IGMP message type: " + igmp.igmpType + " is not recognized";
          igmp.unsupportTypeData = bb.array();
          igmp.log.debug(msg);
          break;
      }
      return igmp;
    };
  }