@tcpip/wire 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});function c(e,t){let r=0;for(let n=0;n<e.length;n+=2)t&&n>=t&&n<t+2||(r+=e[n]<<8|e[n+1]);for(;r>>16;)r=(r&65535)+(r>>16);return~r&65535}function k(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(2);if(c(e,2)!==r)throw new Error("invalid icmp checksum");let n=O(t.getUint8(0)),s=S(n,t.getUint8(1)),o=t.getUint16(4),i=t.getUint16(6),a=e.subarray(8);return{type:n,code:s,identifier:o,sequenceNumber:i,payload:a}}function E(e){let t=new Uint8Array(8+e.payload.length),r=new DataView(t.buffer,t.byteOffset,t.byteLength);r.setUint8(0,$(e.type)),r.setUint8(1,C(e.type,e.code)),r.setUint16(4,e.identifier),r.setUint16(6,e.sequenceNumber),t.set(e.payload,8);let n=c(t,2);return r.setUint16(2,n),t}function O(e){switch(e){case 0:return"echo-reply";case 3:return"destination-unreachable";case 8:return"echo-request";case 11:return"time-exceeded";default:throw new Error("unknown icmp type")}}function $(e){switch(e){case"echo-reply":return 0;case"destination-unreachable":return 3;case"echo-request":return 8;case"time-exceeded":return 11;default:throw new Error("unknown icmp type")}}function S(e,t){switch(e){case"echo-reply":case"echo-request":switch(t){case 0:return;default:throw new Error("unknown icmp code")}case"destination-unreachable":switch(t){case 0:return"network-unreachable";case 1:return"host-unreachable";case 2:return"protocol-unreachable";default:throw new Error("unknown icmp code")}case"time-exceeded":switch(t){case 0:return"ttl-exceeded";case 1:return"fragment-reassembly-time-exceeded";default:throw new Error("unknown icmp code")}default:throw new Error("unknown icmp code")}}function C(e,t){switch(e){case"echo-reply":case"echo-request":switch(t){case void 0:return 0;default:throw new Error("unknown icmp code")}case"destination-unreachable":switch(t){case"network-unreachable":return 0;case"host-unreachable":return 1;case"protocol-unreachable":return 2;default:throw new Error("unknown icmp code")}case"time-exceeded":switch(t){case"ttl-exceeded":return 0;case"fragment-reassembly-time-exceeded":return 1;default:throw new Error("unknown icmp code")}default:throw new Error("unknown icmp code")}}var l=8;function M(e,t){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.subarray(0,l),s=r.getUint16(6);if(t){let d=new Uint8Array(t.length+e.length);if(d.set(t),d.set(e,t.length),c(d,t.length+6)!==s)throw new Error("invalid udp checksum")}else console.warn("no pseudo header provided: udp checksum verification skipped");let o=r.getUint16(4),i=e.subarray(8);if(o!==l+i.length)throw new Error("invalid udp length");let a=r.getUint16(0),u=r.getUint16(2);return{sourcePort:a,destinationPort:u,payload:i}}function z(e,t){let r=new Uint8Array(l+e.payload.length),n=new DataView(r.buffer,r.byteOffset,r.byteLength);if(n.setUint16(0,e.sourcePort),n.setUint16(2,e.destinationPort),n.setUint16(4,l+e.payload.length),n.setUint16(6,0),r.set(e.payload,8),t){let s=A(t),o=new Uint8Array(s.length+r.length);o.set(s),o.set(r,s.length);let i=c(o,s.length+6);n.setUint16(6,i)}else console.warn("no pseudo header provided: udp checksum calculation skipped (set to 0)");return r}var h=20;function D(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(10),n=e.subarray(0,h);if(c(n,10)!==r)throw new Error("invalid ipv4 checksum");if(t.getUint16(2)!==e.length)throw new Error("invalid ipv4 total length");let o=t.getUint8(0),i=o>>4,a=(o&15)*4,u=t.getUint8(1)>>2,d=t.getUint8(1)&3,I=t.getUint16(4),U=t.getUint8(6)>>5,v=(t.getUint8(6)&31)<<8|t.getUint8(7),x=t.getUint8(8),f=F(t.getUint8(9)),g=w(e.subarray(12,16)),P=w(e.subarray(16,20)),b=e.subarray(a);switch(f){case"icmp":return{version:i,dscp:u,ecn:d,identification:I,flags:U,fragmentOffset:v,ttl:x,protocol:f,sourceIP:g,destinationIP:P,payload:k(b)};case"tcp":return{version:i,dscp:u,ecn:d,identification:I,flags:U,fragmentOffset:v,ttl:x,protocol:f,sourceIP:g,destinationIP:P,payload:b};case"udp":return{version:i,dscp:u,ecn:d,identification:I,flags:U,fragmentOffset:v,ttl:x,protocol:f,sourceIP:g,destinationIP:P,payload:M(b,A({sourceIP:g,destinationIP:P,protocol:f,length:b.length}))};default:throw new Error("unknown ipv4 protocol")}}function V(e){let t;switch(e.protocol){case"icmp":t=E(e.payload);break;case"tcp":t=e.payload;break;case"udp":t=z(e.payload,{sourceIP:e.sourceIP,destinationIP:e.destinationIP,protocol:e.protocol,length:l+e.payload.payload.length});break;default:throw new Error("unknown ipv4 protocol")}let r=new Uint8Array(h+t.length),n=new DataView(r.buffer,r.byteOffset,r.byteLength),s=h+t.length;n.setUint8(0,e.version<<4|h/4),n.setUint8(1,e.dscp<<2|e.ecn),n.setUint16(2,s),n.setUint16(4,e.identification),n.setUint8(6,e.flags<<5|e.fragmentOffset>>8),n.setUint8(7,e.fragmentOffset&255),n.setUint8(8,e.ttl),n.setUint8(9,L(e.protocol)),r.set(p(e.sourceIP),12),r.set(p(e.destinationIP),16);let o=r.subarray(0,h),i=c(o,10);return n.setUint16(10,i),r.set(t,20),r}function w(e){return e.join(".")}function p(e){return new Uint8Array(e.split(".").map(t=>parseInt(t,10)))}function F(e){switch(e){case 1:return"icmp";case 6:return"tcp";case 17:return"udp";default:throw new Error("unknown ipv4 protocol")}}function L(e){switch(e){case"icmp":return 1;case"tcp":return 6;case"udp":return 17;default:throw new Error("unknown ipv4 protocol")}}function oe(e){let[t,r]=e.split("/");if(!t||!r)throw new Error("invalid cidr");let n=parseInt(r,10),s=N(n);return{ipAddress:p(t),netmask:s}}function N(e){let t=new Uint8Array(4);for(let r=0;r<e;r++){let n=Math.floor(r/8),s=7-r%8,o=t[n];if(o===void 0)throw new Error("invalid mask size");t[n]=o|1<<s}return t}function A(e){let t=new Uint8Array(12),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=p(e.sourceIP),s=p(e.destinationIP),o=L(e.protocol);return t.set(n,0),t.set(s,4),r.setUint8(8,0),r.setUint8(9,o),r.setUint16(10,e.length),t}function ce(e){let t=e.subarray(0,6),r=e.subarray(6,12),n=e.subarray(12,14),s=e.subarray(14),o=y(t),i=y(r),a=H(n);switch(a){case"ipv4":return{destinationMac:o,sourceMac:i,type:a,payload:D(s)};case"arp":return{destinationMac:o,sourceMac:i,type:a,payload:T(s)};default:throw new Error("unknown ethernet type")}}function pe(e){let t;switch(e.type){case"ipv4":t=V(e.payload);break;case"arp":t=B(e.payload);break;default:throw new Error("unknown ethernet type")}let r=new Uint8Array(14+t.length);return r.set(m(e.destinationMac),0),r.set(m(e.sourceMac),6),r.set(G(e.type),12),r.set(t,14),r}function y(e){if(e.length!==6)throw new Error("invalid mac address");return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join(":")}function m(e){let t=e.split(":");if(t.length!==6)throw new Error("invalid mac address");return new Uint8Array(t.map(r=>{let n=parseInt(r,16);if(Number.isNaN(n))throw new Error("invalid mac address");return n}))}function H(e){switch(new DataView(e.buffer,e.byteOffset,e.byteLength).getUint16(0)){case 2048:return"ipv4";case 34525:return"ipv6";case 2054:return"arp";default:throw new Error("unknown ethernet type")}}function G(e){let t=new Uint8Array(2),r=new DataView(t.buffer,t.byteOffset,t.byteLength);switch(e){case"ipv4":r.setUint16(0,2048);break;case"ipv6":r.setUint16(0,34525);break;case"arp":r.setUint16(0,2054);break;default:throw new Error("unknown ethernet type")}return t}function T(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=j(t.getUint16(0)),n=R(t.getUint16(2)),s=q(t.getUint16(6)),o=y(e.subarray(8,14)),i=w(e.subarray(14,18)),a=y(e.subarray(18,24)),u=w(e.subarray(24,28));return{hardwareType:r,protocolType:n,opcode:s,senderMac:o,senderIP:i,targetMac:a,targetIP:u}}function B(e){let t=new Uint8Array(28),r=new DataView(t.buffer,t.byteOffset,t.byteLength);return r.setUint16(0,_(e.hardwareType)),r.setUint16(2,Z(e.protocolType)),r.setUint8(4,6),r.setUint8(5,4),r.setUint16(6,J(e.opcode)),t.set(m(e.senderMac),8),t.set(p(e.senderIP),14),t.set(m(e.targetMac),18),t.set(p(e.targetIP),24),t}function j(e){switch(e){case 1:return"ethernet";default:throw new Error("unknown hardware type")}}function _(e){switch(e){case"ethernet":return 1;default:throw new Error("unknown hardware type")}}function R(e){switch(e){case 2048:return"ipv4";default:throw new Error("unknown protocol type")}}function Z(e){switch(e){case"ipv4":return 2048;default:throw new Error("unknown protocol type")}}function q(e){switch(e){case 1:return"request";case 2:return"reply";default:throw new Error("unknown opcode")}}function J(e){switch(e){case"request":return 1;case"reply":return 2;default:throw new Error("unknown opcode")}}function he(e){return e.reduce((t,r)=>t+r.toString(16).padStart(2,"0"),"").match(/.{1,4}/g).join(":")}function we(e){return new Uint8Array(e.split(":").flatMap(t=>{let r=parseInt(t,16);return[r>>8,r&255]}))}function ye(e){let r=e.toLowerCase().split(":").map(a=>a.replace(/^0+(?=\w)/,"")),n=-1,s=0,o=-1,i=0;for(let a=0;a<r.length;a++)r[a]==="0"||r[a]===""?(o===-1&&(o=a),i++,i>s&&(n=o,s=i)):(o=-1,i=0);return s>=2&&(r.splice(n,s),n===0?r.unshift("",""):n===r.length?r.push("",""):r.splice(n,0,"")),r.join(":")}function me(e){if(!e)throw new Error(`invalid IPv6 address: ${e}`);let t=e.split("::").map(a=>a.split(":"));if(t.length>2)throw new Error(`invalid IPv6 address: ${e}`);let[r,n]=t;if(!r)throw new Error(`invalid IPv6 address: ${e}`);if(!n)return r.map(a=>a.padStart(4,"0")).join(":");let o=8-(r.length+n.length),i=Array(o).fill("0000");return[...r,...i,...n].map(a=>a.padStart(4,"0")).join(":")}exports.IPV4_HEADER_LENGTH = h; exports.UDP_HEADER_LENGTH = l; exports.calculateChecksum = c; exports.compressIPv6 = ye; exports.expandIPv6 = me; exports.generateNetmask = N; exports.parseArpMessage = T; exports.parseEthernetFrame = ce; exports.parseEthernetType = H; exports.parseHardwareType = j; exports.parseIPv4Address = w; exports.parseIPv4Packet = D; exports.parseIPv4Protocol = F; exports.parseIPv6Address = he; exports.parseIcmpCode = S; exports.parseIcmpMessage = k; exports.parseIcmpType = O; exports.parseMacAddress = y; exports.parseOpcode = q; exports.parseProtocolType = R; exports.parseUdpDatagram = M; exports.serializeArpMessage = B; exports.serializeEthernetFrame = pe; exports.serializeEthernetType = G; exports.serializeHardwareType = _; exports.serializeIPv4Address = p; exports.serializeIPv4Cidr = oe; exports.serializeIPv4Packet = V; exports.serializeIPv4Protocol = L; exports.serializeIPv4PseudoHeader = A; exports.serializeIPv6Address = we; exports.serializeIcmpCode = C; exports.serializeIcmpMessage = E; exports.serializeIcmpType = $; exports.serializeMacAddress = m; exports.serializeOpcode = J; exports.serializeProtocolType = Z; exports.serializeUdpDatagram = z;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/util.ts","../src/icmp.ts","../src/udp.ts","../src/ipv4.ts","../src/ethernet.ts","../src/arp.ts","../src/ipv6.ts"],"names":["calculateChecksum","data","checksumOffset","sum","i","parseIcmpMessage","dataView","checksum","type","parseIcmpType","code","parseIcmpCode","identifier","sequenceNumber","payload","serializeIcmpMessage","message","serializeIcmpType","serializeIcmpCode","UDP_HEADER_LENGTH","parseUdpDatagram","pseudoHeader","header","checksumBuffer","length","sourcePort","destinationPort","serializeUdpDatagram","datagram","buffer","pseudoHeaderBuffer","serializeIPv4PseudoHeader","IPV4_HEADER_LENGTH","parseIPv4Packet","headerChecksum","versionAndHeaderLength","version","headerLength","dscp","ecn","identification","flags","fragmentOffset","ttl","protocol","parseIPv4Protocol","sourceIP","parseIPv4Address","destinationIP","serializeIPv4Packet","packet","totalLength","serializeIPv4Protocol","serializeIPv4Address","ip","byte","serializeIPv4Cidr","cidr","ipString","maskSizeString","maskSize","netmask","generateNetmask","mask","byteIndex","bitIndex","maskByte","sourceIPBuffer","destinationIPBuffer","protocolNumber","parseEthernetFrame","frame","destinationMacBytes","sourceMacBytes","typeBytes","destinationMac","parseMacAddress","sourceMac","parseEthernetType","parseArpMessage","serializeEthernetFrame","serializeArpMessage","serializeMacAddress","serializeEthernetType","mac","segments","parsed","etherType","hardwareType","parseHardwareType","protocolType","parseProtocolType","opcode","parseOpcode","senderMac","senderIP","targetMac","targetIP","request","serializeHardwareType","serializeProtocolType","serializeOpcode","parseIPv6Address","acc","serializeIPv6Address","n","num","compressIPv6","normalizedGroups","group","longestZeroStart","longestZeroLength","currentZeroStart","currentZeroLength","expandIPv6"],"mappings":"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","file":"/Users/grichardson/Documents/dev/tcpip.js/packages/wire/dist/index.cjs","sourcesContent":["/**\n * Calculates the internet checksum of an array of bytes.\n *\n * @param data - The data to calculate the checksum for.\n * @param checksumOffset - The offset of the checksum field in the data.\n */\nexport function calculateChecksum(\n data: Uint8Array,\n checksumOffset?: number\n): number {\n let sum = 0;\n\n // Sum all 16-bit words\n for (let i = 0; i < data.length; i += 2) {\n // Skip the checksum field if specified (16 bits)\n if (checksumOffset && i >= checksumOffset && i < checksumOffset + 2) {\n continue;\n }\n\n sum += (data[i]! << 8) | data[i + 1]!;\n }\n\n // Add the remaining byte if there is one\n while (sum >> 16) {\n sum = (sum & 0xffff) + (sum >> 16);\n }\n\n // Return the one's complement of the sum\n return ~sum & 0xffff;\n}\n","import { calculateChecksum } from './util.js';\n\nexport type IcmpMessage = {\n type: string;\n code?: string;\n identifier: number;\n sequenceNumber: number;\n payload: Uint8Array;\n};\n\n/**\n * Parses an ICMP message into an object.\n */\nexport function parseIcmpMessage(data: Uint8Array): IcmpMessage {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const checksum = dataView.getUint16(2);\n\n if (calculateChecksum(data, 2) !== checksum) {\n throw new Error('invalid icmp checksum');\n }\n\n const type = parseIcmpType(dataView.getUint8(0));\n const code = parseIcmpCode(type, dataView.getUint8(1));\n const identifier = dataView.getUint16(4);\n const sequenceNumber = dataView.getUint16(6);\n const payload = data.subarray(8);\n\n return {\n type,\n code,\n identifier,\n sequenceNumber,\n payload,\n };\n}\n\n/**\n * Serializes an ICMP message from an `ICMPMessage` object.\n */\nexport function serializeIcmpMessage(message: IcmpMessage): Uint8Array {\n const data = new Uint8Array(8 + message.payload.length);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n dataView.setUint8(0, serializeIcmpType(message.type));\n dataView.setUint8(1, serializeIcmpCode(message.type, message.code));\n dataView.setUint16(4, message.identifier);\n dataView.setUint16(6, message.sequenceNumber);\n data.set(message.payload, 8);\n\n // Checksum applies to both header and payload\n const checksum = calculateChecksum(data, 2);\n dataView.setUint16(2, checksum);\n\n return data;\n}\n\nexport function parseIcmpType(type: number) {\n switch (type) {\n case 0:\n return 'echo-reply';\n case 3:\n return 'destination-unreachable';\n case 8:\n return 'echo-request';\n case 11:\n return 'time-exceeded';\n default:\n throw new Error('unknown icmp type');\n }\n}\n\nexport function serializeIcmpType(type: string) {\n switch (type) {\n case 'echo-reply':\n return 0;\n case 'destination-unreachable':\n return 3;\n case 'echo-request':\n return 8;\n case 'time-exceeded':\n return 11;\n default:\n throw new Error('unknown icmp type');\n }\n}\n\nexport function parseIcmpCode(type: string, code: number) {\n switch (type) {\n case 'echo-reply':\n case 'echo-request': {\n switch (code) {\n case 0:\n return undefined;\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'destination-unreachable': {\n switch (code) {\n case 0:\n return 'network-unreachable';\n case 1:\n return 'host-unreachable';\n case 2:\n return 'protocol-unreachable';\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'time-exceeded':\n switch (code) {\n case 0:\n return 'ttl-exceeded';\n case 1:\n return 'fragment-reassembly-time-exceeded';\n default:\n throw new Error('unknown icmp code');\n }\n default:\n throw new Error('unknown icmp code');\n }\n}\n\nexport function serializeIcmpCode(type: string, code?: string) {\n switch (type) {\n case 'echo-reply':\n case 'echo-request': {\n switch (code) {\n case undefined:\n return 0;\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'destination-unreachable': {\n switch (code) {\n case 'network-unreachable':\n return 0;\n case 'host-unreachable':\n return 1;\n case 'protocol-unreachable':\n return 2;\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'time-exceeded':\n switch (code) {\n case 'ttl-exceeded':\n return 0;\n case 'fragment-reassembly-time-exceeded':\n return 1;\n default:\n throw new Error('unknown icmp code');\n }\n default:\n throw new Error('unknown icmp code');\n }\n}\n","import { serializeIPv4PseudoHeader, type IPv4PseudoHeader } from './ipv4.js';\nimport { calculateChecksum } from './util.js';\n\nexport type UdpDatagram = {\n sourcePort: number;\n destinationPort: number;\n payload: Uint8Array;\n};\n\nexport const UDP_HEADER_LENGTH = 8;\n\n/**\n * Parses a UDP datagram into an object.\n *\n * Optionally verifies the UDP checksum if an IP pseudo-header is provided\n * (required for UDP checksum verification).\n */\nexport function parseUdpDatagram(\n data: Uint8Array,\n pseudoHeader?: Uint8Array\n): UdpDatagram {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const header = data.subarray(0, UDP_HEADER_LENGTH);\n const checksum = dataView.getUint16(6);\n\n // If the IP packet is provided, verify the UDP checksum.\n if (pseudoHeader) {\n // Create buffer for checksum verification (pseudo-header + UDP header + payload)\n const checksumBuffer = new Uint8Array(pseudoHeader.length + data.length);\n checksumBuffer.set(pseudoHeader);\n checksumBuffer.set(data, pseudoHeader.length);\n\n if (\n calculateChecksum(checksumBuffer, pseudoHeader.length + 6) !== checksum\n ) {\n throw new Error('invalid udp checksum');\n }\n } else {\n console.warn(\n 'no pseudo header provided: udp checksum verification skipped'\n );\n }\n\n const length = dataView.getUint16(4);\n const payload = data.subarray(8);\n\n if (length !== UDP_HEADER_LENGTH + payload.length) {\n throw new Error('invalid udp length');\n }\n\n const sourcePort = dataView.getUint16(0);\n const destinationPort = dataView.getUint16(2);\n\n return {\n sourcePort,\n destinationPort,\n payload,\n };\n}\n\n/**\n * Serializes a UDP datagram object into a Uint8Array.\n *\n * Optionally calculates the UDP checksum if an IP pseudo-header is provided\n * (required for UDP checksum calculation).\n * If no IP pseudo-header is provided, the checksum field will be set to 0.\n */\nexport function serializeUdpDatagram(\n datagram: UdpDatagram,\n pseudoHeader?: IPv4PseudoHeader\n): Uint8Array {\n const buffer = new Uint8Array(UDP_HEADER_LENGTH + datagram.payload.length);\n const dataView = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n\n dataView.setUint16(0, datagram.sourcePort);\n dataView.setUint16(2, datagram.destinationPort);\n dataView.setUint16(4, UDP_HEADER_LENGTH + datagram.payload.length);\n dataView.setUint16(6, 0); // checksum\n buffer.set(datagram.payload, 8);\n\n if (pseudoHeader) {\n const pseudoHeaderBuffer = serializeIPv4PseudoHeader(pseudoHeader);\n\n // Create buffer for checksum verification (pseudo-header + UDP header + payload)\n const checksumBuffer = new Uint8Array(\n pseudoHeaderBuffer.length + buffer.length\n );\n checksumBuffer.set(pseudoHeaderBuffer);\n checksumBuffer.set(buffer, pseudoHeaderBuffer.length);\n\n const checksum = calculateChecksum(\n checksumBuffer,\n pseudoHeaderBuffer.length + 6\n );\n\n dataView.setUint16(6, checksum);\n } else {\n console.warn(\n 'no pseudo header provided: udp checksum calculation skipped (set to 0)'\n );\n }\n\n return buffer;\n}\n","import {\n serializeIcmpMessage,\n parseIcmpMessage,\n type IcmpMessage,\n} from './icmp.js';\nimport {\n serializeUdpDatagram,\n parseUdpDatagram,\n UDP_HEADER_LENGTH,\n type UdpDatagram,\n} from './udp.js';\nimport { calculateChecksum } from './util.js';\n\nexport type IPv4Address = `${number}.${number}.${number}.${number}`;\nexport type IPv4Cidr = `${IPv4Address}/${number}`;\n\nexport type IPv4PacketBase = {\n version: number;\n dscp: number;\n ecn: number;\n identification: number;\n flags: number;\n fragmentOffset: number;\n ttl: number;\n protocol: string;\n sourceIP: IPv4Address;\n destinationIP: IPv4Address;\n};\n\nexport type IcmpIPv4Packet = IPv4PacketBase & {\n protocol: 'icmp';\n payload: IcmpMessage;\n};\n\nexport type TcpIPv4Packet = IPv4PacketBase & {\n protocol: 'tcp';\n payload: Uint8Array;\n};\n\nexport type UdpIPv4Packet = IPv4PacketBase & {\n protocol: 'udp';\n payload: UdpDatagram;\n};\n\nexport type IPv4Packet = IcmpIPv4Packet | TcpIPv4Packet | UdpIPv4Packet;\n\nexport type IPv4Protocol = IPv4Packet['protocol'];\n\nexport type IPv4PseudoHeader = {\n sourceIP: IPv4Address;\n destinationIP: IPv4Address;\n protocol: IPv4Protocol;\n length: number;\n};\n\nexport const IPV4_HEADER_LENGTH = 20;\n\n/**\n * Parses an IPv4 packet into an object.\n */\nexport function parseIPv4Packet(data: Uint8Array): IPv4Packet {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const headerChecksum = dataView.getUint16(10);\n const header = data.subarray(0, IPV4_HEADER_LENGTH);\n\n if (calculateChecksum(header, 10) !== headerChecksum) {\n throw new Error('invalid ipv4 checksum');\n }\n\n const totalLength = dataView.getUint16(2);\n\n if (totalLength !== data.length) {\n throw new Error('invalid ipv4 total length');\n }\n\n const versionAndHeaderLength = dataView.getUint8(0);\n const version = versionAndHeaderLength >> 4;\n const headerLength = (versionAndHeaderLength & 0xf) * 4;\n const dscp = dataView.getUint8(1) >> 2;\n const ecn = dataView.getUint8(1) & 0x3;\n const identification = dataView.getUint16(4);\n const flags = dataView.getUint8(6) >> 5;\n const fragmentOffset =\n ((dataView.getUint8(6) & 0x1f) << 8) | dataView.getUint8(7);\n const ttl = dataView.getUint8(8);\n const protocol = parseIPv4Protocol(dataView.getUint8(9));\n const sourceIP = parseIPv4Address(data.subarray(12, 16));\n const destinationIP = parseIPv4Address(data.subarray(16, 20));\n const payload = data.subarray(headerLength);\n\n switch (protocol) {\n case 'icmp':\n return {\n version,\n dscp,\n ecn,\n identification,\n flags,\n fragmentOffset,\n ttl,\n protocol,\n sourceIP,\n destinationIP,\n payload: parseIcmpMessage(payload),\n };\n case 'tcp':\n return {\n version,\n dscp,\n ecn,\n identification,\n flags,\n fragmentOffset,\n ttl,\n protocol,\n sourceIP,\n destinationIP,\n payload,\n };\n case 'udp':\n return {\n version,\n dscp,\n ecn,\n identification,\n flags,\n fragmentOffset,\n ttl,\n protocol,\n sourceIP,\n destinationIP,\n payload: parseUdpDatagram(\n payload,\n serializeIPv4PseudoHeader({\n sourceIP,\n destinationIP,\n protocol,\n length: payload.length,\n })\n ),\n };\n default:\n throw new Error('unknown ipv4 protocol');\n }\n}\n\n/**\n * Serializes an IPv4 packet from an `IPv4Packet` object.\n */\nexport function serializeIPv4Packet(packet: IPv4Packet): Uint8Array {\n let payload: Uint8Array;\n\n switch (packet.protocol) {\n case 'icmp':\n payload = serializeIcmpMessage(packet.payload);\n break;\n case 'tcp':\n payload = packet.payload;\n break;\n case 'udp':\n payload = serializeUdpDatagram(packet.payload, {\n sourceIP: packet.sourceIP,\n destinationIP: packet.destinationIP,\n protocol: packet.protocol,\n length: UDP_HEADER_LENGTH + packet.payload.payload.length,\n });\n break;\n default:\n throw new Error('unknown ipv4 protocol');\n }\n\n const data = new Uint8Array(IPV4_HEADER_LENGTH + payload.length);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const totalLength = IPV4_HEADER_LENGTH + payload.length;\n\n dataView.setUint8(0, (packet.version << 4) | (IPV4_HEADER_LENGTH / 4));\n dataView.setUint8(1, (packet.dscp << 2) | packet.ecn);\n dataView.setUint16(2, totalLength);\n dataView.setUint16(4, packet.identification);\n dataView.setUint8(6, (packet.flags << 5) | (packet.fragmentOffset >> 8));\n dataView.setUint8(7, packet.fragmentOffset & 0xff);\n dataView.setUint8(8, packet.ttl);\n dataView.setUint8(9, serializeIPv4Protocol(packet.protocol));\n\n data.set(serializeIPv4Address(packet.sourceIP), 12);\n data.set(serializeIPv4Address(packet.destinationIP), 16);\n\n // Checksum applies to just the header\n const header = data.subarray(0, IPV4_HEADER_LENGTH);\n const checksum = calculateChecksum(header, 10);\n dataView.setUint16(10, checksum);\n\n data.set(payload, 20);\n\n return data;\n}\n\n/**\n * Parses an IPv4 address Uint8Array into a string.\n */\nexport function parseIPv4Address(data: Uint8Array) {\n return data.join('.') as IPv4Address;\n}\n\n/**\n * Serialize an IPv4 address string into a Uint8Array.\n */\nexport function serializeIPv4Address(ip: string) {\n return new Uint8Array(ip.split('.').map((byte) => parseInt(byte, 10)));\n}\n\nexport function parseIPv4Protocol(protocol: number) {\n switch (protocol) {\n case 1:\n return 'icmp';\n case 6:\n return 'tcp';\n case 17:\n return 'udp';\n default:\n throw new Error('unknown ipv4 protocol');\n }\n}\n\nexport function serializeIPv4Protocol(protocol: IPv4Protocol) {\n switch (protocol) {\n case 'icmp':\n return 1;\n case 'tcp':\n return 6;\n case 'udp':\n return 17;\n default:\n throw new Error('unknown ipv4 protocol');\n }\n}\n\n/**\n * Serialize a CIDR notation string into an object with a\n * Uint8Array IP address and netmask.\n */\nexport function serializeIPv4Cidr(cidr: IPv4Cidr) {\n const [ipString, maskSizeString] = cidr.split('/');\n\n if (!ipString || !maskSizeString) {\n throw new Error('invalid cidr');\n }\n\n const maskSize = parseInt(maskSizeString, 10);\n const netmask = generateNetmask(maskSize);\n\n return {\n ipAddress: serializeIPv4Address(ipString),\n netmask,\n };\n}\n\n/**\n * Generates a netmask from a mask size.\n */\nexport function generateNetmask(maskSize: number) {\n const mask = new Uint8Array(4);\n\n for (let i = 0; i < maskSize; i++) {\n const byteIndex = Math.floor(i / 8);\n const bitIndex = 7 - (i % 8);\n const maskByte = mask[byteIndex];\n if (maskByte === undefined) {\n throw new Error('invalid mask size');\n }\n mask[byteIndex] = maskByte | (1 << bitIndex);\n }\n\n return mask;\n}\n\n/**\n * Serializes a pseudo header for use in calculating transport layer checksums.\n */\nexport function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader) {\n const buffer = new Uint8Array(12);\n const dataView = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n\n const sourceIPBuffer = serializeIPv4Address(pseudoHeader.sourceIP);\n const destinationIPBuffer = serializeIPv4Address(pseudoHeader.destinationIP);\n const protocolNumber = serializeIPv4Protocol(pseudoHeader.protocol);\n\n buffer.set(sourceIPBuffer, 0);\n buffer.set(destinationIPBuffer, 4);\n dataView.setUint8(8, 0);\n dataView.setUint8(9, protocolNumber);\n dataView.setUint16(10, pseudoHeader.length);\n\n return buffer;\n}\n","import {\n serializeArpMessage,\n parseArpMessage,\n type ArpMessage,\n} from './arp.js';\nimport {\n serializeIPv4Packet,\n parseIPv4Packet,\n type IPv4Packet,\n} from './ipv4.js';\n\nexport type MacAddress =\n `${string}:${string}:${string}:${string}:${string}:${string}`;\n\nexport type EthernetFrameBase = {\n destinationMac: MacAddress;\n sourceMac: MacAddress;\n};\n\nexport type IPv4EthernetFrame = EthernetFrameBase & {\n type: 'ipv4';\n payload: IPv4Packet;\n};\n\nexport type ARPEthernetFrame = EthernetFrameBase & {\n type: 'arp';\n payload: ArpMessage;\n};\n\n// TODO: IPv6EthernetFrame\nexport type EthernetFrame = IPv4EthernetFrame | ARPEthernetFrame;\n\n/**\n * Parses an Ethernet frame into an object.\n */\nexport function parseEthernetFrame(frame: Uint8Array): EthernetFrame {\n const destinationMacBytes = frame.subarray(0, 6);\n const sourceMacBytes = frame.subarray(6, 12);\n const typeBytes = frame.subarray(12, 14);\n const payload = frame.subarray(14);\n\n const destinationMac = parseMacAddress(destinationMacBytes);\n const sourceMac = parseMacAddress(sourceMacBytes);\n const type = parseEthernetType(typeBytes);\n\n switch (type) {\n case 'ipv4':\n return {\n destinationMac,\n sourceMac,\n type,\n payload: parseIPv4Packet(payload),\n };\n case 'arp':\n return {\n destinationMac,\n sourceMac,\n type,\n payload: parseArpMessage(payload),\n };\n default:\n throw new Error('unknown ethernet type');\n }\n}\n\n/**\n * Serializes an Ethernet frame from a Frame object.\n */\nexport function serializeEthernetFrame(frame: EthernetFrame): Uint8Array {\n let payload: Uint8Array;\n\n switch (frame.type) {\n case 'ipv4':\n payload = serializeIPv4Packet(frame.payload);\n break;\n break;\n case 'arp':\n payload = serializeArpMessage(frame.payload);\n break;\n default:\n throw new Error('unknown ethernet type');\n }\n\n const data = new Uint8Array(14 + payload.length);\n\n data.set(serializeMacAddress(frame.destinationMac), 0);\n data.set(serializeMacAddress(frame.sourceMac), 6);\n data.set(serializeEthernetType(frame.type), 12);\n data.set(payload, 14);\n\n return data;\n}\n\n/**\n * Parses a MAC address Uint8Array into a string.\n */\nexport function parseMacAddress(mac: Uint8Array) {\n if (mac.length !== 6) {\n throw new Error('invalid mac address');\n }\n\n return Array.from(mac)\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join(':') as MacAddress;\n}\n\n/**\n * Serializes a MAC address string into a Uint8Array.\n */\nexport function serializeMacAddress(mac: string) {\n const segments = mac.split(':');\n\n if (segments.length !== 6) {\n throw new Error('invalid mac address');\n }\n\n return new Uint8Array(\n segments.map((byte) => {\n const parsed = parseInt(byte, 16);\n if (Number.isNaN(parsed)) {\n throw new Error('invalid mac address');\n }\n return parsed;\n })\n );\n}\n\n/**\n * Parses an Ethernet type into a string.\n */\nexport function parseEthernetType(etherType: Uint8Array) {\n const dataView = new DataView(\n etherType.buffer,\n etherType.byteOffset,\n etherType.byteLength\n );\n\n const type = dataView.getUint16(0);\n\n switch (type) {\n case 0x0800:\n return 'ipv4';\n case 0x86dd:\n return 'ipv6';\n case 0x0806:\n return 'arp';\n default:\n throw new Error('unknown ethernet type');\n }\n}\n\n/**\n * Serializes an Ethernet type from a string.\n */\nexport function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp') {\n const data = new Uint8Array(2);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n switch (type) {\n case 'ipv4':\n dataView.setUint16(0, 0x0800);\n break;\n case 'ipv6':\n dataView.setUint16(0, 0x86dd);\n break;\n case 'arp':\n dataView.setUint16(0, 0x0806);\n break;\n default:\n throw new Error('unknown ethernet type');\n }\n\n return data;\n}\n","import {\n parseMacAddress,\n serializeMacAddress,\n type MacAddress,\n} from './ethernet.js';\nimport {\n parseIPv4Address,\n serializeIPv4Address,\n type IPv4Address,\n} from './ipv4.js';\n\nexport type ArpMessage = {\n hardwareType: string;\n protocolType: string;\n opcode: string;\n senderMac: MacAddress;\n senderIP: IPv4Address;\n targetMac: MacAddress;\n targetIP: IPv4Address;\n};\n\n/**\n * Parses an ARP message packet into an object.\n */\nexport function parseArpMessage(data: Uint8Array): ArpMessage {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const hardwareType = parseHardwareType(dataView.getUint16(0));\n const protocolType = parseProtocolType(dataView.getUint16(2));\n const opcode = parseOpcode(dataView.getUint16(6));\n const senderMac = parseMacAddress(data.subarray(8, 14));\n const senderIP = parseIPv4Address(data.subarray(14, 18));\n const targetMac = parseMacAddress(data.subarray(18, 24));\n const targetIP = parseIPv4Address(data.subarray(24, 28));\n\n return {\n hardwareType,\n protocolType,\n opcode,\n senderMac,\n senderIP,\n targetMac,\n targetIP,\n };\n}\n\n/**\n * Serializes an ARP message packet from an `ArpMessage` object.\n */\nexport function serializeArpMessage(request: ArpMessage): Uint8Array {\n const data = new Uint8Array(28);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n dataView.setUint16(0, serializeHardwareType(request.hardwareType));\n dataView.setUint16(2, serializeProtocolType(request.protocolType));\n dataView.setUint8(4, 6);\n dataView.setUint8(5, 4);\n dataView.setUint16(6, serializeOpcode(request.opcode));\n data.set(serializeMacAddress(request.senderMac), 8);\n data.set(serializeIPv4Address(request.senderIP), 14);\n data.set(serializeMacAddress(request.targetMac), 18);\n data.set(serializeIPv4Address(request.targetIP), 24);\n\n return data;\n}\n\nexport function parseHardwareType(hardwareType: number) {\n switch (hardwareType) {\n case 1:\n return 'ethernet';\n default:\n throw new Error('unknown hardware type');\n }\n}\n\nexport function serializeHardwareType(hardwareType: string) {\n switch (hardwareType) {\n case 'ethernet':\n return 1;\n default:\n throw new Error('unknown hardware type');\n }\n}\n\nexport function parseProtocolType(protocolType: number) {\n switch (protocolType) {\n case 0x0800:\n return 'ipv4';\n default:\n throw new Error('unknown protocol type');\n }\n}\n\nexport function serializeProtocolType(protocolType: string) {\n switch (protocolType) {\n case 'ipv4':\n return 0x0800;\n default:\n throw new Error('unknown protocol type');\n }\n}\n\nexport function parseOpcode(opcode: number) {\n switch (opcode) {\n case 1:\n return 'request';\n case 2:\n return 'reply';\n default:\n throw new Error('unknown opcode');\n }\n}\n\nexport function serializeOpcode(opcode: string) {\n switch (opcode) {\n case 'request':\n return 1;\n case 'reply':\n return 2;\n default:\n throw new Error('unknown opcode');\n }\n}\n","/**\n * Parses an IPv6 address Uint8Array into a string.\n */\nexport function parseIPv6Address(data: Uint8Array) {\n return data\n .reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), '')\n .match(/.{1,4}/g)!\n .join(':');\n}\n\n/**\n * Serialize an IPv6 address string into a Uint8Array.\n */\nexport function serializeIPv6Address(ip: string) {\n return new Uint8Array(\n ip.split(':').flatMap((n) => {\n const num = parseInt(n, 16);\n return [num >> 8, num & 0xff];\n })\n );\n}\n\n/**\n * Compresses an IPv6 address by removing leading zeros.\n */\nexport function compressIPv6(ip: string) {\n // Split into groups and normalize to lowercase\n const groups = ip.toLowerCase().split(':');\n\n // Remove leading zeros from each group\n const normalizedGroups = groups.map(\n (group) => group.replace(/^0+(?=\\w)/, '') // Remove leading zeros, keep single 0\n );\n\n // Find longest sequence of empty groups\n let longestZeroStart = -1;\n let longestZeroLength = 0;\n let currentZeroStart = -1;\n let currentZeroLength = 0;\n\n for (let i = 0; i < normalizedGroups.length; i++) {\n if (normalizedGroups[i] === '0' || normalizedGroups[i] === '') {\n if (currentZeroStart === -1) currentZeroStart = i;\n currentZeroLength++;\n\n if (currentZeroLength > longestZeroLength) {\n longestZeroStart = currentZeroStart;\n longestZeroLength = currentZeroLength;\n }\n } else {\n currentZeroStart = -1;\n currentZeroLength = 0;\n }\n }\n\n // Replace longest zero sequence with :: if it's at least 2 groups long\n if (longestZeroLength >= 2) {\n // Clear out the zero sequence\n normalizedGroups.splice(longestZeroStart, longestZeroLength);\n\n // Insert empty string for :: compression\n if (longestZeroStart === 0) {\n // Leading zeros - ensure we have two colons at start\n normalizedGroups.unshift('', '');\n } else if (longestZeroStart === normalizedGroups.length) {\n // Trailing zeros - ensure we have two colons at end\n normalizedGroups.push('', '');\n } else {\n // Middle zeros - add empty string for ::\n normalizedGroups.splice(longestZeroStart, 0, '');\n }\n }\n\n return normalizedGroups.join(':');\n}\n\n/**\n * Expands an IPv6 address by adding leading zeros.\n */\nexport function expandIPv6(ip: string) {\n // Handle empty string edge case\n if (!ip) {\n throw new Error(`invalid IPv6 address: ${ip}`);\n }\n\n // Split on :: to handle compressed zeros\n const doubleColonSplit = ip.split('::').map((part) => part.split(':'));\n\n if (doubleColonSplit.length > 2) {\n throw new Error(`invalid IPv6 address: ${ip}`);\n }\n\n const [left, right] = doubleColonSplit;\n\n if (!left) {\n throw new Error(`invalid IPv6 address: ${ip}`);\n }\n\n // If no :: compression, just pad each group\n if (!right) {\n return left.map((group) => group.padStart(4, '0')).join(':');\n }\n\n // Calculate how many zero groups we need\n const totalGroups = 8;\n const missingGroups = totalGroups - (left.length + right.length);\n const zeros = Array(missingGroups).fill('0000');\n\n // Combine all parts and pad each group\n return [...left, ...zeros, ...right]\n .map((group) => group.padStart(4, '0'))\n .join(':');\n}\n"]}
@@ -0,0 +1,201 @@
1
+ type IcmpMessage = {
2
+ type: string;
3
+ code?: string;
4
+ identifier: number;
5
+ sequenceNumber: number;
6
+ payload: Uint8Array;
7
+ };
8
+ /**
9
+ * Parses an ICMP message into an object.
10
+ */
11
+ declare function parseIcmpMessage(data: Uint8Array): IcmpMessage;
12
+ /**
13
+ * Serializes an ICMP message from an `ICMPMessage` object.
14
+ */
15
+ declare function serializeIcmpMessage(message: IcmpMessage): Uint8Array;
16
+ declare function parseIcmpType(type: number): "echo-reply" | "destination-unreachable" | "echo-request" | "time-exceeded";
17
+ declare function serializeIcmpType(type: string): 0 | 8 | 3 | 11;
18
+ declare function parseIcmpCode(type: string, code: number): "network-unreachable" | "host-unreachable" | "protocol-unreachable" | "ttl-exceeded" | "fragment-reassembly-time-exceeded" | undefined;
19
+ declare function serializeIcmpCode(type: string, code?: string): 0 | 2 | 1;
20
+
21
+ type UdpDatagram = {
22
+ sourcePort: number;
23
+ destinationPort: number;
24
+ payload: Uint8Array;
25
+ };
26
+ declare const UDP_HEADER_LENGTH = 8;
27
+ /**
28
+ * Parses a UDP datagram into an object.
29
+ *
30
+ * Optionally verifies the UDP checksum if an IP pseudo-header is provided
31
+ * (required for UDP checksum verification).
32
+ */
33
+ declare function parseUdpDatagram(data: Uint8Array, pseudoHeader?: Uint8Array): UdpDatagram;
34
+ /**
35
+ * Serializes a UDP datagram object into a Uint8Array.
36
+ *
37
+ * Optionally calculates the UDP checksum if an IP pseudo-header is provided
38
+ * (required for UDP checksum calculation).
39
+ * If no IP pseudo-header is provided, the checksum field will be set to 0.
40
+ */
41
+ declare function serializeUdpDatagram(datagram: UdpDatagram, pseudoHeader?: IPv4PseudoHeader): Uint8Array;
42
+
43
+ type IPv4Address = `${number}.${number}.${number}.${number}`;
44
+ type IPv4Cidr = `${IPv4Address}/${number}`;
45
+ type IPv4PacketBase = {
46
+ version: number;
47
+ dscp: number;
48
+ ecn: number;
49
+ identification: number;
50
+ flags: number;
51
+ fragmentOffset: number;
52
+ ttl: number;
53
+ protocol: string;
54
+ sourceIP: IPv4Address;
55
+ destinationIP: IPv4Address;
56
+ };
57
+ type IcmpIPv4Packet = IPv4PacketBase & {
58
+ protocol: 'icmp';
59
+ payload: IcmpMessage;
60
+ };
61
+ type TcpIPv4Packet = IPv4PacketBase & {
62
+ protocol: 'tcp';
63
+ payload: Uint8Array;
64
+ };
65
+ type UdpIPv4Packet = IPv4PacketBase & {
66
+ protocol: 'udp';
67
+ payload: UdpDatagram;
68
+ };
69
+ type IPv4Packet = IcmpIPv4Packet | TcpIPv4Packet | UdpIPv4Packet;
70
+ type IPv4Protocol = IPv4Packet['protocol'];
71
+ type IPv4PseudoHeader = {
72
+ sourceIP: IPv4Address;
73
+ destinationIP: IPv4Address;
74
+ protocol: IPv4Protocol;
75
+ length: number;
76
+ };
77
+ declare const IPV4_HEADER_LENGTH = 20;
78
+ /**
79
+ * Parses an IPv4 packet into an object.
80
+ */
81
+ declare function parseIPv4Packet(data: Uint8Array): IPv4Packet;
82
+ /**
83
+ * Serializes an IPv4 packet from an `IPv4Packet` object.
84
+ */
85
+ declare function serializeIPv4Packet(packet: IPv4Packet): Uint8Array;
86
+ /**
87
+ * Parses an IPv4 address Uint8Array into a string.
88
+ */
89
+ declare function parseIPv4Address(data: Uint8Array): IPv4Address;
90
+ /**
91
+ * Serialize an IPv4 address string into a Uint8Array.
92
+ */
93
+ declare function serializeIPv4Address(ip: string): Uint8Array;
94
+ declare function parseIPv4Protocol(protocol: number): "icmp" | "tcp" | "udp";
95
+ declare function serializeIPv4Protocol(protocol: IPv4Protocol): 1 | 6 | 17;
96
+ /**
97
+ * Serialize a CIDR notation string into an object with a
98
+ * Uint8Array IP address and netmask.
99
+ */
100
+ declare function serializeIPv4Cidr(cidr: IPv4Cidr): {
101
+ ipAddress: Uint8Array;
102
+ netmask: Uint8Array;
103
+ };
104
+ /**
105
+ * Generates a netmask from a mask size.
106
+ */
107
+ declare function generateNetmask(maskSize: number): Uint8Array;
108
+ /**
109
+ * Serializes a pseudo header for use in calculating transport layer checksums.
110
+ */
111
+ declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array;
112
+
113
+ type MacAddress = `${string}:${string}:${string}:${string}:${string}:${string}`;
114
+ type EthernetFrameBase = {
115
+ destinationMac: MacAddress;
116
+ sourceMac: MacAddress;
117
+ };
118
+ type IPv4EthernetFrame = EthernetFrameBase & {
119
+ type: 'ipv4';
120
+ payload: IPv4Packet;
121
+ };
122
+ type ARPEthernetFrame = EthernetFrameBase & {
123
+ type: 'arp';
124
+ payload: ArpMessage;
125
+ };
126
+ type EthernetFrame = IPv4EthernetFrame | ARPEthernetFrame;
127
+ /**
128
+ * Parses an Ethernet frame into an object.
129
+ */
130
+ declare function parseEthernetFrame(frame: Uint8Array): EthernetFrame;
131
+ /**
132
+ * Serializes an Ethernet frame from a Frame object.
133
+ */
134
+ declare function serializeEthernetFrame(frame: EthernetFrame): Uint8Array;
135
+ /**
136
+ * Parses a MAC address Uint8Array into a string.
137
+ */
138
+ declare function parseMacAddress(mac: Uint8Array): MacAddress;
139
+ /**
140
+ * Serializes a MAC address string into a Uint8Array.
141
+ */
142
+ declare function serializeMacAddress(mac: string): Uint8Array;
143
+ /**
144
+ * Parses an Ethernet type into a string.
145
+ */
146
+ declare function parseEthernetType(etherType: Uint8Array): "ipv4" | "arp" | "ipv6";
147
+ /**
148
+ * Serializes an Ethernet type from a string.
149
+ */
150
+ declare function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp'): Uint8Array;
151
+
152
+ type ArpMessage = {
153
+ hardwareType: string;
154
+ protocolType: string;
155
+ opcode: string;
156
+ senderMac: MacAddress;
157
+ senderIP: IPv4Address;
158
+ targetMac: MacAddress;
159
+ targetIP: IPv4Address;
160
+ };
161
+ /**
162
+ * Parses an ARP message packet into an object.
163
+ */
164
+ declare function parseArpMessage(data: Uint8Array): ArpMessage;
165
+ /**
166
+ * Serializes an ARP message packet from an `ArpMessage` object.
167
+ */
168
+ declare function serializeArpMessage(request: ArpMessage): Uint8Array;
169
+ declare function parseHardwareType(hardwareType: number): string;
170
+ declare function serializeHardwareType(hardwareType: string): number;
171
+ declare function parseProtocolType(protocolType: number): string;
172
+ declare function serializeProtocolType(protocolType: string): number;
173
+ declare function parseOpcode(opcode: number): "request" | "reply";
174
+ declare function serializeOpcode(opcode: string): 2 | 1;
175
+
176
+ /**
177
+ * Parses an IPv6 address Uint8Array into a string.
178
+ */
179
+ declare function parseIPv6Address(data: Uint8Array): string;
180
+ /**
181
+ * Serialize an IPv6 address string into a Uint8Array.
182
+ */
183
+ declare function serializeIPv6Address(ip: string): Uint8Array;
184
+ /**
185
+ * Compresses an IPv6 address by removing leading zeros.
186
+ */
187
+ declare function compressIPv6(ip: string): string;
188
+ /**
189
+ * Expands an IPv6 address by adding leading zeros.
190
+ */
191
+ declare function expandIPv6(ip: string): string;
192
+
193
+ /**
194
+ * Calculates the internet checksum of an array of bytes.
195
+ *
196
+ * @param data - The data to calculate the checksum for.
197
+ * @param checksumOffset - The offset of the checksum field in the data.
198
+ */
199
+ declare function calculateChecksum(data: Uint8Array, checksumOffset?: number): number;
200
+
201
+ export { type ARPEthernetFrame, type ArpMessage, type EthernetFrame, type EthernetFrameBase, IPV4_HEADER_LENGTH, type IPv4Address, type IPv4Cidr, type IPv4EthernetFrame, type IPv4Packet, type IPv4PacketBase, type IPv4Protocol, type IPv4PseudoHeader, type IcmpIPv4Packet, type IcmpMessage, type MacAddress, type TcpIPv4Packet, UDP_HEADER_LENGTH, type UdpDatagram, type UdpIPv4Packet, calculateChecksum, compressIPv6, expandIPv6, generateNetmask, parseArpMessage, parseEthernetFrame, parseEthernetType, parseHardwareType, parseIPv4Address, parseIPv4Packet, parseIPv4Protocol, parseIPv6Address, parseIcmpCode, parseIcmpMessage, parseIcmpType, parseMacAddress, parseOpcode, parseProtocolType, parseUdpDatagram, serializeArpMessage, serializeEthernetFrame, serializeEthernetType, serializeHardwareType, serializeIPv4Address, serializeIPv4Cidr, serializeIPv4Packet, serializeIPv4Protocol, serializeIPv4PseudoHeader, serializeIPv6Address, serializeIcmpCode, serializeIcmpMessage, serializeIcmpType, serializeMacAddress, serializeOpcode, serializeProtocolType, serializeUdpDatagram };
@@ -0,0 +1,201 @@
1
+ type IcmpMessage = {
2
+ type: string;
3
+ code?: string;
4
+ identifier: number;
5
+ sequenceNumber: number;
6
+ payload: Uint8Array;
7
+ };
8
+ /**
9
+ * Parses an ICMP message into an object.
10
+ */
11
+ declare function parseIcmpMessage(data: Uint8Array): IcmpMessage;
12
+ /**
13
+ * Serializes an ICMP message from an `ICMPMessage` object.
14
+ */
15
+ declare function serializeIcmpMessage(message: IcmpMessage): Uint8Array;
16
+ declare function parseIcmpType(type: number): "echo-reply" | "destination-unreachable" | "echo-request" | "time-exceeded";
17
+ declare function serializeIcmpType(type: string): 0 | 8 | 3 | 11;
18
+ declare function parseIcmpCode(type: string, code: number): "network-unreachable" | "host-unreachable" | "protocol-unreachable" | "ttl-exceeded" | "fragment-reassembly-time-exceeded" | undefined;
19
+ declare function serializeIcmpCode(type: string, code?: string): 0 | 2 | 1;
20
+
21
+ type UdpDatagram = {
22
+ sourcePort: number;
23
+ destinationPort: number;
24
+ payload: Uint8Array;
25
+ };
26
+ declare const UDP_HEADER_LENGTH = 8;
27
+ /**
28
+ * Parses a UDP datagram into an object.
29
+ *
30
+ * Optionally verifies the UDP checksum if an IP pseudo-header is provided
31
+ * (required for UDP checksum verification).
32
+ */
33
+ declare function parseUdpDatagram(data: Uint8Array, pseudoHeader?: Uint8Array): UdpDatagram;
34
+ /**
35
+ * Serializes a UDP datagram object into a Uint8Array.
36
+ *
37
+ * Optionally calculates the UDP checksum if an IP pseudo-header is provided
38
+ * (required for UDP checksum calculation).
39
+ * If no IP pseudo-header is provided, the checksum field will be set to 0.
40
+ */
41
+ declare function serializeUdpDatagram(datagram: UdpDatagram, pseudoHeader?: IPv4PseudoHeader): Uint8Array;
42
+
43
+ type IPv4Address = `${number}.${number}.${number}.${number}`;
44
+ type IPv4Cidr = `${IPv4Address}/${number}`;
45
+ type IPv4PacketBase = {
46
+ version: number;
47
+ dscp: number;
48
+ ecn: number;
49
+ identification: number;
50
+ flags: number;
51
+ fragmentOffset: number;
52
+ ttl: number;
53
+ protocol: string;
54
+ sourceIP: IPv4Address;
55
+ destinationIP: IPv4Address;
56
+ };
57
+ type IcmpIPv4Packet = IPv4PacketBase & {
58
+ protocol: 'icmp';
59
+ payload: IcmpMessage;
60
+ };
61
+ type TcpIPv4Packet = IPv4PacketBase & {
62
+ protocol: 'tcp';
63
+ payload: Uint8Array;
64
+ };
65
+ type UdpIPv4Packet = IPv4PacketBase & {
66
+ protocol: 'udp';
67
+ payload: UdpDatagram;
68
+ };
69
+ type IPv4Packet = IcmpIPv4Packet | TcpIPv4Packet | UdpIPv4Packet;
70
+ type IPv4Protocol = IPv4Packet['protocol'];
71
+ type IPv4PseudoHeader = {
72
+ sourceIP: IPv4Address;
73
+ destinationIP: IPv4Address;
74
+ protocol: IPv4Protocol;
75
+ length: number;
76
+ };
77
+ declare const IPV4_HEADER_LENGTH = 20;
78
+ /**
79
+ * Parses an IPv4 packet into an object.
80
+ */
81
+ declare function parseIPv4Packet(data: Uint8Array): IPv4Packet;
82
+ /**
83
+ * Serializes an IPv4 packet from an `IPv4Packet` object.
84
+ */
85
+ declare function serializeIPv4Packet(packet: IPv4Packet): Uint8Array;
86
+ /**
87
+ * Parses an IPv4 address Uint8Array into a string.
88
+ */
89
+ declare function parseIPv4Address(data: Uint8Array): IPv4Address;
90
+ /**
91
+ * Serialize an IPv4 address string into a Uint8Array.
92
+ */
93
+ declare function serializeIPv4Address(ip: string): Uint8Array;
94
+ declare function parseIPv4Protocol(protocol: number): "icmp" | "tcp" | "udp";
95
+ declare function serializeIPv4Protocol(protocol: IPv4Protocol): 1 | 6 | 17;
96
+ /**
97
+ * Serialize a CIDR notation string into an object with a
98
+ * Uint8Array IP address and netmask.
99
+ */
100
+ declare function serializeIPv4Cidr(cidr: IPv4Cidr): {
101
+ ipAddress: Uint8Array;
102
+ netmask: Uint8Array;
103
+ };
104
+ /**
105
+ * Generates a netmask from a mask size.
106
+ */
107
+ declare function generateNetmask(maskSize: number): Uint8Array;
108
+ /**
109
+ * Serializes a pseudo header for use in calculating transport layer checksums.
110
+ */
111
+ declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array;
112
+
113
+ type MacAddress = `${string}:${string}:${string}:${string}:${string}:${string}`;
114
+ type EthernetFrameBase = {
115
+ destinationMac: MacAddress;
116
+ sourceMac: MacAddress;
117
+ };
118
+ type IPv4EthernetFrame = EthernetFrameBase & {
119
+ type: 'ipv4';
120
+ payload: IPv4Packet;
121
+ };
122
+ type ARPEthernetFrame = EthernetFrameBase & {
123
+ type: 'arp';
124
+ payload: ArpMessage;
125
+ };
126
+ type EthernetFrame = IPv4EthernetFrame | ARPEthernetFrame;
127
+ /**
128
+ * Parses an Ethernet frame into an object.
129
+ */
130
+ declare function parseEthernetFrame(frame: Uint8Array): EthernetFrame;
131
+ /**
132
+ * Serializes an Ethernet frame from a Frame object.
133
+ */
134
+ declare function serializeEthernetFrame(frame: EthernetFrame): Uint8Array;
135
+ /**
136
+ * Parses a MAC address Uint8Array into a string.
137
+ */
138
+ declare function parseMacAddress(mac: Uint8Array): MacAddress;
139
+ /**
140
+ * Serializes a MAC address string into a Uint8Array.
141
+ */
142
+ declare function serializeMacAddress(mac: string): Uint8Array;
143
+ /**
144
+ * Parses an Ethernet type into a string.
145
+ */
146
+ declare function parseEthernetType(etherType: Uint8Array): "ipv4" | "arp" | "ipv6";
147
+ /**
148
+ * Serializes an Ethernet type from a string.
149
+ */
150
+ declare function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp'): Uint8Array;
151
+
152
+ type ArpMessage = {
153
+ hardwareType: string;
154
+ protocolType: string;
155
+ opcode: string;
156
+ senderMac: MacAddress;
157
+ senderIP: IPv4Address;
158
+ targetMac: MacAddress;
159
+ targetIP: IPv4Address;
160
+ };
161
+ /**
162
+ * Parses an ARP message packet into an object.
163
+ */
164
+ declare function parseArpMessage(data: Uint8Array): ArpMessage;
165
+ /**
166
+ * Serializes an ARP message packet from an `ArpMessage` object.
167
+ */
168
+ declare function serializeArpMessage(request: ArpMessage): Uint8Array;
169
+ declare function parseHardwareType(hardwareType: number): string;
170
+ declare function serializeHardwareType(hardwareType: string): number;
171
+ declare function parseProtocolType(protocolType: number): string;
172
+ declare function serializeProtocolType(protocolType: string): number;
173
+ declare function parseOpcode(opcode: number): "request" | "reply";
174
+ declare function serializeOpcode(opcode: string): 2 | 1;
175
+
176
+ /**
177
+ * Parses an IPv6 address Uint8Array into a string.
178
+ */
179
+ declare function parseIPv6Address(data: Uint8Array): string;
180
+ /**
181
+ * Serialize an IPv6 address string into a Uint8Array.
182
+ */
183
+ declare function serializeIPv6Address(ip: string): Uint8Array;
184
+ /**
185
+ * Compresses an IPv6 address by removing leading zeros.
186
+ */
187
+ declare function compressIPv6(ip: string): string;
188
+ /**
189
+ * Expands an IPv6 address by adding leading zeros.
190
+ */
191
+ declare function expandIPv6(ip: string): string;
192
+
193
+ /**
194
+ * Calculates the internet checksum of an array of bytes.
195
+ *
196
+ * @param data - The data to calculate the checksum for.
197
+ * @param checksumOffset - The offset of the checksum field in the data.
198
+ */
199
+ declare function calculateChecksum(data: Uint8Array, checksumOffset?: number): number;
200
+
201
+ export { type ARPEthernetFrame, type ArpMessage, type EthernetFrame, type EthernetFrameBase, IPV4_HEADER_LENGTH, type IPv4Address, type IPv4Cidr, type IPv4EthernetFrame, type IPv4Packet, type IPv4PacketBase, type IPv4Protocol, type IPv4PseudoHeader, type IcmpIPv4Packet, type IcmpMessage, type MacAddress, type TcpIPv4Packet, UDP_HEADER_LENGTH, type UdpDatagram, type UdpIPv4Packet, calculateChecksum, compressIPv6, expandIPv6, generateNetmask, parseArpMessage, parseEthernetFrame, parseEthernetType, parseHardwareType, parseIPv4Address, parseIPv4Packet, parseIPv4Protocol, parseIPv6Address, parseIcmpCode, parseIcmpMessage, parseIcmpType, parseMacAddress, parseOpcode, parseProtocolType, parseUdpDatagram, serializeArpMessage, serializeEthernetFrame, serializeEthernetType, serializeHardwareType, serializeIPv4Address, serializeIPv4Cidr, serializeIPv4Packet, serializeIPv4Protocol, serializeIPv4PseudoHeader, serializeIPv6Address, serializeIcmpCode, serializeIcmpMessage, serializeIcmpType, serializeMacAddress, serializeOpcode, serializeProtocolType, serializeUdpDatagram };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ function c(e,t){let r=0;for(let n=0;n<e.length;n+=2)t&&n>=t&&n<t+2||(r+=e[n]<<8|e[n+1]);for(;r>>16;)r=(r&65535)+(r>>16);return~r&65535}function k(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(2);if(c(e,2)!==r)throw new Error("invalid icmp checksum");let n=O(t.getUint8(0)),s=S(n,t.getUint8(1)),o=t.getUint16(4),i=t.getUint16(6),a=e.subarray(8);return{type:n,code:s,identifier:o,sequenceNumber:i,payload:a}}function E(e){let t=new Uint8Array(8+e.payload.length),r=new DataView(t.buffer,t.byteOffset,t.byteLength);r.setUint8(0,$(e.type)),r.setUint8(1,C(e.type,e.code)),r.setUint16(4,e.identifier),r.setUint16(6,e.sequenceNumber),t.set(e.payload,8);let n=c(t,2);return r.setUint16(2,n),t}function O(e){switch(e){case 0:return"echo-reply";case 3:return"destination-unreachable";case 8:return"echo-request";case 11:return"time-exceeded";default:throw new Error("unknown icmp type")}}function $(e){switch(e){case"echo-reply":return 0;case"destination-unreachable":return 3;case"echo-request":return 8;case"time-exceeded":return 11;default:throw new Error("unknown icmp type")}}function S(e,t){switch(e){case"echo-reply":case"echo-request":switch(t){case 0:return;default:throw new Error("unknown icmp code")}case"destination-unreachable":switch(t){case 0:return"network-unreachable";case 1:return"host-unreachable";case 2:return"protocol-unreachable";default:throw new Error("unknown icmp code")}case"time-exceeded":switch(t){case 0:return"ttl-exceeded";case 1:return"fragment-reassembly-time-exceeded";default:throw new Error("unknown icmp code")}default:throw new Error("unknown icmp code")}}function C(e,t){switch(e){case"echo-reply":case"echo-request":switch(t){case void 0:return 0;default:throw new Error("unknown icmp code")}case"destination-unreachable":switch(t){case"network-unreachable":return 0;case"host-unreachable":return 1;case"protocol-unreachable":return 2;default:throw new Error("unknown icmp code")}case"time-exceeded":switch(t){case"ttl-exceeded":return 0;case"fragment-reassembly-time-exceeded":return 1;default:throw new Error("unknown icmp code")}default:throw new Error("unknown icmp code")}}var l=8;function M(e,t){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.subarray(0,l),s=r.getUint16(6);if(t){let d=new Uint8Array(t.length+e.length);if(d.set(t),d.set(e,t.length),c(d,t.length+6)!==s)throw new Error("invalid udp checksum")}else console.warn("no pseudo header provided: udp checksum verification skipped");let o=r.getUint16(4),i=e.subarray(8);if(o!==l+i.length)throw new Error("invalid udp length");let a=r.getUint16(0),u=r.getUint16(2);return{sourcePort:a,destinationPort:u,payload:i}}function z(e,t){let r=new Uint8Array(l+e.payload.length),n=new DataView(r.buffer,r.byteOffset,r.byteLength);if(n.setUint16(0,e.sourcePort),n.setUint16(2,e.destinationPort),n.setUint16(4,l+e.payload.length),n.setUint16(6,0),r.set(e.payload,8),t){let s=A(t),o=new Uint8Array(s.length+r.length);o.set(s),o.set(r,s.length);let i=c(o,s.length+6);n.setUint16(6,i)}else console.warn("no pseudo header provided: udp checksum calculation skipped (set to 0)");return r}var h=20;function D(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(10),n=e.subarray(0,h);if(c(n,10)!==r)throw new Error("invalid ipv4 checksum");if(t.getUint16(2)!==e.length)throw new Error("invalid ipv4 total length");let o=t.getUint8(0),i=o>>4,a=(o&15)*4,u=t.getUint8(1)>>2,d=t.getUint8(1)&3,I=t.getUint16(4),U=t.getUint8(6)>>5,v=(t.getUint8(6)&31)<<8|t.getUint8(7),x=t.getUint8(8),f=F(t.getUint8(9)),g=w(e.subarray(12,16)),P=w(e.subarray(16,20)),b=e.subarray(a);switch(f){case"icmp":return{version:i,dscp:u,ecn:d,identification:I,flags:U,fragmentOffset:v,ttl:x,protocol:f,sourceIP:g,destinationIP:P,payload:k(b)};case"tcp":return{version:i,dscp:u,ecn:d,identification:I,flags:U,fragmentOffset:v,ttl:x,protocol:f,sourceIP:g,destinationIP:P,payload:b};case"udp":return{version:i,dscp:u,ecn:d,identification:I,flags:U,fragmentOffset:v,ttl:x,protocol:f,sourceIP:g,destinationIP:P,payload:M(b,A({sourceIP:g,destinationIP:P,protocol:f,length:b.length}))};default:throw new Error("unknown ipv4 protocol")}}function V(e){let t;switch(e.protocol){case"icmp":t=E(e.payload);break;case"tcp":t=e.payload;break;case"udp":t=z(e.payload,{sourceIP:e.sourceIP,destinationIP:e.destinationIP,protocol:e.protocol,length:l+e.payload.payload.length});break;default:throw new Error("unknown ipv4 protocol")}let r=new Uint8Array(h+t.length),n=new DataView(r.buffer,r.byteOffset,r.byteLength),s=h+t.length;n.setUint8(0,e.version<<4|h/4),n.setUint8(1,e.dscp<<2|e.ecn),n.setUint16(2,s),n.setUint16(4,e.identification),n.setUint8(6,e.flags<<5|e.fragmentOffset>>8),n.setUint8(7,e.fragmentOffset&255),n.setUint8(8,e.ttl),n.setUint8(9,L(e.protocol)),r.set(p(e.sourceIP),12),r.set(p(e.destinationIP),16);let o=r.subarray(0,h),i=c(o,10);return n.setUint16(10,i),r.set(t,20),r}function w(e){return e.join(".")}function p(e){return new Uint8Array(e.split(".").map(t=>parseInt(t,10)))}function F(e){switch(e){case 1:return"icmp";case 6:return"tcp";case 17:return"udp";default:throw new Error("unknown ipv4 protocol")}}function L(e){switch(e){case"icmp":return 1;case"tcp":return 6;case"udp":return 17;default:throw new Error("unknown ipv4 protocol")}}function oe(e){let[t,r]=e.split("/");if(!t||!r)throw new Error("invalid cidr");let n=parseInt(r,10),s=N(n);return{ipAddress:p(t),netmask:s}}function N(e){let t=new Uint8Array(4);for(let r=0;r<e;r++){let n=Math.floor(r/8),s=7-r%8,o=t[n];if(o===void 0)throw new Error("invalid mask size");t[n]=o|1<<s}return t}function A(e){let t=new Uint8Array(12),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=p(e.sourceIP),s=p(e.destinationIP),o=L(e.protocol);return t.set(n,0),t.set(s,4),r.setUint8(8,0),r.setUint8(9,o),r.setUint16(10,e.length),t}function ce(e){let t=e.subarray(0,6),r=e.subarray(6,12),n=e.subarray(12,14),s=e.subarray(14),o=y(t),i=y(r),a=H(n);switch(a){case"ipv4":return{destinationMac:o,sourceMac:i,type:a,payload:D(s)};case"arp":return{destinationMac:o,sourceMac:i,type:a,payload:T(s)};default:throw new Error("unknown ethernet type")}}function pe(e){let t;switch(e.type){case"ipv4":t=V(e.payload);break;case"arp":t=B(e.payload);break;default:throw new Error("unknown ethernet type")}let r=new Uint8Array(14+t.length);return r.set(m(e.destinationMac),0),r.set(m(e.sourceMac),6),r.set(G(e.type),12),r.set(t,14),r}function y(e){if(e.length!==6)throw new Error("invalid mac address");return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join(":")}function m(e){let t=e.split(":");if(t.length!==6)throw new Error("invalid mac address");return new Uint8Array(t.map(r=>{let n=parseInt(r,16);if(Number.isNaN(n))throw new Error("invalid mac address");return n}))}function H(e){switch(new DataView(e.buffer,e.byteOffset,e.byteLength).getUint16(0)){case 2048:return"ipv4";case 34525:return"ipv6";case 2054:return"arp";default:throw new Error("unknown ethernet type")}}function G(e){let t=new Uint8Array(2),r=new DataView(t.buffer,t.byteOffset,t.byteLength);switch(e){case"ipv4":r.setUint16(0,2048);break;case"ipv6":r.setUint16(0,34525);break;case"arp":r.setUint16(0,2054);break;default:throw new Error("unknown ethernet type")}return t}function T(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=j(t.getUint16(0)),n=R(t.getUint16(2)),s=q(t.getUint16(6)),o=y(e.subarray(8,14)),i=w(e.subarray(14,18)),a=y(e.subarray(18,24)),u=w(e.subarray(24,28));return{hardwareType:r,protocolType:n,opcode:s,senderMac:o,senderIP:i,targetMac:a,targetIP:u}}function B(e){let t=new Uint8Array(28),r=new DataView(t.buffer,t.byteOffset,t.byteLength);return r.setUint16(0,_(e.hardwareType)),r.setUint16(2,Z(e.protocolType)),r.setUint8(4,6),r.setUint8(5,4),r.setUint16(6,J(e.opcode)),t.set(m(e.senderMac),8),t.set(p(e.senderIP),14),t.set(m(e.targetMac),18),t.set(p(e.targetIP),24),t}function j(e){switch(e){case 1:return"ethernet";default:throw new Error("unknown hardware type")}}function _(e){switch(e){case"ethernet":return 1;default:throw new Error("unknown hardware type")}}function R(e){switch(e){case 2048:return"ipv4";default:throw new Error("unknown protocol type")}}function Z(e){switch(e){case"ipv4":return 2048;default:throw new Error("unknown protocol type")}}function q(e){switch(e){case 1:return"request";case 2:return"reply";default:throw new Error("unknown opcode")}}function J(e){switch(e){case"request":return 1;case"reply":return 2;default:throw new Error("unknown opcode")}}function he(e){return e.reduce((t,r)=>t+r.toString(16).padStart(2,"0"),"").match(/.{1,4}/g).join(":")}function we(e){return new Uint8Array(e.split(":").flatMap(t=>{let r=parseInt(t,16);return[r>>8,r&255]}))}function ye(e){let r=e.toLowerCase().split(":").map(a=>a.replace(/^0+(?=\w)/,"")),n=-1,s=0,o=-1,i=0;for(let a=0;a<r.length;a++)r[a]==="0"||r[a]===""?(o===-1&&(o=a),i++,i>s&&(n=o,s=i)):(o=-1,i=0);return s>=2&&(r.splice(n,s),n===0?r.unshift("",""):n===r.length?r.push("",""):r.splice(n,0,"")),r.join(":")}function me(e){if(!e)throw new Error(`invalid IPv6 address: ${e}`);let t=e.split("::").map(a=>a.split(":"));if(t.length>2)throw new Error(`invalid IPv6 address: ${e}`);let[r,n]=t;if(!r)throw new Error(`invalid IPv6 address: ${e}`);if(!n)return r.map(a=>a.padStart(4,"0")).join(":");let o=8-(r.length+n.length),i=Array(o).fill("0000");return[...r,...i,...n].map(a=>a.padStart(4,"0")).join(":")}export{h as IPV4_HEADER_LENGTH,l as UDP_HEADER_LENGTH,c as calculateChecksum,ye as compressIPv6,me as expandIPv6,N as generateNetmask,T as parseArpMessage,ce as parseEthernetFrame,H as parseEthernetType,j as parseHardwareType,w as parseIPv4Address,D as parseIPv4Packet,F as parseIPv4Protocol,he as parseIPv6Address,S as parseIcmpCode,k as parseIcmpMessage,O as parseIcmpType,y as parseMacAddress,q as parseOpcode,R as parseProtocolType,M as parseUdpDatagram,B as serializeArpMessage,pe as serializeEthernetFrame,G as serializeEthernetType,_ as serializeHardwareType,p as serializeIPv4Address,oe as serializeIPv4Cidr,V as serializeIPv4Packet,L as serializeIPv4Protocol,A as serializeIPv4PseudoHeader,we as serializeIPv6Address,C as serializeIcmpCode,E as serializeIcmpMessage,$ as serializeIcmpType,m as serializeMacAddress,J as serializeOpcode,Z as serializeProtocolType,z as serializeUdpDatagram};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/util.ts","../src/icmp.ts","../src/udp.ts","../src/ipv4.ts","../src/ethernet.ts","../src/arp.ts","../src/ipv6.ts"],"sourcesContent":["/**\n * Calculates the internet checksum of an array of bytes.\n *\n * @param data - The data to calculate the checksum for.\n * @param checksumOffset - The offset of the checksum field in the data.\n */\nexport function calculateChecksum(\n data: Uint8Array,\n checksumOffset?: number\n): number {\n let sum = 0;\n\n // Sum all 16-bit words\n for (let i = 0; i < data.length; i += 2) {\n // Skip the checksum field if specified (16 bits)\n if (checksumOffset && i >= checksumOffset && i < checksumOffset + 2) {\n continue;\n }\n\n sum += (data[i]! << 8) | data[i + 1]!;\n }\n\n // Add the remaining byte if there is one\n while (sum >> 16) {\n sum = (sum & 0xffff) + (sum >> 16);\n }\n\n // Return the one's complement of the sum\n return ~sum & 0xffff;\n}\n","import { calculateChecksum } from './util.js';\n\nexport type IcmpMessage = {\n type: string;\n code?: string;\n identifier: number;\n sequenceNumber: number;\n payload: Uint8Array;\n};\n\n/**\n * Parses an ICMP message into an object.\n */\nexport function parseIcmpMessage(data: Uint8Array): IcmpMessage {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const checksum = dataView.getUint16(2);\n\n if (calculateChecksum(data, 2) !== checksum) {\n throw new Error('invalid icmp checksum');\n }\n\n const type = parseIcmpType(dataView.getUint8(0));\n const code = parseIcmpCode(type, dataView.getUint8(1));\n const identifier = dataView.getUint16(4);\n const sequenceNumber = dataView.getUint16(6);\n const payload = data.subarray(8);\n\n return {\n type,\n code,\n identifier,\n sequenceNumber,\n payload,\n };\n}\n\n/**\n * Serializes an ICMP message from an `ICMPMessage` object.\n */\nexport function serializeIcmpMessage(message: IcmpMessage): Uint8Array {\n const data = new Uint8Array(8 + message.payload.length);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n dataView.setUint8(0, serializeIcmpType(message.type));\n dataView.setUint8(1, serializeIcmpCode(message.type, message.code));\n dataView.setUint16(4, message.identifier);\n dataView.setUint16(6, message.sequenceNumber);\n data.set(message.payload, 8);\n\n // Checksum applies to both header and payload\n const checksum = calculateChecksum(data, 2);\n dataView.setUint16(2, checksum);\n\n return data;\n}\n\nexport function parseIcmpType(type: number) {\n switch (type) {\n case 0:\n return 'echo-reply';\n case 3:\n return 'destination-unreachable';\n case 8:\n return 'echo-request';\n case 11:\n return 'time-exceeded';\n default:\n throw new Error('unknown icmp type');\n }\n}\n\nexport function serializeIcmpType(type: string) {\n switch (type) {\n case 'echo-reply':\n return 0;\n case 'destination-unreachable':\n return 3;\n case 'echo-request':\n return 8;\n case 'time-exceeded':\n return 11;\n default:\n throw new Error('unknown icmp type');\n }\n}\n\nexport function parseIcmpCode(type: string, code: number) {\n switch (type) {\n case 'echo-reply':\n case 'echo-request': {\n switch (code) {\n case 0:\n return undefined;\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'destination-unreachable': {\n switch (code) {\n case 0:\n return 'network-unreachable';\n case 1:\n return 'host-unreachable';\n case 2:\n return 'protocol-unreachable';\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'time-exceeded':\n switch (code) {\n case 0:\n return 'ttl-exceeded';\n case 1:\n return 'fragment-reassembly-time-exceeded';\n default:\n throw new Error('unknown icmp code');\n }\n default:\n throw new Error('unknown icmp code');\n }\n}\n\nexport function serializeIcmpCode(type: string, code?: string) {\n switch (type) {\n case 'echo-reply':\n case 'echo-request': {\n switch (code) {\n case undefined:\n return 0;\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'destination-unreachable': {\n switch (code) {\n case 'network-unreachable':\n return 0;\n case 'host-unreachable':\n return 1;\n case 'protocol-unreachable':\n return 2;\n default:\n throw new Error('unknown icmp code');\n }\n }\n case 'time-exceeded':\n switch (code) {\n case 'ttl-exceeded':\n return 0;\n case 'fragment-reassembly-time-exceeded':\n return 1;\n default:\n throw new Error('unknown icmp code');\n }\n default:\n throw new Error('unknown icmp code');\n }\n}\n","import { serializeIPv4PseudoHeader, type IPv4PseudoHeader } from './ipv4.js';\nimport { calculateChecksum } from './util.js';\n\nexport type UdpDatagram = {\n sourcePort: number;\n destinationPort: number;\n payload: Uint8Array;\n};\n\nexport const UDP_HEADER_LENGTH = 8;\n\n/**\n * Parses a UDP datagram into an object.\n *\n * Optionally verifies the UDP checksum if an IP pseudo-header is provided\n * (required for UDP checksum verification).\n */\nexport function parseUdpDatagram(\n data: Uint8Array,\n pseudoHeader?: Uint8Array\n): UdpDatagram {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const header = data.subarray(0, UDP_HEADER_LENGTH);\n const checksum = dataView.getUint16(6);\n\n // If the IP packet is provided, verify the UDP checksum.\n if (pseudoHeader) {\n // Create buffer for checksum verification (pseudo-header + UDP header + payload)\n const checksumBuffer = new Uint8Array(pseudoHeader.length + data.length);\n checksumBuffer.set(pseudoHeader);\n checksumBuffer.set(data, pseudoHeader.length);\n\n if (\n calculateChecksum(checksumBuffer, pseudoHeader.length + 6) !== checksum\n ) {\n throw new Error('invalid udp checksum');\n }\n } else {\n console.warn(\n 'no pseudo header provided: udp checksum verification skipped'\n );\n }\n\n const length = dataView.getUint16(4);\n const payload = data.subarray(8);\n\n if (length !== UDP_HEADER_LENGTH + payload.length) {\n throw new Error('invalid udp length');\n }\n\n const sourcePort = dataView.getUint16(0);\n const destinationPort = dataView.getUint16(2);\n\n return {\n sourcePort,\n destinationPort,\n payload,\n };\n}\n\n/**\n * Serializes a UDP datagram object into a Uint8Array.\n *\n * Optionally calculates the UDP checksum if an IP pseudo-header is provided\n * (required for UDP checksum calculation).\n * If no IP pseudo-header is provided, the checksum field will be set to 0.\n */\nexport function serializeUdpDatagram(\n datagram: UdpDatagram,\n pseudoHeader?: IPv4PseudoHeader\n): Uint8Array {\n const buffer = new Uint8Array(UDP_HEADER_LENGTH + datagram.payload.length);\n const dataView = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n\n dataView.setUint16(0, datagram.sourcePort);\n dataView.setUint16(2, datagram.destinationPort);\n dataView.setUint16(4, UDP_HEADER_LENGTH + datagram.payload.length);\n dataView.setUint16(6, 0); // checksum\n buffer.set(datagram.payload, 8);\n\n if (pseudoHeader) {\n const pseudoHeaderBuffer = serializeIPv4PseudoHeader(pseudoHeader);\n\n // Create buffer for checksum verification (pseudo-header + UDP header + payload)\n const checksumBuffer = new Uint8Array(\n pseudoHeaderBuffer.length + buffer.length\n );\n checksumBuffer.set(pseudoHeaderBuffer);\n checksumBuffer.set(buffer, pseudoHeaderBuffer.length);\n\n const checksum = calculateChecksum(\n checksumBuffer,\n pseudoHeaderBuffer.length + 6\n );\n\n dataView.setUint16(6, checksum);\n } else {\n console.warn(\n 'no pseudo header provided: udp checksum calculation skipped (set to 0)'\n );\n }\n\n return buffer;\n}\n","import {\n serializeIcmpMessage,\n parseIcmpMessage,\n type IcmpMessage,\n} from './icmp.js';\nimport {\n serializeUdpDatagram,\n parseUdpDatagram,\n UDP_HEADER_LENGTH,\n type UdpDatagram,\n} from './udp.js';\nimport { calculateChecksum } from './util.js';\n\nexport type IPv4Address = `${number}.${number}.${number}.${number}`;\nexport type IPv4Cidr = `${IPv4Address}/${number}`;\n\nexport type IPv4PacketBase = {\n version: number;\n dscp: number;\n ecn: number;\n identification: number;\n flags: number;\n fragmentOffset: number;\n ttl: number;\n protocol: string;\n sourceIP: IPv4Address;\n destinationIP: IPv4Address;\n};\n\nexport type IcmpIPv4Packet = IPv4PacketBase & {\n protocol: 'icmp';\n payload: IcmpMessage;\n};\n\nexport type TcpIPv4Packet = IPv4PacketBase & {\n protocol: 'tcp';\n payload: Uint8Array;\n};\n\nexport type UdpIPv4Packet = IPv4PacketBase & {\n protocol: 'udp';\n payload: UdpDatagram;\n};\n\nexport type IPv4Packet = IcmpIPv4Packet | TcpIPv4Packet | UdpIPv4Packet;\n\nexport type IPv4Protocol = IPv4Packet['protocol'];\n\nexport type IPv4PseudoHeader = {\n sourceIP: IPv4Address;\n destinationIP: IPv4Address;\n protocol: IPv4Protocol;\n length: number;\n};\n\nexport const IPV4_HEADER_LENGTH = 20;\n\n/**\n * Parses an IPv4 packet into an object.\n */\nexport function parseIPv4Packet(data: Uint8Array): IPv4Packet {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const headerChecksum = dataView.getUint16(10);\n const header = data.subarray(0, IPV4_HEADER_LENGTH);\n\n if (calculateChecksum(header, 10) !== headerChecksum) {\n throw new Error('invalid ipv4 checksum');\n }\n\n const totalLength = dataView.getUint16(2);\n\n if (totalLength !== data.length) {\n throw new Error('invalid ipv4 total length');\n }\n\n const versionAndHeaderLength = dataView.getUint8(0);\n const version = versionAndHeaderLength >> 4;\n const headerLength = (versionAndHeaderLength & 0xf) * 4;\n const dscp = dataView.getUint8(1) >> 2;\n const ecn = dataView.getUint8(1) & 0x3;\n const identification = dataView.getUint16(4);\n const flags = dataView.getUint8(6) >> 5;\n const fragmentOffset =\n ((dataView.getUint8(6) & 0x1f) << 8) | dataView.getUint8(7);\n const ttl = dataView.getUint8(8);\n const protocol = parseIPv4Protocol(dataView.getUint8(9));\n const sourceIP = parseIPv4Address(data.subarray(12, 16));\n const destinationIP = parseIPv4Address(data.subarray(16, 20));\n const payload = data.subarray(headerLength);\n\n switch (protocol) {\n case 'icmp':\n return {\n version,\n dscp,\n ecn,\n identification,\n flags,\n fragmentOffset,\n ttl,\n protocol,\n sourceIP,\n destinationIP,\n payload: parseIcmpMessage(payload),\n };\n case 'tcp':\n return {\n version,\n dscp,\n ecn,\n identification,\n flags,\n fragmentOffset,\n ttl,\n protocol,\n sourceIP,\n destinationIP,\n payload,\n };\n case 'udp':\n return {\n version,\n dscp,\n ecn,\n identification,\n flags,\n fragmentOffset,\n ttl,\n protocol,\n sourceIP,\n destinationIP,\n payload: parseUdpDatagram(\n payload,\n serializeIPv4PseudoHeader({\n sourceIP,\n destinationIP,\n protocol,\n length: payload.length,\n })\n ),\n };\n default:\n throw new Error('unknown ipv4 protocol');\n }\n}\n\n/**\n * Serializes an IPv4 packet from an `IPv4Packet` object.\n */\nexport function serializeIPv4Packet(packet: IPv4Packet): Uint8Array {\n let payload: Uint8Array;\n\n switch (packet.protocol) {\n case 'icmp':\n payload = serializeIcmpMessage(packet.payload);\n break;\n case 'tcp':\n payload = packet.payload;\n break;\n case 'udp':\n payload = serializeUdpDatagram(packet.payload, {\n sourceIP: packet.sourceIP,\n destinationIP: packet.destinationIP,\n protocol: packet.protocol,\n length: UDP_HEADER_LENGTH + packet.payload.payload.length,\n });\n break;\n default:\n throw new Error('unknown ipv4 protocol');\n }\n\n const data = new Uint8Array(IPV4_HEADER_LENGTH + payload.length);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const totalLength = IPV4_HEADER_LENGTH + payload.length;\n\n dataView.setUint8(0, (packet.version << 4) | (IPV4_HEADER_LENGTH / 4));\n dataView.setUint8(1, (packet.dscp << 2) | packet.ecn);\n dataView.setUint16(2, totalLength);\n dataView.setUint16(4, packet.identification);\n dataView.setUint8(6, (packet.flags << 5) | (packet.fragmentOffset >> 8));\n dataView.setUint8(7, packet.fragmentOffset & 0xff);\n dataView.setUint8(8, packet.ttl);\n dataView.setUint8(9, serializeIPv4Protocol(packet.protocol));\n\n data.set(serializeIPv4Address(packet.sourceIP), 12);\n data.set(serializeIPv4Address(packet.destinationIP), 16);\n\n // Checksum applies to just the header\n const header = data.subarray(0, IPV4_HEADER_LENGTH);\n const checksum = calculateChecksum(header, 10);\n dataView.setUint16(10, checksum);\n\n data.set(payload, 20);\n\n return data;\n}\n\n/**\n * Parses an IPv4 address Uint8Array into a string.\n */\nexport function parseIPv4Address(data: Uint8Array) {\n return data.join('.') as IPv4Address;\n}\n\n/**\n * Serialize an IPv4 address string into a Uint8Array.\n */\nexport function serializeIPv4Address(ip: string) {\n return new Uint8Array(ip.split('.').map((byte) => parseInt(byte, 10)));\n}\n\nexport function parseIPv4Protocol(protocol: number) {\n switch (protocol) {\n case 1:\n return 'icmp';\n case 6:\n return 'tcp';\n case 17:\n return 'udp';\n default:\n throw new Error('unknown ipv4 protocol');\n }\n}\n\nexport function serializeIPv4Protocol(protocol: IPv4Protocol) {\n switch (protocol) {\n case 'icmp':\n return 1;\n case 'tcp':\n return 6;\n case 'udp':\n return 17;\n default:\n throw new Error('unknown ipv4 protocol');\n }\n}\n\n/**\n * Serialize a CIDR notation string into an object with a\n * Uint8Array IP address and netmask.\n */\nexport function serializeIPv4Cidr(cidr: IPv4Cidr) {\n const [ipString, maskSizeString] = cidr.split('/');\n\n if (!ipString || !maskSizeString) {\n throw new Error('invalid cidr');\n }\n\n const maskSize = parseInt(maskSizeString, 10);\n const netmask = generateNetmask(maskSize);\n\n return {\n ipAddress: serializeIPv4Address(ipString),\n netmask,\n };\n}\n\n/**\n * Generates a netmask from a mask size.\n */\nexport function generateNetmask(maskSize: number) {\n const mask = new Uint8Array(4);\n\n for (let i = 0; i < maskSize; i++) {\n const byteIndex = Math.floor(i / 8);\n const bitIndex = 7 - (i % 8);\n const maskByte = mask[byteIndex];\n if (maskByte === undefined) {\n throw new Error('invalid mask size');\n }\n mask[byteIndex] = maskByte | (1 << bitIndex);\n }\n\n return mask;\n}\n\n/**\n * Serializes a pseudo header for use in calculating transport layer checksums.\n */\nexport function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader) {\n const buffer = new Uint8Array(12);\n const dataView = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n\n const sourceIPBuffer = serializeIPv4Address(pseudoHeader.sourceIP);\n const destinationIPBuffer = serializeIPv4Address(pseudoHeader.destinationIP);\n const protocolNumber = serializeIPv4Protocol(pseudoHeader.protocol);\n\n buffer.set(sourceIPBuffer, 0);\n buffer.set(destinationIPBuffer, 4);\n dataView.setUint8(8, 0);\n dataView.setUint8(9, protocolNumber);\n dataView.setUint16(10, pseudoHeader.length);\n\n return buffer;\n}\n","import {\n serializeArpMessage,\n parseArpMessage,\n type ArpMessage,\n} from './arp.js';\nimport {\n serializeIPv4Packet,\n parseIPv4Packet,\n type IPv4Packet,\n} from './ipv4.js';\n\nexport type MacAddress =\n `${string}:${string}:${string}:${string}:${string}:${string}`;\n\nexport type EthernetFrameBase = {\n destinationMac: MacAddress;\n sourceMac: MacAddress;\n};\n\nexport type IPv4EthernetFrame = EthernetFrameBase & {\n type: 'ipv4';\n payload: IPv4Packet;\n};\n\nexport type ARPEthernetFrame = EthernetFrameBase & {\n type: 'arp';\n payload: ArpMessage;\n};\n\n// TODO: IPv6EthernetFrame\nexport type EthernetFrame = IPv4EthernetFrame | ARPEthernetFrame;\n\n/**\n * Parses an Ethernet frame into an object.\n */\nexport function parseEthernetFrame(frame: Uint8Array): EthernetFrame {\n const destinationMacBytes = frame.subarray(0, 6);\n const sourceMacBytes = frame.subarray(6, 12);\n const typeBytes = frame.subarray(12, 14);\n const payload = frame.subarray(14);\n\n const destinationMac = parseMacAddress(destinationMacBytes);\n const sourceMac = parseMacAddress(sourceMacBytes);\n const type = parseEthernetType(typeBytes);\n\n switch (type) {\n case 'ipv4':\n return {\n destinationMac,\n sourceMac,\n type,\n payload: parseIPv4Packet(payload),\n };\n case 'arp':\n return {\n destinationMac,\n sourceMac,\n type,\n payload: parseArpMessage(payload),\n };\n default:\n throw new Error('unknown ethernet type');\n }\n}\n\n/**\n * Serializes an Ethernet frame from a Frame object.\n */\nexport function serializeEthernetFrame(frame: EthernetFrame): Uint8Array {\n let payload: Uint8Array;\n\n switch (frame.type) {\n case 'ipv4':\n payload = serializeIPv4Packet(frame.payload);\n break;\n break;\n case 'arp':\n payload = serializeArpMessage(frame.payload);\n break;\n default:\n throw new Error('unknown ethernet type');\n }\n\n const data = new Uint8Array(14 + payload.length);\n\n data.set(serializeMacAddress(frame.destinationMac), 0);\n data.set(serializeMacAddress(frame.sourceMac), 6);\n data.set(serializeEthernetType(frame.type), 12);\n data.set(payload, 14);\n\n return data;\n}\n\n/**\n * Parses a MAC address Uint8Array into a string.\n */\nexport function parseMacAddress(mac: Uint8Array) {\n if (mac.length !== 6) {\n throw new Error('invalid mac address');\n }\n\n return Array.from(mac)\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join(':') as MacAddress;\n}\n\n/**\n * Serializes a MAC address string into a Uint8Array.\n */\nexport function serializeMacAddress(mac: string) {\n const segments = mac.split(':');\n\n if (segments.length !== 6) {\n throw new Error('invalid mac address');\n }\n\n return new Uint8Array(\n segments.map((byte) => {\n const parsed = parseInt(byte, 16);\n if (Number.isNaN(parsed)) {\n throw new Error('invalid mac address');\n }\n return parsed;\n })\n );\n}\n\n/**\n * Parses an Ethernet type into a string.\n */\nexport function parseEthernetType(etherType: Uint8Array) {\n const dataView = new DataView(\n etherType.buffer,\n etherType.byteOffset,\n etherType.byteLength\n );\n\n const type = dataView.getUint16(0);\n\n switch (type) {\n case 0x0800:\n return 'ipv4';\n case 0x86dd:\n return 'ipv6';\n case 0x0806:\n return 'arp';\n default:\n throw new Error('unknown ethernet type');\n }\n}\n\n/**\n * Serializes an Ethernet type from a string.\n */\nexport function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp') {\n const data = new Uint8Array(2);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n switch (type) {\n case 'ipv4':\n dataView.setUint16(0, 0x0800);\n break;\n case 'ipv6':\n dataView.setUint16(0, 0x86dd);\n break;\n case 'arp':\n dataView.setUint16(0, 0x0806);\n break;\n default:\n throw new Error('unknown ethernet type');\n }\n\n return data;\n}\n","import {\n parseMacAddress,\n serializeMacAddress,\n type MacAddress,\n} from './ethernet.js';\nimport {\n parseIPv4Address,\n serializeIPv4Address,\n type IPv4Address,\n} from './ipv4.js';\n\nexport type ArpMessage = {\n hardwareType: string;\n protocolType: string;\n opcode: string;\n senderMac: MacAddress;\n senderIP: IPv4Address;\n targetMac: MacAddress;\n targetIP: IPv4Address;\n};\n\n/**\n * Parses an ARP message packet into an object.\n */\nexport function parseArpMessage(data: Uint8Array): ArpMessage {\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const hardwareType = parseHardwareType(dataView.getUint16(0));\n const protocolType = parseProtocolType(dataView.getUint16(2));\n const opcode = parseOpcode(dataView.getUint16(6));\n const senderMac = parseMacAddress(data.subarray(8, 14));\n const senderIP = parseIPv4Address(data.subarray(14, 18));\n const targetMac = parseMacAddress(data.subarray(18, 24));\n const targetIP = parseIPv4Address(data.subarray(24, 28));\n\n return {\n hardwareType,\n protocolType,\n opcode,\n senderMac,\n senderIP,\n targetMac,\n targetIP,\n };\n}\n\n/**\n * Serializes an ARP message packet from an `ArpMessage` object.\n */\nexport function serializeArpMessage(request: ArpMessage): Uint8Array {\n const data = new Uint8Array(28);\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n dataView.setUint16(0, serializeHardwareType(request.hardwareType));\n dataView.setUint16(2, serializeProtocolType(request.protocolType));\n dataView.setUint8(4, 6);\n dataView.setUint8(5, 4);\n dataView.setUint16(6, serializeOpcode(request.opcode));\n data.set(serializeMacAddress(request.senderMac), 8);\n data.set(serializeIPv4Address(request.senderIP), 14);\n data.set(serializeMacAddress(request.targetMac), 18);\n data.set(serializeIPv4Address(request.targetIP), 24);\n\n return data;\n}\n\nexport function parseHardwareType(hardwareType: number) {\n switch (hardwareType) {\n case 1:\n return 'ethernet';\n default:\n throw new Error('unknown hardware type');\n }\n}\n\nexport function serializeHardwareType(hardwareType: string) {\n switch (hardwareType) {\n case 'ethernet':\n return 1;\n default:\n throw new Error('unknown hardware type');\n }\n}\n\nexport function parseProtocolType(protocolType: number) {\n switch (protocolType) {\n case 0x0800:\n return 'ipv4';\n default:\n throw new Error('unknown protocol type');\n }\n}\n\nexport function serializeProtocolType(protocolType: string) {\n switch (protocolType) {\n case 'ipv4':\n return 0x0800;\n default:\n throw new Error('unknown protocol type');\n }\n}\n\nexport function parseOpcode(opcode: number) {\n switch (opcode) {\n case 1:\n return 'request';\n case 2:\n return 'reply';\n default:\n throw new Error('unknown opcode');\n }\n}\n\nexport function serializeOpcode(opcode: string) {\n switch (opcode) {\n case 'request':\n return 1;\n case 'reply':\n return 2;\n default:\n throw new Error('unknown opcode');\n }\n}\n","/**\n * Parses an IPv6 address Uint8Array into a string.\n */\nexport function parseIPv6Address(data: Uint8Array) {\n return data\n .reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), '')\n .match(/.{1,4}/g)!\n .join(':');\n}\n\n/**\n * Serialize an IPv6 address string into a Uint8Array.\n */\nexport function serializeIPv6Address(ip: string) {\n return new Uint8Array(\n ip.split(':').flatMap((n) => {\n const num = parseInt(n, 16);\n return [num >> 8, num & 0xff];\n })\n );\n}\n\n/**\n * Compresses an IPv6 address by removing leading zeros.\n */\nexport function compressIPv6(ip: string) {\n // Split into groups and normalize to lowercase\n const groups = ip.toLowerCase().split(':');\n\n // Remove leading zeros from each group\n const normalizedGroups = groups.map(\n (group) => group.replace(/^0+(?=\\w)/, '') // Remove leading zeros, keep single 0\n );\n\n // Find longest sequence of empty groups\n let longestZeroStart = -1;\n let longestZeroLength = 0;\n let currentZeroStart = -1;\n let currentZeroLength = 0;\n\n for (let i = 0; i < normalizedGroups.length; i++) {\n if (normalizedGroups[i] === '0' || normalizedGroups[i] === '') {\n if (currentZeroStart === -1) currentZeroStart = i;\n currentZeroLength++;\n\n if (currentZeroLength > longestZeroLength) {\n longestZeroStart = currentZeroStart;\n longestZeroLength = currentZeroLength;\n }\n } else {\n currentZeroStart = -1;\n currentZeroLength = 0;\n }\n }\n\n // Replace longest zero sequence with :: if it's at least 2 groups long\n if (longestZeroLength >= 2) {\n // Clear out the zero sequence\n normalizedGroups.splice(longestZeroStart, longestZeroLength);\n\n // Insert empty string for :: compression\n if (longestZeroStart === 0) {\n // Leading zeros - ensure we have two colons at start\n normalizedGroups.unshift('', '');\n } else if (longestZeroStart === normalizedGroups.length) {\n // Trailing zeros - ensure we have two colons at end\n normalizedGroups.push('', '');\n } else {\n // Middle zeros - add empty string for ::\n normalizedGroups.splice(longestZeroStart, 0, '');\n }\n }\n\n return normalizedGroups.join(':');\n}\n\n/**\n * Expands an IPv6 address by adding leading zeros.\n */\nexport function expandIPv6(ip: string) {\n // Handle empty string edge case\n if (!ip) {\n throw new Error(`invalid IPv6 address: ${ip}`);\n }\n\n // Split on :: to handle compressed zeros\n const doubleColonSplit = ip.split('::').map((part) => part.split(':'));\n\n if (doubleColonSplit.length > 2) {\n throw new Error(`invalid IPv6 address: ${ip}`);\n }\n\n const [left, right] = doubleColonSplit;\n\n if (!left) {\n throw new Error(`invalid IPv6 address: ${ip}`);\n }\n\n // If no :: compression, just pad each group\n if (!right) {\n return left.map((group) => group.padStart(4, '0')).join(':');\n }\n\n // Calculate how many zero groups we need\n const totalGroups = 8;\n const missingGroups = totalGroups - (left.length + right.length);\n const zeros = Array(missingGroups).fill('0000');\n\n // Combine all parts and pad each group\n return [...left, ...zeros, ...right]\n .map((group) => group.padStart(4, '0'))\n .join(':');\n}\n"],"mappings":"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","names":["calculateChecksum","data","checksumOffset","sum","i","parseIcmpMessage","data","dataView","checksum","calculateChecksum","type","parseIcmpType","code","parseIcmpCode","identifier","sequenceNumber","payload","serializeIcmpMessage","message","serializeIcmpType","serializeIcmpCode","UDP_HEADER_LENGTH","parseUdpDatagram","data","pseudoHeader","dataView","header","checksum","checksumBuffer","calculateChecksum","length","payload","sourcePort","destinationPort","serializeUdpDatagram","datagram","buffer","pseudoHeaderBuffer","serializeIPv4PseudoHeader","IPV4_HEADER_LENGTH","parseIPv4Packet","data","dataView","headerChecksum","header","calculateChecksum","versionAndHeaderLength","version","headerLength","dscp","ecn","identification","flags","fragmentOffset","ttl","protocol","parseIPv4Protocol","sourceIP","parseIPv4Address","destinationIP","payload","parseIcmpMessage","parseUdpDatagram","serializeIPv4PseudoHeader","serializeIPv4Packet","packet","serializeIcmpMessage","serializeUdpDatagram","UDP_HEADER_LENGTH","totalLength","serializeIPv4Protocol","serializeIPv4Address","checksum","ip","byte","serializeIPv4Cidr","cidr","ipString","maskSizeString","maskSize","netmask","generateNetmask","mask","i","byteIndex","bitIndex","maskByte","pseudoHeader","buffer","sourceIPBuffer","destinationIPBuffer","protocolNumber","parseEthernetFrame","frame","destinationMacBytes","sourceMacBytes","typeBytes","payload","destinationMac","parseMacAddress","sourceMac","type","parseEthernetType","parseIPv4Packet","parseArpMessage","serializeEthernetFrame","serializeIPv4Packet","serializeArpMessage","data","serializeMacAddress","serializeEthernetType","mac","byte","segments","parsed","etherType","dataView","parseArpMessage","data","dataView","hardwareType","parseHardwareType","protocolType","parseProtocolType","opcode","parseOpcode","senderMac","parseMacAddress","senderIP","parseIPv4Address","targetMac","targetIP","serializeArpMessage","request","serializeHardwareType","serializeProtocolType","serializeOpcode","serializeMacAddress","serializeIPv4Address","parseIPv6Address","data","acc","byte","serializeIPv6Address","ip","n","num","compressIPv6","normalizedGroups","group","longestZeroStart","longestZeroLength","currentZeroStart","currentZeroLength","i","expandIPv6","doubleColonSplit","part","left","right","missingGroups","zeros"]}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@tcpip/wire",
3
+ "version": "0.1.0",
4
+ "description": "Wire protocol utilities for tcpip.js",
5
+ "main": "dist/index.cjs",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "tsup --clean",
10
+ "test": "vitest",
11
+ "prepublishOnly": "npm run build"
12
+ },
13
+ "files": [
14
+ "dist/**/*"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "import": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.cjs"
21
+ }
22
+ },
23
+ "dependencies": {},
24
+ "devDependencies": {
25
+ "@total-typescript/tsconfig": "^1.0.4",
26
+ "tcpip": "0.2",
27
+ "typescript": "^5.0.4",
28
+ "vitest": "^3.0.1"
29
+ }
30
+ }