@tcpip/wire 0.1.0 → 0.1.2
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 +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -2
- package/dist/index.d.ts +37 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
package/dist/index.cjs
CHANGED
|
@@ -1,2 +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;
|
|
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 E(e){if(e.length===0)throw new Error("empty string");let t=0;for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);if(n<48||n>57)throw new Error("invalid character");t=t*10+(n-48)}return t}function k(e){let t=0;for(let r=0;r<e.length;r++){let n=e.charCodeAt(r),o;if(n>=48&&n<=57)o=n-48;else if(n>=97&&n<=102)o=n-87;else if(n>=65&&n<=70)o=n-55;else throw new Error("invalid hex character");t=t<<4|o}return t}function M(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=C(t.getUint8(0)),o=F(n,t.getUint8(1)),s=t.getUint16(4),a=t.getUint16(6),i=e.subarray(8);return{type:n,code:o,identifier:s,sequenceNumber:a,payload:i}}function z(e){let t=new Uint8Array(8+e.payload.length),r=new DataView(t.buffer,t.byteOffset,t.byteLength);r.setUint8(0,S(e.type)),r.setUint8(1,N(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 C(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 S(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 F(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 N(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 D(e,t){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.subarray(0,l),o=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)!==o)throw new Error("invalid udp checksum")}else console.warn("no pseudo header provided: udp checksum verification skipped");let s=r.getUint16(4),a=e.subarray(8);if(s!==l+a.length)throw new Error("invalid udp length");let i=r.getUint16(0),u=r.getUint16(2);return{sourcePort:i,destinationPort:u,payload:a}}function V(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 o=A(t),s=new Uint8Array(o.length+r.length);s.set(o),s.set(r,o.length);let a=c(s,o.length+6);n.setUint16(6,a)}else console.warn("no pseudo header provided: udp checksum calculation skipped (set to 0)");return r}var h=20;function L(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 s=t.getUint8(0),a=s>>4,i=(s&15)*4,u=t.getUint8(1)>>2,d=t.getUint8(1)&3,b=t.getUint16(4),U=t.getUint8(6)>>5,x=(t.getUint8(6)&31)<<8|t.getUint8(7),I=t.getUint8(8),f=H(t.getUint8(9)),m=w(e.subarray(12,16)),P=w(e.subarray(16,20)),v=e.subarray(i);switch(f){case"icmp":return{version:a,dscp:u,ecn:d,identification:b,flags:U,fragmentOffset:x,ttl:I,protocol:f,sourceIP:m,destinationIP:P,payload:M(v)};case"tcp":return{version:a,dscp:u,ecn:d,identification:b,flags:U,fragmentOffset:x,ttl:I,protocol:f,sourceIP:m,destinationIP:P,payload:v};case"udp":return{version:a,dscp:u,ecn:d,identification:b,flags:U,fragmentOffset:x,ttl:I,protocol:f,sourceIP:m,destinationIP:P,payload:D(v,A({sourceIP:m,destinationIP:P,protocol:f,length:v.length}))};default:throw new Error("unknown ipv4 protocol")}}function $(e){let t;switch(e.protocol){case"icmp":t=z(e.payload);break;case"tcp":t=e.payload;break;case"udp":t=V(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),o=h+t.length;n.setUint8(0,e.version<<4|h/4),n.setUint8(1,e.dscp<<2|e.ecn),n.setUint16(2,o),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,B(e.protocol)),r.set(p(e.sourceIP),12),r.set(p(e.destinationIP),16);let s=r.subarray(0,h),a=c(s,10);return n.setUint16(10,a),r.set(t,20),r}function w(e){if(e.length!==4)throw new Error("invalid ipv4 address");return e.join(".")}function p(e){let t=e.split("."),r=new Uint8Array(4);if(t.length!==4)throw new Error("invalid ipv4 address");for(let n=0;n<4;n++){let o=t[n];if(o.length===0)throw new Error(`invalid ipv4 address: empty octet at position ${n}`);if(o.length>3)throw new Error(`invalid ipv4 address: octet too long at position ${n}`);let s=E(o);if(s>255)throw new Error(`invalid ipv4 address: octet too large at position ${n}`);r[n]=s}return r}function H(e){switch(e){case 1:return"icmp";case 6:return"tcp";case 17:return"udp";default:throw new Error("unknown ipv4 protocol")}}function B(e){switch(e){case"icmp":return 1;case"tcp":return 6;case"udp":return 17;default:throw new Error("unknown ipv4 protocol")}}function ie(e){let[t,r]=e.split("/");if(!t||!r)throw new Error("invalid cidr");let n=parseInt(r,10),o=G(n);return{ipAddress:p(t),netmask:o}}function G(e){let t=new Uint8Array(4);for(let r=0;r<e;r++){let n=Math.floor(r/8),o=7-r%8,s=t[n];if(s===void 0)throw new Error("invalid mask size");t[n]=s|1<<o}return t}function A(e){let t=new Uint8Array(12),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=p(e.sourceIP),o=p(e.destinationIP),s=B(e.protocol);return t.set(n,0),t.set(o,4),r.setUint8(8,0),r.setUint8(9,s),r.setUint16(10,e.length),t}function ce(e){let t=e[0]<<24|e[1]<<16|e[2]<<8|e[3];if(t===0)return 0;if(t===4294967295)return 32;if(t===4294967040)return 24;if(t===4294901760)return 16;if(t===4278190080)return 8;let r=0,n=2147483648;for(;n&t;)r++,n>>>=1;if(t&~(4294967295<<32-r))throw new Error("invalid netmask: non-contiguous bits");return r}function le(e){let t=e.subarray(0,6),r=e.subarray(6,12),n=e.subarray(12,14),o=e.subarray(14),s=y(t),a=y(r),i=j(n);switch(i){case"ipv4":return{destinationMac:s,sourceMac:a,type:i,payload:L(o)};case"arp":return{destinationMac:s,sourceMac:a,type:i,payload:T(o)};default:throw new Error("unknown ethernet type")}}function fe(e){let t;switch(e.type){case"ipv4":t=$(e.payload);break;case"arp":t=O(e.payload);break;default:throw new Error("unknown ethernet type")}let r=new Uint8Array(14+t.length);return r.set(g(e.destinationMac),0),r.set(g(e.sourceMac),6),r.set(R(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 g(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 he(){let e=new Uint8Array(6);return crypto.getRandomValues(e),e[0]=e[0]&252|2,e}function j(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 R(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=_(t.getUint16(0)),n=q(t.getUint16(2)),o=K(t.getUint16(6)),s=y(e.subarray(8,14)),a=w(e.subarray(14,18)),i=y(e.subarray(18,24)),u=w(e.subarray(24,28));return{hardwareType:r,protocolType:n,opcode:o,senderMac:s,senderIP:a,targetMac:i,targetIP:u}}function O(e){let t=new Uint8Array(28),r=new DataView(t.buffer,t.byteOffset,t.byteLength);return r.setUint16(0,Z(e.hardwareType)),r.setUint16(2,J(e.protocolType)),r.setUint8(4,6),r.setUint8(5,4),r.setUint16(6,Q(e.opcode)),t.set(g(e.senderMac),8),t.set(p(e.senderIP),14),t.set(g(e.targetMac),18),t.set(p(e.targetIP),24),t}function _(e){switch(e){case 1:return"ethernet";default:throw new Error("unknown hardware type")}}function Z(e){switch(e){case"ethernet":return 1;default:throw new Error("unknown hardware type")}}function q(e){switch(e){case 2048:return"ipv4";default:throw new Error("unknown protocol type")}}function J(e){switch(e){case"ipv4":return 2048;default:throw new Error("unknown protocol type")}}function K(e){switch(e){case 1:return"request";case 2:return"reply";default:throw new Error("unknown opcode")}}function Q(e){switch(e){case"request":return 1;case"reply":return 2;default:throw new Error("unknown opcode")}}function ve(e){if(e.length!==16)throw new Error("invalid ipv6 address");return e.reduce((t,r)=>t+r.toString(16).padStart(2,"0"),"").match(/.{1,4}/g).join(":")}function be(e){let r=W(e).split(":"),n=new Uint8Array(16);if(r.length!==8)throw new Error("invalid ipv6 address");for(let o=0;o<8;o++){let s=r[o];if(s.length===0)throw new Error(`invalid ipv6 address: empty group at position ${o}`);if(s.length>4)throw new Error(`invalid ipv6 address: group too long at position ${o}`);let a=k(s);if(a>65535)throw new Error(`invalid ipv6 address: group value too large at position ${o}`);n[o*2]=a>>8,n[o*2+1]=a&255}return n}function Ue(e){let r=e.toLowerCase().split(":").map(i=>i.replace(/^0+(?=\w)/,"")),n=-1,o=0,s=-1,a=0;for(let i=0;i<r.length;i++)r[i]==="0"||r[i]===""?(s===-1&&(s=i),a++,a>o&&(n=s,o=a)):(s=-1,a=0);return o>=2&&(r.splice(n,o),n===0?r.unshift("",""):n===r.length?r.push("",""):r.splice(n,0,"")),r.join(":")}function W(e){if(!e)throw new Error(`invalid IPv6 address: ${e}`);let t=e.split("::").map(i=>i.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(i=>i.padStart(4,"0")).join(":");let s=8-(r.length+n.length),a=Array(s).fill("0000");return[...r,...a,...n].map(i=>i.padStart(4,"0")).join(":")}exports.IPV4_HEADER_LENGTH = h; exports.UDP_HEADER_LENGTH = l; exports.calculateChecksum = c; exports.compressIPv6 = Ue; exports.expandIPv6 = W; exports.generateMacAddress = he; exports.generateNetmask = G; exports.getPrefixLength = ce; exports.parseArpMessage = T; exports.parseEthernetFrame = le; exports.parseEthernetType = j; exports.parseHardwareType = _; exports.parseHex = k; exports.parseIPv4Address = w; exports.parseIPv4Packet = L; exports.parseIPv4Protocol = H; exports.parseIPv6Address = ve; exports.parseIcmpCode = F; exports.parseIcmpMessage = M; exports.parseIcmpType = C; exports.parseMacAddress = y; exports.parseOpcode = K; exports.parseProtocolType = q; exports.parseUdpDatagram = D; exports.parseUint = E; exports.serializeArpMessage = O; exports.serializeEthernetFrame = fe; exports.serializeEthernetType = R; exports.serializeHardwareType = Z; exports.serializeIPv4Address = p; exports.serializeIPv4Cidr = ie; exports.serializeIPv4Packet = $; exports.serializeIPv4Protocol = B; exports.serializeIPv4PseudoHeader = A; exports.serializeIPv6Address = be; exports.serializeIcmpCode = N; exports.serializeIcmpMessage = z; exports.serializeIcmpType = S; exports.serializeMacAddress = g; exports.serializeOpcode = Q; exports.serializeProtocolType = J; exports.serializeUdpDatagram = V;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +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"]}
|
|
1
|
+
{"version":3,"sources":["../src/util.ts","../src/icmp.ts","../src/udp.ts","../src/ipv4.ts"],"names":["calculateChecksum","data","checksumOffset","sum","i","parseUint","str","value","char","parseHex","hex","digit","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","parts","bytes","part"],"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\n/**\n * Parses a string into an unsigned integer.\n *\n * Uses direct character code comparison instead of `parseInt`\n * for better performance and stricter validation.\n *\n * `parseInt` is too permissive and allows invalid input like\n * whitespace, signs, and decimals.\n *\n * Throws if invalid characters are encountered.\n */\nexport function parseUint(str: string): number {\n if (str.length === 0) {\n throw new Error('empty string');\n }\n\n let value = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n\n if (char < 48 || char > 57) {\n // 0-9\n throw new Error('invalid character');\n }\n\n value = value * 10 + (char - 48);\n }\n\n return value;\n}\n\n/**\n * Parses a hex string into a number.\n *\n * Uses direct character code comparison instead of `parseInt`\n * for better performance and stricter validation.\n *\n * `parseInt` is too permissive and allows invalid hex characters\n * to slip through.\n *\n * Throws if invalid hex characters are encountered.\n */\nexport function parseHex(hex: string): number {\n let value = 0;\n for (let i = 0; i < hex.length; i++) {\n const char = hex.charCodeAt(i);\n let digit: number;\n\n if (char >= 48 && char <= 57) {\n // 0-9\n digit = char - 48;\n } else if (char >= 97 && char <= 102) {\n // a-f\n digit = char - 87;\n } else if (char >= 65 && char <= 70) {\n // A-F\n digit = char - 55;\n } else {\n throw new Error('invalid hex character');\n }\n\n value = (value << 4) | digit;\n }\n\n return value;\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 parseIcmpMessage,\n serializeIcmpMessage,\n type IcmpMessage,\n} from './icmp.js';\nimport {\n parseUdpDatagram,\n serializeUdpDatagram,\n UDP_HEADER_LENGTH,\n type UdpDatagram,\n} from './udp.js';\nimport { calculateChecksum, parseUint } 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 if (data.length !== 4) {\n throw new Error('invalid ipv4 address');\n }\n\n return data.join('.') as IPv4Address;\n}\n\n/**\n * Serialize an IPv4 address string into a Uint8Array.\n */\nexport function serializeIPv4Address(ip: string): Uint8Array {\n const parts = ip.split('.');\n const bytes = new Uint8Array(4);\n\n if (parts.length !== 4) {\n throw new Error('invalid ipv4 address');\n }\n\n for (let i = 0; i < 4; i++) {\n const part = parts[i]!;\n\n // Length validation\n if (part.length === 0) {\n throw new Error(`invalid ipv4 address: empty octet at position ${i}`);\n }\n if (part.length > 3) {\n throw new Error(`invalid ipv4 address: octet too long at position ${i}`);\n }\n\n // Parse and range check\n const value = parseUint(part);\n if (value > 0xff) {\n throw new Error(`invalid ipv4 address: octet too large at position ${i}`);\n }\n bytes[i] = value;\n }\n\n return bytes;\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: string) {\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\n/**\n * Determines the CIDR prefix length from a netmask Uint8Array.\n */\nexport function getPrefixLength(netmask: Uint8Array): number {\n // Convert to a single 32-bit integer first\n const value =\n (netmask[0]! << 24) |\n (netmask[1]! << 16) |\n (netmask[2]! << 8) |\n netmask[3]!;\n\n // Fast paths for common netmask patterns\n if (value === 0) return 0;\n if (value === 0xffffffff) return 32;\n if (value === 0xffffff00) return 24;\n if (value === 0xffff0000) return 16;\n if (value === 0xff000000) return 8;\n\n // Count 1 bits from the left for other cases\n let count = 0;\n let testBit = 0x80000000;\n\n while (testBit & value) {\n count++;\n testBit >>>= 1;\n }\n\n // Validate contiguous bits\n if ((value & ~(0xffffffff << (32 - count))) !== 0) {\n throw new Error('invalid netmask: non-contiguous bits');\n }\n\n return count;\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -97,7 +97,7 @@ declare function serializeIPv4Protocol(protocol: IPv4Protocol): 1 | 6 | 17;
|
|
|
97
97
|
* Serialize a CIDR notation string into an object with a
|
|
98
98
|
* Uint8Array IP address and netmask.
|
|
99
99
|
*/
|
|
100
|
-
declare function serializeIPv4Cidr(cidr:
|
|
100
|
+
declare function serializeIPv4Cidr(cidr: string): {
|
|
101
101
|
ipAddress: Uint8Array;
|
|
102
102
|
netmask: Uint8Array;
|
|
103
103
|
};
|
|
@@ -109,6 +109,10 @@ declare function generateNetmask(maskSize: number): Uint8Array;
|
|
|
109
109
|
* Serializes a pseudo header for use in calculating transport layer checksums.
|
|
110
110
|
*/
|
|
111
111
|
declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array;
|
|
112
|
+
/**
|
|
113
|
+
* Determines the CIDR prefix length from a netmask Uint8Array.
|
|
114
|
+
*/
|
|
115
|
+
declare function getPrefixLength(netmask: Uint8Array): number;
|
|
112
116
|
|
|
113
117
|
type MacAddress = `${string}:${string}:${string}:${string}:${string}:${string}`;
|
|
114
118
|
type EthernetFrameBase = {
|
|
@@ -140,6 +144,13 @@ declare function parseMacAddress(mac: Uint8Array): MacAddress;
|
|
|
140
144
|
* Serializes a MAC address string into a Uint8Array.
|
|
141
145
|
*/
|
|
142
146
|
declare function serializeMacAddress(mac: string): Uint8Array;
|
|
147
|
+
/**
|
|
148
|
+
* Generates a random MAC address.
|
|
149
|
+
*
|
|
150
|
+
* The generated address is locally administered (so won't conflict
|
|
151
|
+
* with real devices) and unicast (so it can be used as a source address).
|
|
152
|
+
*/
|
|
153
|
+
declare function generateMacAddress(): Uint8Array;
|
|
143
154
|
/**
|
|
144
155
|
* Parses an Ethernet type into a string.
|
|
145
156
|
*/
|
|
@@ -197,5 +208,29 @@ declare function expandIPv6(ip: string): string;
|
|
|
197
208
|
* @param checksumOffset - The offset of the checksum field in the data.
|
|
198
209
|
*/
|
|
199
210
|
declare function calculateChecksum(data: Uint8Array, checksumOffset?: number): number;
|
|
211
|
+
/**
|
|
212
|
+
* Parses a string into an unsigned integer.
|
|
213
|
+
*
|
|
214
|
+
* Uses direct character code comparison instead of `parseInt`
|
|
215
|
+
* for better performance and stricter validation.
|
|
216
|
+
*
|
|
217
|
+
* `parseInt` is too permissive and allows invalid input like
|
|
218
|
+
* whitespace, signs, and decimals.
|
|
219
|
+
*
|
|
220
|
+
* Throws if invalid characters are encountered.
|
|
221
|
+
*/
|
|
222
|
+
declare function parseUint(str: string): number;
|
|
223
|
+
/**
|
|
224
|
+
* Parses a hex string into a number.
|
|
225
|
+
*
|
|
226
|
+
* Uses direct character code comparison instead of `parseInt`
|
|
227
|
+
* for better performance and stricter validation.
|
|
228
|
+
*
|
|
229
|
+
* `parseInt` is too permissive and allows invalid hex characters
|
|
230
|
+
* to slip through.
|
|
231
|
+
*
|
|
232
|
+
* Throws if invalid hex characters are encountered.
|
|
233
|
+
*/
|
|
234
|
+
declare function parseHex(hex: string): number;
|
|
200
235
|
|
|
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 };
|
|
236
|
+
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, generateMacAddress, generateNetmask, getPrefixLength, parseArpMessage, parseEthernetFrame, parseEthernetType, parseHardwareType, parseHex, parseIPv4Address, parseIPv4Packet, parseIPv4Protocol, parseIPv6Address, parseIcmpCode, parseIcmpMessage, parseIcmpType, parseMacAddress, parseOpcode, parseProtocolType, parseUdpDatagram, parseUint, serializeArpMessage, serializeEthernetFrame, serializeEthernetType, serializeHardwareType, serializeIPv4Address, serializeIPv4Cidr, serializeIPv4Packet, serializeIPv4Protocol, serializeIPv4PseudoHeader, serializeIPv6Address, serializeIcmpCode, serializeIcmpMessage, serializeIcmpType, serializeMacAddress, serializeOpcode, serializeProtocolType, serializeUdpDatagram };
|
package/dist/index.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ declare function serializeIPv4Protocol(protocol: IPv4Protocol): 1 | 6 | 17;
|
|
|
97
97
|
* Serialize a CIDR notation string into an object with a
|
|
98
98
|
* Uint8Array IP address and netmask.
|
|
99
99
|
*/
|
|
100
|
-
declare function serializeIPv4Cidr(cidr:
|
|
100
|
+
declare function serializeIPv4Cidr(cidr: string): {
|
|
101
101
|
ipAddress: Uint8Array;
|
|
102
102
|
netmask: Uint8Array;
|
|
103
103
|
};
|
|
@@ -109,6 +109,10 @@ declare function generateNetmask(maskSize: number): Uint8Array;
|
|
|
109
109
|
* Serializes a pseudo header for use in calculating transport layer checksums.
|
|
110
110
|
*/
|
|
111
111
|
declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array;
|
|
112
|
+
/**
|
|
113
|
+
* Determines the CIDR prefix length from a netmask Uint8Array.
|
|
114
|
+
*/
|
|
115
|
+
declare function getPrefixLength(netmask: Uint8Array): number;
|
|
112
116
|
|
|
113
117
|
type MacAddress = `${string}:${string}:${string}:${string}:${string}:${string}`;
|
|
114
118
|
type EthernetFrameBase = {
|
|
@@ -140,6 +144,13 @@ declare function parseMacAddress(mac: Uint8Array): MacAddress;
|
|
|
140
144
|
* Serializes a MAC address string into a Uint8Array.
|
|
141
145
|
*/
|
|
142
146
|
declare function serializeMacAddress(mac: string): Uint8Array;
|
|
147
|
+
/**
|
|
148
|
+
* Generates a random MAC address.
|
|
149
|
+
*
|
|
150
|
+
* The generated address is locally administered (so won't conflict
|
|
151
|
+
* with real devices) and unicast (so it can be used as a source address).
|
|
152
|
+
*/
|
|
153
|
+
declare function generateMacAddress(): Uint8Array;
|
|
143
154
|
/**
|
|
144
155
|
* Parses an Ethernet type into a string.
|
|
145
156
|
*/
|
|
@@ -197,5 +208,29 @@ declare function expandIPv6(ip: string): string;
|
|
|
197
208
|
* @param checksumOffset - The offset of the checksum field in the data.
|
|
198
209
|
*/
|
|
199
210
|
declare function calculateChecksum(data: Uint8Array, checksumOffset?: number): number;
|
|
211
|
+
/**
|
|
212
|
+
* Parses a string into an unsigned integer.
|
|
213
|
+
*
|
|
214
|
+
* Uses direct character code comparison instead of `parseInt`
|
|
215
|
+
* for better performance and stricter validation.
|
|
216
|
+
*
|
|
217
|
+
* `parseInt` is too permissive and allows invalid input like
|
|
218
|
+
* whitespace, signs, and decimals.
|
|
219
|
+
*
|
|
220
|
+
* Throws if invalid characters are encountered.
|
|
221
|
+
*/
|
|
222
|
+
declare function parseUint(str: string): number;
|
|
223
|
+
/**
|
|
224
|
+
* Parses a hex string into a number.
|
|
225
|
+
*
|
|
226
|
+
* Uses direct character code comparison instead of `parseInt`
|
|
227
|
+
* for better performance and stricter validation.
|
|
228
|
+
*
|
|
229
|
+
* `parseInt` is too permissive and allows invalid hex characters
|
|
230
|
+
* to slip through.
|
|
231
|
+
*
|
|
232
|
+
* Throws if invalid hex characters are encountered.
|
|
233
|
+
*/
|
|
234
|
+
declare function parseHex(hex: string): number;
|
|
200
235
|
|
|
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 };
|
|
236
|
+
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, generateMacAddress, generateNetmask, getPrefixLength, parseArpMessage, parseEthernetFrame, parseEthernetType, parseHardwareType, parseHex, parseIPv4Address, parseIPv4Packet, parseIPv4Protocol, parseIPv6Address, parseIcmpCode, parseIcmpMessage, parseIcmpType, parseMacAddress, parseOpcode, parseProtocolType, parseUdpDatagram, parseUint, serializeArpMessage, serializeEthernetFrame, serializeEthernetType, serializeHardwareType, serializeIPv4Address, serializeIPv4Cidr, serializeIPv4Packet, serializeIPv4Protocol, serializeIPv4PseudoHeader, serializeIPv6Address, serializeIcmpCode, serializeIcmpMessage, serializeIcmpType, serializeMacAddress, serializeOpcode, serializeProtocolType, serializeUdpDatagram };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +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};
|
|
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 E(e){if(e.length===0)throw new Error("empty string");let t=0;for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);if(n<48||n>57)throw new Error("invalid character");t=t*10+(n-48)}return t}function k(e){let t=0;for(let r=0;r<e.length;r++){let n=e.charCodeAt(r),o;if(n>=48&&n<=57)o=n-48;else if(n>=97&&n<=102)o=n-87;else if(n>=65&&n<=70)o=n-55;else throw new Error("invalid hex character");t=t<<4|o}return t}function M(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=C(t.getUint8(0)),o=F(n,t.getUint8(1)),s=t.getUint16(4),a=t.getUint16(6),i=e.subarray(8);return{type:n,code:o,identifier:s,sequenceNumber:a,payload:i}}function z(e){let t=new Uint8Array(8+e.payload.length),r=new DataView(t.buffer,t.byteOffset,t.byteLength);r.setUint8(0,S(e.type)),r.setUint8(1,N(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 C(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 S(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 F(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 N(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 D(e,t){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.subarray(0,l),o=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)!==o)throw new Error("invalid udp checksum")}else console.warn("no pseudo header provided: udp checksum verification skipped");let s=r.getUint16(4),a=e.subarray(8);if(s!==l+a.length)throw new Error("invalid udp length");let i=r.getUint16(0),u=r.getUint16(2);return{sourcePort:i,destinationPort:u,payload:a}}function V(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 o=A(t),s=new Uint8Array(o.length+r.length);s.set(o),s.set(r,o.length);let a=c(s,o.length+6);n.setUint16(6,a)}else console.warn("no pseudo header provided: udp checksum calculation skipped (set to 0)");return r}var h=20;function L(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 s=t.getUint8(0),a=s>>4,i=(s&15)*4,u=t.getUint8(1)>>2,d=t.getUint8(1)&3,b=t.getUint16(4),U=t.getUint8(6)>>5,x=(t.getUint8(6)&31)<<8|t.getUint8(7),I=t.getUint8(8),f=H(t.getUint8(9)),m=w(e.subarray(12,16)),P=w(e.subarray(16,20)),v=e.subarray(i);switch(f){case"icmp":return{version:a,dscp:u,ecn:d,identification:b,flags:U,fragmentOffset:x,ttl:I,protocol:f,sourceIP:m,destinationIP:P,payload:M(v)};case"tcp":return{version:a,dscp:u,ecn:d,identification:b,flags:U,fragmentOffset:x,ttl:I,protocol:f,sourceIP:m,destinationIP:P,payload:v};case"udp":return{version:a,dscp:u,ecn:d,identification:b,flags:U,fragmentOffset:x,ttl:I,protocol:f,sourceIP:m,destinationIP:P,payload:D(v,A({sourceIP:m,destinationIP:P,protocol:f,length:v.length}))};default:throw new Error("unknown ipv4 protocol")}}function $(e){let t;switch(e.protocol){case"icmp":t=z(e.payload);break;case"tcp":t=e.payload;break;case"udp":t=V(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),o=h+t.length;n.setUint8(0,e.version<<4|h/4),n.setUint8(1,e.dscp<<2|e.ecn),n.setUint16(2,o),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,B(e.protocol)),r.set(p(e.sourceIP),12),r.set(p(e.destinationIP),16);let s=r.subarray(0,h),a=c(s,10);return n.setUint16(10,a),r.set(t,20),r}function w(e){if(e.length!==4)throw new Error("invalid ipv4 address");return e.join(".")}function p(e){let t=e.split("."),r=new Uint8Array(4);if(t.length!==4)throw new Error("invalid ipv4 address");for(let n=0;n<4;n++){let o=t[n];if(o.length===0)throw new Error(`invalid ipv4 address: empty octet at position ${n}`);if(o.length>3)throw new Error(`invalid ipv4 address: octet too long at position ${n}`);let s=E(o);if(s>255)throw new Error(`invalid ipv4 address: octet too large at position ${n}`);r[n]=s}return r}function H(e){switch(e){case 1:return"icmp";case 6:return"tcp";case 17:return"udp";default:throw new Error("unknown ipv4 protocol")}}function B(e){switch(e){case"icmp":return 1;case"tcp":return 6;case"udp":return 17;default:throw new Error("unknown ipv4 protocol")}}function ie(e){let[t,r]=e.split("/");if(!t||!r)throw new Error("invalid cidr");let n=parseInt(r,10),o=G(n);return{ipAddress:p(t),netmask:o}}function G(e){let t=new Uint8Array(4);for(let r=0;r<e;r++){let n=Math.floor(r/8),o=7-r%8,s=t[n];if(s===void 0)throw new Error("invalid mask size");t[n]=s|1<<o}return t}function A(e){let t=new Uint8Array(12),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=p(e.sourceIP),o=p(e.destinationIP),s=B(e.protocol);return t.set(n,0),t.set(o,4),r.setUint8(8,0),r.setUint8(9,s),r.setUint16(10,e.length),t}function ce(e){let t=e[0]<<24|e[1]<<16|e[2]<<8|e[3];if(t===0)return 0;if(t===4294967295)return 32;if(t===4294967040)return 24;if(t===4294901760)return 16;if(t===4278190080)return 8;let r=0,n=2147483648;for(;n&t;)r++,n>>>=1;if(t&~(4294967295<<32-r))throw new Error("invalid netmask: non-contiguous bits");return r}function le(e){let t=e.subarray(0,6),r=e.subarray(6,12),n=e.subarray(12,14),o=e.subarray(14),s=y(t),a=y(r),i=j(n);switch(i){case"ipv4":return{destinationMac:s,sourceMac:a,type:i,payload:L(o)};case"arp":return{destinationMac:s,sourceMac:a,type:i,payload:T(o)};default:throw new Error("unknown ethernet type")}}function fe(e){let t;switch(e.type){case"ipv4":t=$(e.payload);break;case"arp":t=O(e.payload);break;default:throw new Error("unknown ethernet type")}let r=new Uint8Array(14+t.length);return r.set(g(e.destinationMac),0),r.set(g(e.sourceMac),6),r.set(R(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 g(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 he(){let e=new Uint8Array(6);return crypto.getRandomValues(e),e[0]=e[0]&252|2,e}function j(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 R(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=_(t.getUint16(0)),n=q(t.getUint16(2)),o=K(t.getUint16(6)),s=y(e.subarray(8,14)),a=w(e.subarray(14,18)),i=y(e.subarray(18,24)),u=w(e.subarray(24,28));return{hardwareType:r,protocolType:n,opcode:o,senderMac:s,senderIP:a,targetMac:i,targetIP:u}}function O(e){let t=new Uint8Array(28),r=new DataView(t.buffer,t.byteOffset,t.byteLength);return r.setUint16(0,Z(e.hardwareType)),r.setUint16(2,J(e.protocolType)),r.setUint8(4,6),r.setUint8(5,4),r.setUint16(6,Q(e.opcode)),t.set(g(e.senderMac),8),t.set(p(e.senderIP),14),t.set(g(e.targetMac),18),t.set(p(e.targetIP),24),t}function _(e){switch(e){case 1:return"ethernet";default:throw new Error("unknown hardware type")}}function Z(e){switch(e){case"ethernet":return 1;default:throw new Error("unknown hardware type")}}function q(e){switch(e){case 2048:return"ipv4";default:throw new Error("unknown protocol type")}}function J(e){switch(e){case"ipv4":return 2048;default:throw new Error("unknown protocol type")}}function K(e){switch(e){case 1:return"request";case 2:return"reply";default:throw new Error("unknown opcode")}}function Q(e){switch(e){case"request":return 1;case"reply":return 2;default:throw new Error("unknown opcode")}}function ve(e){if(e.length!==16)throw new Error("invalid ipv6 address");return e.reduce((t,r)=>t+r.toString(16).padStart(2,"0"),"").match(/.{1,4}/g).join(":")}function be(e){let r=W(e).split(":"),n=new Uint8Array(16);if(r.length!==8)throw new Error("invalid ipv6 address");for(let o=0;o<8;o++){let s=r[o];if(s.length===0)throw new Error(`invalid ipv6 address: empty group at position ${o}`);if(s.length>4)throw new Error(`invalid ipv6 address: group too long at position ${o}`);let a=k(s);if(a>65535)throw new Error(`invalid ipv6 address: group value too large at position ${o}`);n[o*2]=a>>8,n[o*2+1]=a&255}return n}function Ue(e){let r=e.toLowerCase().split(":").map(i=>i.replace(/^0+(?=\w)/,"")),n=-1,o=0,s=-1,a=0;for(let i=0;i<r.length;i++)r[i]==="0"||r[i]===""?(s===-1&&(s=i),a++,a>o&&(n=s,o=a)):(s=-1,a=0);return o>=2&&(r.splice(n,o),n===0?r.unshift("",""):n===r.length?r.push("",""):r.splice(n,0,"")),r.join(":")}function W(e){if(!e)throw new Error(`invalid IPv6 address: ${e}`);let t=e.split("::").map(i=>i.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(i=>i.padStart(4,"0")).join(":");let s=8-(r.length+n.length),a=Array(s).fill("0000");return[...r,...a,...n].map(i=>i.padStart(4,"0")).join(":")}export{h as IPV4_HEADER_LENGTH,l as UDP_HEADER_LENGTH,c as calculateChecksum,Ue as compressIPv6,W as expandIPv6,he as generateMacAddress,G as generateNetmask,ce as getPrefixLength,T as parseArpMessage,le as parseEthernetFrame,j as parseEthernetType,_ as parseHardwareType,k as parseHex,w as parseIPv4Address,L as parseIPv4Packet,H as parseIPv4Protocol,ve as parseIPv6Address,F as parseIcmpCode,M as parseIcmpMessage,C as parseIcmpType,y as parseMacAddress,K as parseOpcode,q as parseProtocolType,D as parseUdpDatagram,E as parseUint,O as serializeArpMessage,fe as serializeEthernetFrame,R as serializeEthernetType,Z as serializeHardwareType,p as serializeIPv4Address,ie as serializeIPv4Cidr,$ as serializeIPv4Packet,B as serializeIPv4Protocol,A as serializeIPv4PseudoHeader,be as serializeIPv6Address,N as serializeIcmpCode,z as serializeIcmpMessage,S as serializeIcmpType,g as serializeMacAddress,Q as serializeOpcode,J as serializeProtocolType,V as serializeUdpDatagram};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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"]}
|
|
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\n/**\n * Parses a string into an unsigned integer.\n *\n * Uses direct character code comparison instead of `parseInt`\n * for better performance and stricter validation.\n *\n * `parseInt` is too permissive and allows invalid input like\n * whitespace, signs, and decimals.\n *\n * Throws if invalid characters are encountered.\n */\nexport function parseUint(str: string): number {\n if (str.length === 0) {\n throw new Error('empty string');\n }\n\n let value = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n\n if (char < 48 || char > 57) {\n // 0-9\n throw new Error('invalid character');\n }\n\n value = value * 10 + (char - 48);\n }\n\n return value;\n}\n\n/**\n * Parses a hex string into a number.\n *\n * Uses direct character code comparison instead of `parseInt`\n * for better performance and stricter validation.\n *\n * `parseInt` is too permissive and allows invalid hex characters\n * to slip through.\n *\n * Throws if invalid hex characters are encountered.\n */\nexport function parseHex(hex: string): number {\n let value = 0;\n for (let i = 0; i < hex.length; i++) {\n const char = hex.charCodeAt(i);\n let digit: number;\n\n if (char >= 48 && char <= 57) {\n // 0-9\n digit = char - 48;\n } else if (char >= 97 && char <= 102) {\n // a-f\n digit = char - 87;\n } else if (char >= 65 && char <= 70) {\n // A-F\n digit = char - 55;\n } else {\n throw new Error('invalid hex character');\n }\n\n value = (value << 4) | digit;\n }\n\n return value;\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 parseIcmpMessage,\n serializeIcmpMessage,\n type IcmpMessage,\n} from './icmp.js';\nimport {\n parseUdpDatagram,\n serializeUdpDatagram,\n UDP_HEADER_LENGTH,\n type UdpDatagram,\n} from './udp.js';\nimport { calculateChecksum, parseUint } 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 if (data.length !== 4) {\n throw new Error('invalid ipv4 address');\n }\n\n return data.join('.') as IPv4Address;\n}\n\n/**\n * Serialize an IPv4 address string into a Uint8Array.\n */\nexport function serializeIPv4Address(ip: string): Uint8Array {\n const parts = ip.split('.');\n const bytes = new Uint8Array(4);\n\n if (parts.length !== 4) {\n throw new Error('invalid ipv4 address');\n }\n\n for (let i = 0; i < 4; i++) {\n const part = parts[i]!;\n\n // Length validation\n if (part.length === 0) {\n throw new Error(`invalid ipv4 address: empty octet at position ${i}`);\n }\n if (part.length > 3) {\n throw new Error(`invalid ipv4 address: octet too long at position ${i}`);\n }\n\n // Parse and range check\n const value = parseUint(part);\n if (value > 0xff) {\n throw new Error(`invalid ipv4 address: octet too large at position ${i}`);\n }\n bytes[i] = value;\n }\n\n return bytes;\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: string) {\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\n/**\n * Determines the CIDR prefix length from a netmask Uint8Array.\n */\nexport function getPrefixLength(netmask: Uint8Array): number {\n // Convert to a single 32-bit integer first\n const value =\n (netmask[0]! << 24) |\n (netmask[1]! << 16) |\n (netmask[2]! << 8) |\n netmask[3]!;\n\n // Fast paths for common netmask patterns\n if (value === 0) return 0;\n if (value === 0xffffffff) return 32;\n if (value === 0xffffff00) return 24;\n if (value === 0xffff0000) return 16;\n if (value === 0xff000000) return 8;\n\n // Count 1 bits from the left for other cases\n let count = 0;\n let testBit = 0x80000000;\n\n while (testBit & value) {\n count++;\n testBit >>>= 1;\n }\n\n // Validate contiguous bits\n if ((value & ~(0xffffffff << (32 - count))) !== 0) {\n throw new Error('invalid netmask: non-contiguous bits');\n }\n\n return count;\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 * Generates a random MAC address.\n *\n * The generated address is locally administered (so won't conflict\n * with real devices) and unicast (so it can be used as a source address).\n */\nexport function generateMacAddress() {\n const mac = new Uint8Array(6);\n crypto.getRandomValues(mac);\n\n // Control bits only apply to the first byte\n mac[0] =\n // Clear the 2 least significant bits\n (mac[0]! & 0b11111100) |\n // Set locally administered bit (bit 1) to 1 and unicast bit (bit 0) to 0\n 0b00000010;\n\n return mac;\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","import { parseHex } from './util.js';\n\n/**\n * Parses an IPv6 address Uint8Array into a string.\n */\nexport function parseIPv6Address(data: Uint8Array) {\n if (data.length !== 16) {\n throw new Error('invalid ipv6 address');\n }\n\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): Uint8Array {\n const expanded = expandIPv6(ip);\n const parts = expanded.split(':');\n const bytes = new Uint8Array(16);\n\n if (parts.length !== 8) {\n throw new Error('invalid ipv6 address');\n }\n\n for (let i = 0; i < 8; i++) {\n const part = parts[i]!;\n\n // Length validation\n if (part.length === 0) {\n throw new Error(`invalid ipv6 address: empty group at position ${i}`);\n }\n if (part.length > 4) {\n throw new Error(`invalid ipv6 address: group too long at position ${i}`);\n }\n\n const value = parseHex(part);\n if (value > 0xffff) {\n throw new Error(\n `invalid ipv6 address: group value too large at position ${i}`\n );\n }\n bytes[i * 2] = value >> 8;\n bytes[i * 2 + 1] = value & 0xff;\n }\n\n return bytes;\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","parseUint","str","value","char","parseHex","hex","digit","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","parts","bytes","i","part","value","parseUint","serializeIPv4Cidr","cidr","ipString","maskSizeString","maskSize","netmask","generateNetmask","mask","byteIndex","bitIndex","maskByte","pseudoHeader","buffer","sourceIPBuffer","destinationIPBuffer","protocolNumber","getPrefixLength","count","testBit","parseEthernetFrame","frame","destinationMacBytes","sourceMacBytes","typeBytes","payload","destinationMac","parseMacAddress","sourceMac","type","parseEthernetType","parseIPv4Packet","parseArpMessage","serializeEthernetFrame","serializeIPv4Packet","serializeArpMessage","data","serializeMacAddress","serializeEthernetType","mac","byte","segments","parsed","generateMacAddress","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","parts","expandIPv6","bytes","i","part","value","parseHex","compressIPv6","normalizedGroups","group","longestZeroStart","longestZeroLength","currentZeroStart","currentZeroLength","doubleColonSplit","left","right","missingGroups","zeros"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tcpip/wire",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Wire protocol utilities for tcpip.js",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"dependencies": {},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@total-typescript/tsconfig": "^1.0.4",
|
|
26
|
-
"tcpip": "0.2",
|
|
27
26
|
"typescript": "^5.0.4",
|
|
28
27
|
"vitest": "^3.0.1"
|
|
29
28
|
}
|