Esempio n. 1
0
 internal static void WriteVersion0Header(byte[] buffer, int offset,
                                          IgmpMessageType igmpMessageType, byte code, uint identifier, IpV4Address groupAddress, ulong accessKey)
 {
     buffer.Write(offset + Offset.MessageType, (byte)igmpMessageType);
     buffer.Write(offset + Offset.Code, code);
     buffer.Write(offset + Offset.Version0GroupAddress, groupAddress, Endianity.Big);
     buffer.Write(offset + Offset.Identifier, identifier, Endianity.Big);
     buffer.Write(offset + Offset.AccessKey, accessKey, Endianity.Big);
     WriteChecksum(buffer, offset, Version0HeaderLength);
 }
Esempio n. 2
0
        internal static void WriteHeader(byte[] buffer, int offset, IgmpMessageType igmpMessageType, TimeSpan maxResponseTime, IpV4Address groupAddress)
        {
            ByteArrayExtensions.Write(buffer, offset, (byte)igmpMessageType);
            double num = maxResponseTime.TotalSeconds * 10.0;

            if (num >= 256.0 || num < 0.0)
            {
                throw new ArgumentOutOfRangeException("maxResponseTime", (object)maxResponseTime, "must be in the range [" + (object)TimeSpan.Zero + ", " + (string)(object)TimeSpan.FromSeconds(25.5) + "]");
            }
            ByteArrayExtensions.Write(buffer, offset + 1, (byte)num);
            ByteArrayExtensions.Write(buffer, offset + 4, groupAddress, Endianity.Big);
            IgmpDatagram.WriteChecksum(buffer, offset, 8);
        }
Esempio n. 3
0
        internal static void WriteVersion1PlusSimpleHeader(byte[] buffer, int offset,
                                                           IgmpMessageType igmpMessageType, TimeSpan maxResponseTime, IpV4Address groupAddress)
        {
            buffer.Write(offset + Offset.MessageType, (byte)igmpMessageType);

            double numTenthOfASecond = (maxResponseTime.TotalSeconds * 10);

            if (numTenthOfASecond >= 256 || numTenthOfASecond < 0)
            {
                throw new ArgumentOutOfRangeException("maxResponseTime", maxResponseTime, "must be in the range [" + TimeSpan.Zero + ", " + TimeSpan.FromSeconds(255 * 0.1) + "]");
            }
            buffer.Write(offset + Offset.MaxResponseCode, (byte)numTenthOfASecond);

            buffer.Write(offset + Offset.Version1PlusGroupAddress, groupAddress, Endianity.Big);

            WriteChecksum(buffer, offset, HeaderLength);
        }
Esempio n. 4
0
        internal static void WriteHeader(byte[] buffer, int offset,
                                         IgmpMessageType igmpMessageType, TimeSpan maxResponseTime, IpV4Address groupAddress)
        {
            buffer.Write(offset + Offset.MessageType, (byte)igmpMessageType);

            double numTenthOfASecond = (maxResponseTime.TotalSeconds * 10);
            if (numTenthOfASecond >= 256 || numTenthOfASecond < 0)
                throw new ArgumentOutOfRangeException("maxResponseTime", maxResponseTime, "must be in the range [" + TimeSpan.Zero + ", " + TimeSpan.FromSeconds(255 * 0.1) + "]");
            buffer.Write(offset + Offset.MaxResponseCode, (byte)numTenthOfASecond);

            buffer.Write(offset + Offset.GroupAddress, groupAddress, Endianity.Big);

            WriteChecksum(buffer, offset, HeaderLength);
        }
Esempio n. 5
0
 internal static void WriteVersion0Header(byte[] buffer, int offset,
                                          IgmpMessageType igmpMessageType, byte code, uint identifier, IpV4Address groupAddress, ulong accessKey)
 {
     buffer.Write(offset + Offset.MessageType, (byte)igmpMessageType);
     buffer.Write(offset + Offset.Code, code);
     buffer.Write(offset + Offset.Version0GroupAddress, groupAddress, Endianity.Big);
     buffer.Write(offset + Offset.Identifier, identifier, Endianity.Big);
     buffer.Write(offset + Offset.AccessKey, accessKey, Endianity.Big);
     WriteChecksum(buffer, offset, Version0HeaderLength);
 }
Esempio n. 6
0
        public static IgmpLayer NextIgmpLayer(this Random random)
        {
            IgmpMessageType igmpMessageType = random.NextEnum(IgmpMessageType.None, IgmpMessageType.CreateGroupRequestVersion0,
                                                              IgmpMessageType.CreateGroupReplyVersion0, IgmpMessageType.JoinGroupRequestVersion0,
                                                              IgmpMessageType.JoinGroupReplyVersion0, IgmpMessageType.LeaveGroupRequestVersion0,
                                                              IgmpMessageType.LeaveGroupReplyVersion0, IgmpMessageType.ConfirmGroupRequestVersion0,
                                                              IgmpMessageType.ConfirmGroupReplyVersion0,
                                                              IgmpMessageType.MulticastTraceRouteResponse, IgmpMessageType.MulticastTraceRoute); // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
            IgmpQueryVersion igmpQueryVersion    = IgmpQueryVersion.None;
            TimeSpan         igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1), TimeSpan.FromSeconds(256 * 0.1) - TimeSpan.FromTicks(1));
            IpV4Address      igmpGroupAddress    = random.NextIpV4Address();
            bool?            igmpIsSuppressRouterSideProcessing;
            byte?            igmpQueryRobustnessVariable;
            TimeSpan?        igmpQueryInterval;

            IpV4Address[]     igmpSourceAddresses;
            IgmpGroupRecord[] igmpGroupRecords;

            switch (igmpMessageType)
            {
            case IgmpMessageType.MembershipQuery:
                igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown);
                switch (igmpQueryVersion)
                {
                case IgmpQueryVersion.Version1:
                    return(new IgmpQueryVersion1Layer
                    {
                        GroupAddress = igmpGroupAddress
                    });

                case IgmpQueryVersion.Version2:
                    return(new IgmpQueryVersion2Layer
                    {
                        MaxResponseTime = igmpMaxResponseTime,
                        GroupAddress = igmpGroupAddress
                    });

                case IgmpQueryVersion.Version3:
                    igmpIsSuppressRouterSideProcessing = random.NextBool();
                    igmpQueryRobustnessVariable        = random.NextByte(8);
                    igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1),
                                                              IgmpDatagram.MaxVersion3MaxResponseTime - TimeSpan.FromTicks(1));
                    igmpQueryInterval   = random.NextTimeSpan(TimeSpan.Zero, IgmpDatagram.MaxQueryInterval - TimeSpan.FromTicks(1));
                    igmpSourceAddresses = random.NextIpV4Addresses(random.Next(1000));
                    return(new IgmpQueryVersion3Layer
                    {
                        SourceAddresses = igmpSourceAddresses.AsReadOnly(),
                        MaxResponseTime = igmpMaxResponseTime,
                        GroupAddress = igmpGroupAddress,
                        IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing.Value,
                        QueryRobustnessVariable = igmpQueryRobustnessVariable.Value,
                        QueryInterval = igmpQueryInterval.Value,
                    });

                default:
                    throw new InvalidOperationException("Invalid Query Version " + igmpQueryVersion);
                }

            case IgmpMessageType.MembershipReportVersion1:
                return(new IgmpReportVersion1Layer
                {
                    GroupAddress = igmpGroupAddress
                });

            case IgmpMessageType.MembershipReportVersion2:
                return(new IgmpReportVersion2Layer
                {
                    MaxResponseTime = igmpMaxResponseTime,
                    GroupAddress = igmpGroupAddress
                });

            case IgmpMessageType.LeaveGroupVersion2:
                return(new IgmpLeaveGroupVersion2Layer
                {
                    MaxResponseTime = igmpMaxResponseTime,
                    GroupAddress = igmpGroupAddress
                });

            case IgmpMessageType.MembershipReportVersion3:
                igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100));
                if (igmpGroupRecords.Count() == 0 && random.NextBool())
                {
                    return(new IgmpReportVersion3Layer());
                }
                return(new IgmpReportVersion3Layer
                {
                    GroupRecords = igmpGroupRecords.AsReadOnly()
                });

            default:
                throw new InvalidOperationException("Invalid message type " + igmpMessageType);
            }
        }
        public static IgmpLayer NextIgmpLayer(this Random random)
        {
            IgmpMessageType igmpMessageType = random.NextEnum(IgmpMessageType.None,
                                                              IgmpMessageType.MulticastTraceRouteResponse, IgmpMessageType.MulticastTraceRoute); // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
            TimeSpan    igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1), TimeSpan.FromSeconds(256 * 0.1) - TimeSpan.FromTicks(1));
            IpV4Address igmpGroupAddress    = random.NextIpV4Address();
            ulong       accessKey           = random.NextULong();
            uint        identifier          = random.NextUInt();

            switch (igmpMessageType)
            {
            case IgmpMessageType.CreateGroupRequestVersion0:
                return(new IgmpCreateGroupRequestVersion0Layer
                {
                    CreateGroupRequestCode = random.NextEnum <IgmpVersion0CreateGroupRequestCode>(),
                    Identifier = identifier,
                });

            case IgmpMessageType.CreateGroupReplyVersion0:
            case IgmpMessageType.JoinGroupReplyVersion0:
            case IgmpMessageType.LeaveGroupReplyVersion0:
            case IgmpMessageType.ConfirmGroupReplyVersion0:
                IgmpVersion0ReplyCode code = random.NextEnum <IgmpVersion0ReplyCode>();
                return(new IgmpReplyVersion0Layer
                {
                    MessageType = igmpMessageType,
                    Code = code,
                    RetryInThisManySeconds = (byte)(code == IgmpVersion0ReplyCode.RequestPendingRetryInThisManySeconds? random.NextByte((byte)IgmpVersion0ReplyCode.RequestPendingRetryInThisManySeconds, byte.MaxValue) : 0),
                    Identifier = identifier,
                    GroupAddress = igmpGroupAddress,
                    AccessKey = accessKey,
                });

            case IgmpMessageType.JoinGroupRequestVersion0:
            case IgmpMessageType.LeaveGroupRequestVersion0:
                return(new IgmpRequestVersion0Layer
                {
                    MessageType = igmpMessageType,
                    Identifier = identifier,
                    GroupAddress = igmpGroupAddress,
                    AccessKey = accessKey,
                });

            case IgmpMessageType.ConfirmGroupRequestVersion0:
                return(new IgmpConfirmGroupRequestVersion0Layer
                {
                    GroupAddress = igmpGroupAddress,
                    AccessKey = accessKey,
                });

            case IgmpMessageType.MembershipQuery:
                IgmpQueryVersion igmpQueryVersion = random.NextEnum(IgmpQueryVersion.None, IgmpQueryVersion.Unknown);
                switch (igmpQueryVersion)
                {
                case IgmpQueryVersion.Version1:
                    return(new IgmpQueryVersion1Layer
                    {
                        GroupAddress = igmpGroupAddress
                    });

                case IgmpQueryVersion.Version2:
                    return(new IgmpQueryVersion2Layer
                    {
                        MaxResponseTime = igmpMaxResponseTime,
                        GroupAddress = igmpGroupAddress
                    });

                case IgmpQueryVersion.Version3:
                    bool igmpIsSuppressRouterSideProcessing = random.NextBool();
                    byte igmpQueryRobustnessVariable        = random.NextByte(8);
                    igmpMaxResponseTime = random.NextTimeSpan(TimeSpan.FromSeconds(0.1),
                                                              IgmpDatagram.MaxVersion3MaxResponseTime - TimeSpan.FromTicks(1));
                    TimeSpan      igmpQueryInterval   = random.NextTimeSpan(TimeSpan.Zero, IgmpDatagram.MaxQueryInterval - TimeSpan.FromTicks(1));
                    IpV4Address[] igmpSourceAddresses = random.NextIpV4Addresses(random.Next(1000));
                    return(new IgmpQueryVersion3Layer
                    {
                        SourceAddresses = igmpSourceAddresses.AsReadOnly(),
                        MaxResponseTime = igmpMaxResponseTime,
                        GroupAddress = igmpGroupAddress,
                        IsSuppressRouterSideProcessing = igmpIsSuppressRouterSideProcessing,
                        QueryRobustnessVariable = igmpQueryRobustnessVariable,
                        QueryInterval = igmpQueryInterval,
                    });

                default:
                    throw new InvalidOperationException("Invalid Query Version " + igmpQueryVersion);
                }

            case IgmpMessageType.MembershipReportVersion1:
                return(new IgmpReportVersion1Layer
                {
                    GroupAddress = igmpGroupAddress
                });

            case IgmpMessageType.MembershipReportVersion2:
                return(new IgmpReportVersion2Layer
                {
                    MaxResponseTime = igmpMaxResponseTime,
                    GroupAddress = igmpGroupAddress
                });

            case IgmpMessageType.LeaveGroupVersion2:
                return(new IgmpLeaveGroupVersion2Layer
                {
                    MaxResponseTime = igmpMaxResponseTime,
                    GroupAddress = igmpGroupAddress
                });

            case IgmpMessageType.MembershipReportVersion3:
                IgmpGroupRecord[] igmpGroupRecords = random.NextIgmpGroupRecords(random.Next(100));
                if (!igmpGroupRecords.Any() && random.NextBool())
                {
                    return(new IgmpReportVersion3Layer());
                }
                return(new IgmpReportVersion3Layer
                {
                    GroupRecords = igmpGroupRecords.AsReadOnly()
                });

            default:
                throw new InvalidOperationException("Invalid message type " + igmpMessageType);
            }
        }