{"action":"created","comment":{"url":"https://api.github.com/repos/libpnet/libpnet/pulls/comments/45793428","id":45793428,"diff_hunk":"@@ -0,0 +1,360 @@\n+// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com>\n+//\n+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n+// option. This file may not be copied, modified, or distributed\n+// except according to those terms.\n+\n+//! ICMP packet abstraction\n+\n+use packet::{Packet, PrimitiveValues};\n+use pnet_macros_support::types::*;\n+\n+/// Represents the \"ICMP type\" header field.\n+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\n+pub struct IcmpType(pub u8);\n+\n+impl IcmpType {\n+    /// Create an ICMP type\n+    pub fn new(val: u8) -> IcmpType {\n+        IcmpType(val)\n+    }\n+}\n+\n+impl PrimitiveValues for IcmpType {\n+    type T = (u8,);\n+    fn to_primitive_values(&self) -> (u8,) {\n+        (self.0,)\n+    }\n+}\n+\n+/// Represents the \"ICMP code\" header field.\n+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\n+pub struct IcmpCode(pub u8);\n+\n+impl IcmpCode {\n+    /// Create an ICMP code\n+    pub fn new(val: u8) -> IcmpCode {\n+        IcmpCode(val)\n+    }\n+}\n+\n+impl PrimitiveValues for IcmpCode {\n+    type T = (u8,);\n+    fn to_primitive_values(&self) -> (u8,) {\n+        (self.0,)\n+    }\n+}\n+\n+/// Represents a generic ICMP packet\n+#[packet]\n+pub struct Icmp {\n+    #[construct_with(u8)]\n+    icmp_type: IcmpType,\n+    #[construct_with(u8)]\n+    icmp_code: IcmpCode,\n+    checksum: u16be,\n+    // theoritically, the header is 64 bytes long, but since the \"Rest Of Header\" part depends on\n+    // the ICMP type and ICMP code, we consider it's part of the payload.\n+    // rest_of_header: u32be,\n+    #[payload]\n+    payload: Vec<u8>,\n+}\n+\n+/// Calculates the checksum of an ICMP packet\n+pub fn checksum(packet: &IcmpPacket) -> u16be {\n+    use packet::Packet;\n+\n+    let mut sum = 0u32;\n+    let mut i = 0;\n+    while i < packet.packet().len() {\n+        let word = (packet.packet()[i] as u32) << 8 | packet.packet()[i + 1] as u32;\n+        sum = sum + word;\n+        i = i + 2;\n+    }\n+    while sum >> 16 != 0 {\n+        sum = (sum >> 16) + (sum & 0xFFFF);\n+    }\n+\n+    !sum as u16\n+}\n+\n+/// Enumeration of the recognized ICMP types\n+#[allow(non_snake_case)]\n+#[allow(non_upper_case_globals)]\n+pub mod icmp_types {\n+\n+    use packet::icmp::IcmpType;\n+    /// ICMP type for \"echo reply\" packet\n+    pub const EchoReply: IcmpType = IcmpType(0);\n+    /// ICMP type for \"destination unreachable\" packet\n+    pub const DestinationUnreachable: IcmpType = IcmpType(3);\n+    /// ICMP type for \"source quench\" packet\n+    pub const SourceQuench: IcmpType = IcmpType(4);\n+    /// ICMP type for \"redirect message\" packet\n+    pub const RedirectMessage: IcmpType = IcmpType(5);\n+    /// ICMP type for \"echo request\" packet\n+    pub const EchoRequest: IcmpType = IcmpType(8);\n+    /// ICMP type for \"router advertisement\" packet\n+    pub const RouterAdvertisement: IcmpType = IcmpType(9);\n+    /// ICMP type for \"router solicitation\" packet\n+    pub const RouterSolicitation: IcmpType = IcmpType(10);\n+    /// ICMP type for \"time exceeded\" packet\n+    pub const TimeExceeded: IcmpType = IcmpType(11);\n+    /// ICMP type for \"parameter problem\" packet\n+    pub const ParameterProblem: IcmpType = IcmpType(12);\n+    /// ICMP type for \"timestamp\" packet\n+    pub const Timestamp: IcmpType = IcmpType(13);\n+    /// ICMP type for \"timestamp reply\" packet\n+    pub const TimestampReply: IcmpType = IcmpType(14);\n+    /// ICMP type for \"information request\" packet\n+    pub const InformationRequest: IcmpType = IcmpType(15);\n+    /// ICMP type for \"information reply\" packet\n+    pub const InformationReply: IcmpType = IcmpType(16);\n+    /// ICMP type for \"address mask request\" packet\n+    pub const AddressMaskRequest: IcmpType = IcmpType(17);\n+    /// ICMP type for \"address mask reply\" packet\n+    pub const AddressMaskReply: IcmpType = IcmpType(18);\n+    /// ICMP type for \"traceroute\" packet\n+    pub const Traceroute: IcmpType = IcmpType(30);\n+}\n+\n+\n+/// abstraction for ICMP echo reply packets\n+pub mod echo_reply {\n+    use packet::{Packet, PrimitiveValues};\n+    use packet::icmp::{IcmpCode, IcmpType};\n+    use pnet_macros_support::types::*;\n+\n+    /// Represent the \"identifier\" field of the ICMP echo replay header.\n+    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\n+    pub struct Identifier(pub u16);\n+\n+    impl Identifier {\n+        /// Create an identifier\n+        pub fn new(val: u16) -> Identifier {\n+            Identifier(val)\n+        }\n+    }\n+\n+    impl PrimitiveValues for Identifier {\n+        type T = (u16,);\n+        fn to_primitive_values(&self) -> (u16,) {\n+            (self.0,)\n+        }\n+    }\n+\n+    /// Represent the \"sequence number\" field of the ICMP echo replay header.\n+    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\n+    pub struct SequenceNumber(pub u16);\n+\n+    impl SequenceNumber {\n+        /// Create a sequence number\n+        pub fn new(val: u16) -> SequenceNumber {\n+            SequenceNumber(val)\n+        }\n+    }\n+\n+    impl PrimitiveValues for SequenceNumber {\n+        type T = (u16,);\n+        fn to_primitive_values(&self) -> (u16,) {\n+            (self.0,)\n+        }\n+    }\n+\n+    /// Enumeration of available ICMP codes for ICMP echo replay packets. There is actually only\n+    /// one, since the only valid ICMP code is 0.\n+    #[allow(non_snake_case)]\n+\t#[allow(non_upper_case_globals)]\n+    pub mod IcmpCodes {\n+        use packet::icmp::IcmpCode;\n+        /// 0 is the only available ICMP code for \"echo reply\" ICMP packets.\n+        pub const NoCode: IcmpCode = IcmpCode(0);\n+    }\n+\n+    /// Represents an ICMP echo reply packet.\n+    #[packet]\n+    pub struct EchoReply {\n+        #[construct_with(u8)]\n+        icmp_type: IcmpType,\n+        #[construct_with(u8)]\n+        icmp_code: IcmpCode,\n+        checksum: u16be,\n+        identifier: u16be,\n+        sequence_number: u16be,\n+        #[payload]\n+        payload: Vec<u8>,\n+    }\n+}\n+\n+/// abstraction for \"echo request\" ICMP packets.\n+pub mod echo_request {\n+    use packet::{Packet, PrimitiveValues};\n+    use packet::icmp::{IcmpCode, IcmpType};\n+    use pnet_macros_support::types::*;\n+\n+    /// Represents an indentifier field\n+    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\n+    pub struct Identifier(pub u16);\n+\n+    impl Identifier {\n+        /// Create an identifier\n+        pub fn new(val: u16) -> Identifier {\n+            Identifier(val)\n+        }\n+    }\n+\n+    impl PrimitiveValues for Identifier {\n+        type T = (u16,);\n+        fn to_primitive_values(&self) -> (u16,) {\n+            (self.0,)\n+        }\n+    }\n+\n+    /// Represents a sequence number field\n+    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\n+    pub struct SequenceNumber(pub u16);\n+\n+    impl SequenceNumber {\n+        /// Create a sequence number\n+        pub fn new(val: u16) -> SequenceNumber {\n+            SequenceNumber(val)\n+        }\n+    }\n+\n+    impl PrimitiveValues for SequenceNumber {\n+        type T = (u16,);\n+        fn to_primitive_values(&self) -> (u16,) {\n+            (self.0,)\n+        }\n+    }\n+\n+    /// Enumeration of available ICMP codes for \"echo reply\" ICMP packets. There is actually only\n+    /// one, since the only valid ICMP code is 0.\n+    #[allow(non_snake_case)]\n+\t#[allow(non_upper_case_globals)]\n+    pub mod IcmpCodes {\n+        use packet::icmp::IcmpCode;\n+        /// 0 is the only available ICMP code for \"echo reply\" ICMP packets.\n+        pub const NoCode: IcmpCode = IcmpCode(0);\n+    }\n+\n+    /// Represents an \"echo request\" ICMP packet.\n+    #[packet]\n+    pub struct EchoRequest {\n+        #[construct_with(u8)]\n+        icmp_type: IcmpType,\n+        #[construct_with(u8)]\n+        icmp_code: IcmpCode,\n+        checksum: u16be,\n+        identifier: u16be,\n+        sequence_number: u16be,\n+        #[payload]\n+        payload: Vec<u8>,\n+    }\n+\n+}\n+\n+/// abstraction for \"destination unreachable\" ICMP packets.\n+pub mod destination_unreachable {\n+    use packet::icmp::{IcmpCode, IcmpType};\n+    use pnet_macros_support::types::*;\n+\n+    /// Enumeration of the recognized ICMP codes for \"destination unreachable\" ICMP packets.\n+    #[allow(non_snake_case)]\n+\t#[allow(non_upper_case_globals)]\n+    pub mod IcmpCodes {\n+        use packet::icmp::IcmpCode;\n+        /// ICMP code for \"destination network unreachable\" packet\n+        pub const DestinationNetworkUnreachable: IcmpCode = IcmpCode(0);\n+        /// ICMP code for \"destination host unreachable\" packet\n+        pub const DestinationHostUnreachable: IcmpCode = IcmpCode(1);\n+        /// ICMP code for \"destination protocol unreachable\" packet\n+        pub const DestinationProtocolUnreachable: IcmpCode = IcmpCode(2);\n+        /// ICMP code for \"destination port unreachable\" packet\n+        pub const DestinationPortUnreachable: IcmpCode = IcmpCode(3);\n+        /// ICMP code for \"fragmentation required and DFF flag set\" packet\n+        pub const FragmentationRequiredAndDFFlagSet: IcmpCode = IcmpCode(4);\n+        /// ICMP code for \"source route failed\" packet\n+        pub const SourceRouteFailed: IcmpCode = IcmpCode(5);\n+        /// ICMP code for \"destination network unknown\" packet\n+        pub const DestinationNetworkUnknown: IcmpCode = IcmpCode(6);\n+        /// ICMP code for \"destination host unknown\" packet\n+        pub const DestinationHostUnknown: IcmpCode = IcmpCode(7);\n+        /// ICMP code for \"source host isolated\" packet\n+        pub const SourceHostIsolated: IcmpCode = IcmpCode(8);\n+        /// ICMP code for \"network administrative prohibited\" packet\n+        pub const NetworkAdministrativelyProhibited: IcmpCode = IcmpCode(9);\n+        /// ICMP code for \"host administrative prohibited\" packet\n+        pub const HostAdministrativelyProhibited: IcmpCode = IcmpCode(10);\n+        /// ICMP code for \"network unreachable for this Type Of Service\" packet\n+        pub const NetworkUnreachableForTOS: IcmpCode = IcmpCode(11);\n+        /// ICMP code for \"host unreachable for this Type Of Service\" packet\n+        pub const HostUnreachableForTOS: IcmpCode = IcmpCode(12);\n+        /// ICMP code for \"communication administratively prohibited\" packet\n+        pub const CommunicationAdministrativelyProhibited: IcmpCode = IcmpCode(13);\n+        /// ICMP code for \"host precedence violation\" packet\n+        pub const HostPrecedenceViolation: IcmpCode = IcmpCode(14);\n+        /// ICMP code for \"precedence cut off in effect\" packet\n+        pub const PrecedenceCutoffInEffect: IcmpCode = IcmpCode(15);\n+    }\n+\n+    /// Represents an \"echo request\" ICMP packet.\n+    #[packet]\n+    pub struct DestinationUnreachable {\n+        #[construct_with(u8)]\n+        icmp_type: IcmpType,\n+        #[construct_with(u8)]\n+        icmp_code: IcmpCode,\n+        checksum: u16be,\n+        unused: u32be,\n+        #[payload]\n+        payload: Vec<u8>,\n+    }\n+}\n+\n+#[test]\n+fn icmp_packet_test() {\n+    use packet::icmp::{IcmpType};\n+    use packet::icmp::{IcmpCode};\n+\n+    let mut packet = [0u8; 16];\n+    {\n+        let mut icmp_packet = MutableIcmpPacket::new(&mut packet[..]).unwrap();\n+\n+        icmp_packet.set_icmp_type(IcmpType(1));\n+        assert_eq!(icmp_packet.get_icmp_type().0, 1);\n+\n+        icmp_packet.set_icmp_code(IcmpCode(0x02));\n+        assert_eq!(icmp_packet.get_icmp_code().0, 0x02);\n+","path":"src/packet/icmp.rs","position":331,"original_position":331,"commit_id":"7bb450920014d714790fd31c6b57772457029223","original_commit_id":"7bb450920014d714790fd31c6b57772457029223","user":{"login":"mrmonday","id":165689,"avatar_url":"https://avatars.githubusercontent.com/u/165689?v=3","gravatar_id":"","url":"https://api.github.com/users/mrmonday","html_url":"https://github.com/mrmonday","followers_url":"https://api.github.com/users/mrmonday/followers","following_url":"https://api.github.com/users/mrmonday/following{/other_user}","gists_url":"https://api.github.com/users/mrmonday/gists{/gist_id}","starred_url":"https://api.github.com/users/mrmonday/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrmonday/subscriptions","organizations_url":"https://api.github.com/users/mrmonday/orgs","repos_url":"https://api.github.com/users/mrmonday/repos","events_url":"https://api.github.com/users/mrmonday/events{/privacy}","received_events_url":"https://api.github.com/users/mrmonday/received_events","type":"User","site_admin":false},"body":"Would it be possible to use IcmpTypes/IcmpCodes from the constants you declared above instead? It would be good to test on a \"real world\" packet which you might encounter in the wild, rather than one artificially constructed (obviously there'll be some amount of construction - it would be good to minimise it as much as possible though).","created_at":"2015-11-24T20:55:33Z","updated_at":"2015-11-24T20:55:33Z","html_url":"https://github.com/libpnet/libpnet/pull/89#discussion_r45793428","pull_request_url":"https://api.github.com/repos/libpnet/libpnet/pulls/89","_links":{"self":{"href":"https://api.github.com/repos/libpnet/libpnet/pulls/comments/45793428"},"html":{"href":"https://github.com/libpnet/libpnet/pull/89#discussion_r45793428"},"pull_request":{"href":"https://api.github.com/repos/libpnet/libpnet/pulls/89"}}},"pull_request":{"url":"https://api.github.com/repos/libpnet/libpnet/pulls/89","id":40295415,"html_url":"https://github.com/libpnet/libpnet/pull/89","diff_url":"https://github.com/libpnet/libpnet/pull/89.diff","patch_url":"https://github.com/libpnet/libpnet/pull/89.patch","issue_url":"https://api.github.com/repos/libpnet/libpnet/issues/89","number":89,"state":"open","locked":false,"title":"implement icmp packets","user":{"login":"little-dude","id":6646324,"avatar_url":"https://avatars.githubusercontent.com/u/6646324?v=3","gravatar_id":"","url":"https://api.github.com/users/little-dude","html_url":"https://github.com/little-dude","followers_url":"https://api.github.com/users/little-dude/followers","following_url":"https://api.github.com/users/little-dude/following{/other_user}","gists_url":"https://api.github.com/users/little-dude/gists{/gist_id}","starred_url":"https://api.github.com/users/little-dude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/little-dude/subscriptions","organizations_url":"https://api.github.com/users/little-dude/orgs","repos_url":"https://api.github.com/users/little-dude/repos","events_url":"https://api.github.com/users/little-dude/events{/privacy}","received_events_url":"https://api.github.com/users/little-dude/received_events","type":"User","site_admin":false},"body":"I'm making this a PR instead of an issue to make it easier to read.\r\n\r\nI'm trying to implement ICMP packets. It's far from begin complete, but I'd like to see if I can at least log an ICMP echo request using the `packetdump` example you provide.\r\n\r\nBut it does not compile because some getters are not created.\r\n\r\nI define a generic ICMP packet like this:\r\n\r\n```rust\r\n\r\n#[packet]                                                                           \r\npub struct Icmp {                                                                   \r\n    #[construct_with(u8)]                                                           \r\n    type_: IcmpType,  // get_type_() is not created (btw I'll come up with a better name, but \"type\" is reserved)\r\n    #[construct_with(u8)]                                                           \r\n    code: DestinationUnreachableCode,  // get_code_() is not created                                               \r\n    checksum: u16be,                                                                \r\n    rest_of_header: u32be,                                                          \r\n    #[payload]                                                                      \r\n    payload: Vec<u8> // Internet Header + 64 bits of Original Data Datagram         \r\n}   \r\n```                                                                                \r\n\r\nBut when I call `get_type_()` or `get_code()`:\r\n\r\n```\r\n~/libpnet git:icmptests ❯❯❯ sudo cargo run --example=packetdump lo                                                                                                                    \r\n   Compiling pnet v0.0.1 (file:///home/corentih/libpnet)\r\nexamples/packetdump.rs:64:16: 64:27 error: no method named `get_type_` found for type `core::option::Option<pnet::packet::icmp::IcmpPacket<'_>>` in the current scope\r\nexamples/packetdump.rs:64     match icmp.get_type_() {\r\n                                         ^~~~~~~~~~~\r\nexamples/packetdump.rs:68:52: 68:63 error: no method named `get_type_` found for type `core::option::Option<pnet::packet::icmp::IcmpPacket<'_>>` in the current scope\r\nexamples/packetdump.rs:68                                               icmp.get_type_())\r\n                                                                             ^~~~~~~~~~~\r\nnote: in expansion of format_args!\r\n<std macros>:2:25: 2:56 note: expansion site\r\n<std macros>:1:1: 2:62 note: in expansion of print!\r\n<std macros>:3:1: 3:54 note: expansion site\r\n<std macros>:1:1: 3:58 note: in expansion of println!\r\nexamples/packetdump.rs:66:38: 68:64 note: expansion site\r\nexamples/packetdump.rs:74:24: 74:34 error: no method named `get_code` found for type `core::option::Option<pnet::packet::icmp::IcmpEchoRequestPacket<'_>>` in the current scope\r\nexamples/packetdump.rs:74     match echo_request.get_code() {\r\n                                                 ^~~~~~~~~~\r\nexamples/packetdump.rs:75:109: 75:119 error: no method named `get_code` found for type `core::option::Option<pnet::packet::icmp::IcmpEchoRequestPacket<'_>>` in the current scope\r\nexamples/packetdump.rs:75         IcmpTypes::EchoRequest => println!(\"[{}]: ICMP echo request: code={}\", interface_name, echo_request.get_code()),\r\n                                                                                                                                      ^~~~~~~~~~\r\nnote: in expansion of format_args!\r\n<std macros>:2:25: 2:56 note: expansion site\r\n<std macros>:1:1: 2:62 note: in expansion of print!\r\n<std macros>:3:1: 3:54 note: expansion site\r\n<std macros>:1:1: 3:58 note: in expansion of println!\r\nexamples/packetdump.rs:75:35: 75:120 note: expansion site\r\nexamples/packetdump.rs:76:129: 76:139 error: no method named `get_code` found for type `core::option::Option<pnet::packet::icmp::IcmpEchoRequestPacket<'_>>` in the current scope\r\nexamples/packetdump.rs:76         _                         => println!(\"[{}]: Unknown ICMP echo request packet: (code={})\", interface_name, echo_request.get_code())\r\n                                                                                                                                                          ^~~~~~~~~~\r\nnote: in expansion of format_args!\r\n<std macros>:2:25: 2:56 note: expansion site\r\n<std macros>:1:1: 2:62 note: in expansion of print!\r\n<std macros>:3:1: 3:54 note: expansion site\r\n<std macros>:1:1: 3:58 note: in expansion of println!\r\nexamples/packetdump.rs:76:38: 76:140 note: expansion site\r\nerror: aborting due to 5 previous errors\r\nCould not compile `pnet`.\r\n```\r\n\r\nTwo questions:\r\n\r\n- Do you like the approach I take for the implementation, generally speaking? The way I write code at the moment is mostly driven by the errors the compiler throws me, and I have not idea if it's good or not\r\n- I can't figure out why the getters are not created, can you give me some pointers please?","created_at":"2015-07-18T17:21:46Z","updated_at":"2015-11-24T20:55:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cd9233a20f946b1ddfb7cc6edb5970559cac0b93","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/libpnet/libpnet/pulls/89/commits","review_comments_url":"https://api.github.com/repos/libpnet/libpnet/pulls/89/comments","review_comment_url":"https://api.github.com/repos/libpnet/libpnet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/libpnet/libpnet/issues/89/comments","statuses_url":"https://api.github.com/repos/libpnet/libpnet/statuses/7bb450920014d714790fd31c6b57772457029223","head":{"label":"little-dude:icmptests","ref":"icmptests","sha":"7bb450920014d714790fd31c6b57772457029223","user":{"login":"little-dude","id":6646324,"avatar_url":"https://avatars.githubusercontent.com/u/6646324?v=3","gravatar_id":"","url":"https://api.github.com/users/little-dude","html_url":"https://github.com/little-dude","followers_url":"https://api.github.com/users/little-dude/followers","following_url":"https://api.github.com/users/little-dude/following{/other_user}","gists_url":"https://api.github.com/users/little-dude/gists{/gist_id}","starred_url":"https://api.github.com/users/little-dude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/little-dude/subscriptions","organizations_url":"https://api.github.com/users/little-dude/orgs","repos_url":"https://api.github.com/users/little-dude/repos","events_url":"https://api.github.com/users/little-dude/events{/privacy}","received_events_url":"https://api.github.com/users/little-dude/received_events","type":"User","site_admin":false},"repo":{"id":28609505,"name":"libpnet","full_name":"little-dude/libpnet","owner":{"login":"little-dude","id":6646324,"avatar_url":"https://avatars.githubusercontent.com/u/6646324?v=3","gravatar_id":"","url":"https://api.github.com/users/little-dude","html_url":"https://github.com/little-dude","followers_url":"https://api.github.com/users/little-dude/followers","following_url":"https://api.github.com/users/little-dude/following{/other_user}","gists_url":"https://api.github.com/users/little-dude/gists{/gist_id}","starred_url":"https://api.github.com/users/little-dude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/little-dude/subscriptions","organizations_url":"https://api.github.com/users/little-dude/orgs","repos_url":"https://api.github.com/users/little-dude/repos","events_url":"https://api.github.com/users/little-dude/events{/privacy}","received_events_url":"https://api.github.com/users/little-dude/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/little-dude/libpnet","description":"Cross-platform, low level networking using the Rust programming language.","fork":true,"url":"https://api.github.com/repos/little-dude/libpnet","forks_url":"https://api.github.com/repos/little-dude/libpnet/forks","keys_url":"https://api.github.com/repos/little-dude/libpnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/little-dude/libpnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/little-dude/libpnet/teams","hooks_url":"https://api.github.com/repos/little-dude/libpnet/hooks","issue_events_url":"https://api.github.com/repos/little-dude/libpnet/issues/events{/number}","events_url":"https://api.github.com/repos/little-dude/libpnet/events","assignees_url":"https://api.github.com/repos/little-dude/libpnet/assignees{/user}","branches_url":"https://api.github.com/repos/little-dude/libpnet/branches{/branch}","tags_url":"https://api.github.com/repos/little-dude/libpnet/tags","blobs_url":"https://api.github.com/repos/little-dude/libpnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/little-dude/libpnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/little-dude/libpnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/little-dude/libpnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/little-dude/libpnet/statuses/{sha}","languages_url":"https://api.github.com/repos/little-dude/libpnet/languages","stargazers_url":"https://api.github.com/repos/little-dude/libpnet/stargazers","contributors_url":"https://api.github.com/repos/little-dude/libpnet/contributors","subscribers_url":"https://api.github.com/repos/little-dude/libpnet/subscribers","subscription_url":"https://api.github.com/repos/little-dude/libpnet/subscription","commits_url":"https://api.github.com/repos/little-dude/libpnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/little-dude/libpnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/little-dude/libpnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/little-dude/libpnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/little-dude/libpnet/contents/{+path}","compare_url":"https://api.github.com/repos/little-dude/libpnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/little-dude/libpnet/merges","archive_url":"https://api.github.com/repos/little-dude/libpnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/little-dude/libpnet/downloads","issues_url":"https://api.github.com/repos/little-dude/libpnet/issues{/number}","pulls_url":"https://api.github.com/repos/little-dude/libpnet/pulls{/number}","milestones_url":"https://api.github.com/repos/little-dude/libpnet/milestones{/number}","notifications_url":"https://api.github.com/repos/little-dude/libpnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/little-dude/libpnet/labels{/name}","releases_url":"https://api.github.com/repos/little-dude/libpnet/releases{/id}","created_at":"2014-12-29T22:58:56Z","updated_at":"2014-12-29T22:59:08Z","pushed_at":"2015-11-24T20:36:52Z","git_url":"git://github.com/little-dude/libpnet.git","ssh_url":"git@github.com:little-dude/libpnet.git","clone_url":"https://github.com/little-dude/libpnet.git","svn_url":"https://github.com/little-dude/libpnet","homepage":"","size":425,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"libpnet:master","ref":"master","sha":"c8bd15f33ec490f3b36d17df289ce472f80a41d5","user":{"login":"libpnet","id":8604237,"avatar_url":"https://avatars.githubusercontent.com/u/8604237?v=3","gravatar_id":"","url":"https://api.github.com/users/libpnet","html_url":"https://github.com/libpnet","followers_url":"https://api.github.com/users/libpnet/followers","following_url":"https://api.github.com/users/libpnet/following{/other_user}","gists_url":"https://api.github.com/users/libpnet/gists{/gist_id}","starred_url":"https://api.github.com/users/libpnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/libpnet/subscriptions","organizations_url":"https://api.github.com/users/libpnet/orgs","repos_url":"https://api.github.com/users/libpnet/repos","events_url":"https://api.github.com/users/libpnet/events{/privacy}","received_events_url":"https://api.github.com/users/libpnet/received_events","type":"Organization","site_admin":false},"repo":{"id":23515627,"name":"libpnet","full_name":"libpnet/libpnet","owner":{"login":"libpnet","id":8604237,"avatar_url":"https://avatars.githubusercontent.com/u/8604237?v=3","gravatar_id":"","url":"https://api.github.com/users/libpnet","html_url":"https://github.com/libpnet","followers_url":"https://api.github.com/users/libpnet/followers","following_url":"https://api.github.com/users/libpnet/following{/other_user}","gists_url":"https://api.github.com/users/libpnet/gists{/gist_id}","starred_url":"https://api.github.com/users/libpnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/libpnet/subscriptions","organizations_url":"https://api.github.com/users/libpnet/orgs","repos_url":"https://api.github.com/users/libpnet/repos","events_url":"https://api.github.com/users/libpnet/events{/privacy}","received_events_url":"https://api.github.com/users/libpnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/libpnet/libpnet","description":"Cross-platform, low level networking using the Rust programming language.","fork":false,"url":"https://api.github.com/repos/libpnet/libpnet","forks_url":"https://api.github.com/repos/libpnet/libpnet/forks","keys_url":"https://api.github.com/repos/libpnet/libpnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/libpnet/libpnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/libpnet/libpnet/teams","hooks_url":"https://api.github.com/repos/libpnet/libpnet/hooks","issue_events_url":"https://api.github.com/repos/libpnet/libpnet/issues/events{/number}","events_url":"https://api.github.com/repos/libpnet/libpnet/events","assignees_url":"https://api.github.com/repos/libpnet/libpnet/assignees{/user}","branches_url":"https://api.github.com/repos/libpnet/libpnet/branches{/branch}","tags_url":"https://api.github.com/repos/libpnet/libpnet/tags","blobs_url":"https://api.github.com/repos/libpnet/libpnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/libpnet/libpnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/libpnet/libpnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/libpnet/libpnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/libpnet/libpnet/statuses/{sha}","languages_url":"https://api.github.com/repos/libpnet/libpnet/languages","stargazers_url":"https://api.github.com/repos/libpnet/libpnet/stargazers","contributors_url":"https://api.github.com/repos/libpnet/libpnet/contributors","subscribers_url":"https://api.github.com/repos/libpnet/libpnet/subscribers","subscription_url":"https://api.github.com/repos/libpnet/libpnet/subscription","commits_url":"https://api.github.com/repos/libpnet/libpnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/libpnet/libpnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/libpnet/libpnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/libpnet/libpnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/libpnet/libpnet/contents/{+path}","compare_url":"https://api.github.com/repos/libpnet/libpnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/libpnet/libpnet/merges","archive_url":"https://api.github.com/repos/libpnet/libpnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/libpnet/libpnet/downloads","issues_url":"https://api.github.com/repos/libpnet/libpnet/issues{/number}","pulls_url":"https://api.github.com/repos/libpnet/libpnet/pulls{/number}","milestones_url":"https://api.github.com/repos/libpnet/libpnet/milestones{/number}","notifications_url":"https://api.github.com/repos/libpnet/libpnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/libpnet/libpnet/labels{/name}","releases_url":"https://api.github.com/repos/libpnet/libpnet/releases{/id}","created_at":"2014-08-31T14:44:47Z","updated_at":"2015-11-23T15:36:28Z","pushed_at":"2015-11-24T20:36:52Z","git_url":"git://github.com/libpnet/libpnet.git","ssh_url":"git@github.com:libpnet/libpnet.git","clone_url":"https://github.com/libpnet/libpnet.git","svn_url":"https://github.com/libpnet/libpnet","homepage":"","size":497,"stargazers_count":168,"watchers_count":168,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":33,"mirror_url":null,"open_issues_count":19,"forks":33,"open_issues":19,"watchers":168,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/libpnet/libpnet/pulls/89"},"html":{"href":"https://github.com/libpnet/libpnet/pull/89"},"issue":{"href":"https://api.github.com/repos/libpnet/libpnet/issues/89"},"comments":{"href":"https://api.github.com/repos/libpnet/libpnet/issues/89/comments"},"review_comments":{"href":"https://api.github.com/repos/libpnet/libpnet/pulls/89/comments"},"review_comment":{"href":"https://api.github.com/repos/libpnet/libpnet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/libpnet/libpnet/pulls/89/commits"},"statuses":{"href":"https://api.github.com/repos/libpnet/libpnet/statuses/7bb450920014d714790fd31c6b57772457029223"}}}}