@tcpip/wire 0.1.2 → 0.1.3
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/LICENSE +21 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -9
- package/dist/index.d.ts +46 -9
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +16 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
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 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;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});function p(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){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 M(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 z(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(2);if(p(e,2)!==r)throw new Error("invalid icmp checksum");let n=F(t.getUint8(0)),o=_(n,t.getUint8(1)),s=t.getUint16(4),i=t.getUint16(6),a=e.subarray(8);return{type:n,code:o,identifier:s,sequenceNumber:i,payload:a}}function V(e){let t=new Uint8Array(8+e.payload.length),r=new DataView(t.buffer,t.byteOffset,t.byteLength);r.setUint8(0,H(e.type)),r.setUint8(1,G(e.type,e.code)),r.setUint16(4,e.identifier),r.setUint16(6,e.sequenceNumber),t.set(e.payload,8);let n=p(t,2);return r.setUint16(2,n),t}function F(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 H(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 _(e,t){switch(e){case"echo-reply":case"echo-request":{if(t===0)return;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 G(e,t){switch(e){case"echo-reply":case"echo-request":{if(t===void 0)return 0;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 b=20;function D(e,t){if(e.length<b)throw new Error("tcp segment too short");let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=r.getUint16(16);if(t){let c=new Uint8Array(t.length+e.length);if(c.set(t),c.set(e,t.length),p(c,t.length+16)!==n)throw new Error("invalid tcp checksum")}else console.warn("no pseudo header provided: tcp checksum verification skipped");let o=(r.getUint8(12)>>4)*4;if(o<b)throw new Error("invalid tcp data offset");let s=r.getUint8(13),i=e.subarray(b,o),a=e.subarray(o);return{sourcePort:r.getUint16(0),destinationPort:r.getUint16(2),sequenceNumber:r.getUint32(4),acknowledgmentNumber:r.getUint32(8),dataOffset:o,reserved:(r.getUint8(12)&14)>>1,flags:{urg:(s&32)!==0,ack:(s&16)!==0,psh:(s&8)!==0,rst:(s&4)!==0,syn:(s&2)!==0,fin:(s&1)!==0},windowSize:r.getUint16(14),urgentPointer:r.getUint16(18),options:i,payload:a}}function T(e,t){let r=b+e.options.length,n=new Uint8Array(r+e.payload.length),o=new DataView(n.buffer,n.byteOffset,n.byteLength);o.setUint16(0,e.sourcePort),o.setUint16(2,e.destinationPort),o.setUint32(4,e.sequenceNumber),o.setUint32(8,e.acknowledgmentNumber),o.setUint8(12,r/4<<4|e.reserved<<1);let s=(e.flags.urg?32:0)|(e.flags.ack?16:0)|(e.flags.psh?8:0)|(e.flags.rst?4:0)|(e.flags.syn?2:0)|(e.flags.fin?1:0);if(o.setUint8(13,s),o.setUint16(14,e.windowSize),o.setUint16(16,0),o.setUint16(18,e.urgentPointer),n.set(e.options,b),n.set(e.payload,r),t){let i=f(t),a=new Uint8Array(i.length+n.length);a.set(i),a.set(n,i.length);let c=p(a,i.length+16);o.setUint16(16,c)}return n}var h=8;function L(e,t){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.subarray(0,h),o=r.getUint16(6);if(t){let l=new Uint8Array(t.length+e.length);if(l.set(t),l.set(e,t.length),p(l,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),i=e.subarray(8);if(s!==h+i.length)throw new Error("invalid udp length");let a=r.getUint16(0),c=r.getUint16(2);return{sourcePort:a,destinationPort:c,payload:i}}function S(e,t){let r=new Uint8Array(h+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,h+e.payload.length),n.setUint16(6,0),r.set(e.payload,8),t){let o=f(t),s=new Uint8Array(o.length+r.length);s.set(o),s.set(r,o.length);let i=p(s,o.length+6);n.setUint16(6,i)}else console.warn("no pseudo header provided: udp checksum calculation skipped (set to 0)");return r}var w=20;function B(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(10),n=e.subarray(0,w);if(p(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),i=s>>4,a=(s&15)*4,c=t.getUint8(1)>>2,l=t.getUint8(1)&3,x=t.getUint16(4),I=t.getUint8(6)>>5,A=(t.getUint8(6)&31)<<8|t.getUint8(7),E=t.getUint8(8),d=R(t.getUint8(9)),g=P(e.subarray(12,16)),y=P(e.subarray(16,20)),m=e.subarray(a);switch(d){case"icmp":return{version:i,dscp:c,ecn:l,identification:x,flags:I,fragmentOffset:A,ttl:E,protocol:d,sourceIP:g,destinationIP:y,payload:z(m)};case"tcp":return{version:i,dscp:c,ecn:l,identification:x,flags:I,fragmentOffset:A,ttl:E,protocol:d,sourceIP:g,destinationIP:y,payload:D(m,f({sourceIP:g,destinationIP:y,protocol:d,length:m.length}))};case"udp":return{version:i,dscp:c,ecn:l,identification:x,flags:I,fragmentOffset:A,ttl:E,protocol:d,sourceIP:g,destinationIP:y,payload:L(m,f({sourceIP:g,destinationIP:y,protocol:d,length:m.length}))};default:throw new Error("unknown ipv4 protocol")}}function N(e){let t;switch(e.protocol){case"icmp":t=V(e.payload);break;case"tcp":t=T(e.payload,{sourceIP:e.sourceIP,destinationIP:e.destinationIP,protocol:e.protocol,length:w+e.payload.payload.length});break;case"udp":t=S(e.payload,{sourceIP:e.sourceIP,destinationIP:e.destinationIP,protocol:e.protocol,length:h+e.payload.payload.length});break;default:throw new Error("unknown ipv4 protocol")}let r=new Uint8Array(w+t.length),n=new DataView(r.buffer,r.byteOffset,r.byteLength),o=w+t.length;n.setUint8(0,e.version<<4|w/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,$(e.protocol)),r.set(u(e.sourceIP),12),r.set(u(e.destinationIP),16);let s=r.subarray(0,w),i=p(s,10);return n.setUint16(10,i),r.set(t,20),r}function P(e){if(e.length!==4)throw new Error("invalid ipv4 address");return e.join(".")}function u(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=k(o);if(s>255)throw new Error(`invalid ipv4 address: octet too large at position ${n}`);r[n]=s}return r}function R(e){switch(e){case 1:return"icmp";case 6:return"tcp";case 17:return"udp";default:throw new Error("unknown ipv4 protocol")}}function $(e){switch(e){case"icmp":return 1;case"tcp":return 6;case"udp":return 17;default:throw new Error("unknown ipv4 protocol")}}function he(e){let[t,r]=e.split("/");if(!t||!r)throw new Error("invalid cidr");let n=Number.parseInt(r,10),o=j(n);return{ipAddress:u(t),netmask:o}}function j(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 f(e){let t=new Uint8Array(12),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=u(e.sourceIP),o=u(e.destinationIP),s=$(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 we(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))!==0)throw new Error("invalid netmask: non-contiguous bits");return r}function be(e){let t=e.subarray(0,6),r=e.subarray(6,12),n=e.subarray(12,14),o=e.subarray(14),s=U(t),i=U(r),a=q(n);switch(a){case"ipv4":return{destinationMac:s,sourceMac:i,type:a,payload:B(o)};case"arp":return{destinationMac:s,sourceMac:i,type:a,payload:O(o)};default:throw new Error("unknown ethernet type")}}function Pe(e){let t;switch(e.type){case"ipv4":t=N(e.payload);break;case"arp":t=C(e.payload);break;default:throw new Error("unknown ethernet type")}let r=new Uint8Array(14+t.length);return r.set(v(e.destinationMac),0),r.set(v(e.sourceMac),6),r.set(Z(e.type),12),r.set(t,14),r}function U(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 v(e){let t=e.split(":");if(t.length!==6)throw new Error("invalid mac address");return new Uint8Array(t.map(r=>{let n=Number.parseInt(r,16);if(Number.isNaN(n))throw new Error("invalid mac address");return n}))}function Ue(){let e=new Uint8Array(6);return crypto.getRandomValues(e),e[0]=e[0]&252|2,e}function q(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 Z(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 O(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=J(t.getUint16(0)),n=Q(t.getUint16(2)),o=X(t.getUint16(6)),s=U(e.subarray(8,14)),i=P(e.subarray(14,18)),a=U(e.subarray(18,24)),c=P(e.subarray(24,28));return{hardwareType:r,protocolType:n,opcode:o,senderMac:s,senderIP:i,targetMac:a,targetIP:c}}function C(e){let t=new Uint8Array(28),r=new DataView(t.buffer,t.byteOffset,t.byteLength);return r.setUint16(0,K(e.hardwareType)),r.setUint16(2,W(e.protocolType)),r.setUint8(4,6),r.setUint8(5,4),r.setUint16(6,Y(e.opcode)),t.set(v(e.senderMac),8),t.set(u(e.senderIP),14),t.set(v(e.targetMac),18),t.set(u(e.targetIP),24),t}function J(e){if(e===1)return"ethernet";throw new Error("unknown hardware type")}function K(e){if(e==="ethernet")return 1;throw new Error("unknown hardware type")}function Q(e){if(e===2048)return"ipv4";throw new Error("unknown protocol type")}function W(e){if(e==="ipv4")return 2048;throw new Error("unknown protocol type")}function X(e){switch(e){case 1:return"request";case 2:return"reply";default:throw new Error("unknown opcode")}}function Y(e){switch(e){case"request":return 1;case"reply":return 2;default:throw new Error("unknown opcode")}}function ke(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 Me(e){let r=ee(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 i=M(s);if(i>65535)throw new Error(`invalid ipv6 address: group value too large at position ${o}`);n[o*2]=i>>8,n[o*2+1]=i&255}return n}function ze(e){let r=e.toLowerCase().split(":").map(a=>a.replace(/^0+(?=\w)/,"")),n=-1,o=0,s=-1,i=0;for(let a=0;a<r.length;a++)r[a]==="0"||r[a]===""?(s===-1&&(s=a),i++,i>o&&(n=s,o=i)):(s=-1,i=0);return o>=2&&(r.splice(n,o),n===0?r.unshift("",""):n===r.length?r.push("",""):r.splice(n,0,"")),r.join(":")}function ee(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 s=8-(r.length+n.length),i=Array(s).fill("0000");return[...r,...i,...n].map(a=>a.padStart(4,"0")).join(":")}exports.IPV4_HEADER_LENGTH = w; exports.TCP_HEADER_MIN_LENGTH = b; exports.UDP_HEADER_LENGTH = h; exports.calculateChecksum = p; exports.compressIPv6 = ze; exports.expandIPv6 = ee; exports.generateMacAddress = Ue; exports.generateNetmask = j; exports.getPrefixLength = we; exports.parseArpMessage = O; exports.parseEthernetFrame = be; exports.parseEthernetType = q; exports.parseHardwareType = J; exports.parseHex = M; exports.parseIPv4Address = P; exports.parseIPv4Packet = B; exports.parseIPv4Protocol = R; exports.parseIPv6Address = ke; exports.parseIcmpCode = _; exports.parseIcmpMessage = z; exports.parseIcmpType = F; exports.parseMacAddress = U; exports.parseOpcode = X; exports.parseProtocolType = Q; exports.parseTcpSegment = D; exports.parseUdpDatagram = L; exports.parseUint = k; exports.serializeArpMessage = C; exports.serializeEthernetFrame = Pe; exports.serializeEthernetType = Z; exports.serializeHardwareType = K; exports.serializeIPv4Address = u; exports.serializeIPv4Cidr = he; exports.serializeIPv4Packet = N; exports.serializeIPv4Protocol = $; exports.serializeIPv4PseudoHeader = f; exports.serializeIPv6Address = Me; exports.serializeIcmpCode = G; exports.serializeIcmpMessage = V; exports.serializeIcmpType = H; exports.serializeMacAddress = v; exports.serializeOpcode = Y; exports.serializeProtocolType = W; exports.serializeTcpSegment = T; exports.serializeUdpDatagram = S;
|
|
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"],"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"]}
|
|
1
|
+
{"version":3,"sources":["../src/util.ts","../src/icmp.ts","../src/tcp.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","TCP_HEADER_MIN_LENGTH","parseTcpSegment","pseudoHeader","checksumBuffer","dataOffset","flagsByte","options","serializeTcpSegment","segment","headerLength","buffer","flags","pseudoHeaderBuffer","serializeIPv4PseudoHeader","UDP_HEADER_LENGTH","parseUdpDatagram","header","length","sourcePort","destinationPort","serializeUdpDatagram","datagram","IPV4_HEADER_LENGTH","parseIPv4Packet","headerChecksum","versionAndHeaderLength","version","dscp","ecn","identification","fragmentOffset","ttl","protocol","parseIPv4Protocol","sourceIP","parseIPv4Address","destinationIP","serializeIPv4Packet","packet","totalLength","serializeIPv4Protocol","serializeIPv4Address","ip","parts","bytes","part"],"mappings":"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","file":"/home/runner/work/tcpip.js/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 { type IPv4PseudoHeader, serializeIPv4PseudoHeader } from './ipv4.js';\nimport { calculateChecksum } from './util.js';\n\nexport type TcpSegment = {\n sourcePort: number;\n destinationPort: number;\n sequenceNumber: number;\n acknowledgmentNumber: number;\n dataOffset: number;\n reserved: number;\n flags: {\n urg: boolean;\n ack: boolean;\n psh: boolean;\n rst: boolean;\n syn: boolean;\n fin: boolean;\n };\n windowSize: number;\n urgentPointer: number;\n options: Uint8Array;\n payload: Uint8Array;\n};\n\nexport const TCP_HEADER_MIN_LENGTH = 20;\n\n/**\n * Parses a TCP segment into an object.\n *\n * Optionally verifies the TCP checksum if an IP pseudo-header is provided\n * (required for TCP checksum verification).\n */\nexport function parseTcpSegment(\n data: Uint8Array,\n pseudoHeader?: Uint8Array\n): TcpSegment {\n if (data.length < TCP_HEADER_MIN_LENGTH) {\n throw new Error('tcp segment too short');\n }\n\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const checksum = dataView.getUint16(16);\n\n // If the IP pseudo-header is provided, verify the TCP checksum\n if (pseudoHeader) {\n // Create buffer for checksum verification (pseudo-header + TCP segment)\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 + 16) !== checksum\n ) {\n throw new Error('invalid tcp checksum');\n }\n } else {\n console.warn(\n 'no pseudo header provided: tcp checksum verification skipped'\n );\n }\n\n const dataOffset = (dataView.getUint8(12) >> 4) * 4;\n if (dataOffset < TCP_HEADER_MIN_LENGTH) {\n throw new Error('invalid tcp data offset');\n }\n\n const flagsByte = dataView.getUint8(13);\n const options = data.subarray(TCP_HEADER_MIN_LENGTH, dataOffset);\n const payload = data.subarray(dataOffset);\n\n return {\n sourcePort: dataView.getUint16(0),\n destinationPort: dataView.getUint16(2),\n sequenceNumber: dataView.getUint32(4),\n acknowledgmentNumber: dataView.getUint32(8),\n dataOffset: dataOffset,\n reserved: (dataView.getUint8(12) & 0x0e) >> 1,\n flags: {\n urg: (flagsByte & 0x20) !== 0,\n ack: (flagsByte & 0x10) !== 0,\n psh: (flagsByte & 0x08) !== 0,\n rst: (flagsByte & 0x04) !== 0,\n syn: (flagsByte & 0x02) !== 0,\n fin: (flagsByte & 0x01) !== 0,\n },\n windowSize: dataView.getUint16(14),\n urgentPointer: dataView.getUint16(18),\n options,\n payload,\n };\n}\n\n/**\n * Serializes a TCP segment object into a Uint8Array.\n *\n * Optionally calculates the TCP checksum if an IP pseudo-header is provided\n * (required for TCP checksum calculation).\n * If no IP pseudo-header is provided, the checksum field will be set to 0.\n */\nexport function serializeTcpSegment(\n segment: TcpSegment,\n pseudoHeader?: IPv4PseudoHeader\n): Uint8Array {\n const headerLength = TCP_HEADER_MIN_LENGTH + segment.options.length;\n const buffer = new Uint8Array(headerLength + segment.payload.length);\n const dataView = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n\n dataView.setUint16(0, segment.sourcePort);\n dataView.setUint16(2, segment.destinationPort);\n dataView.setUint32(4, segment.sequenceNumber);\n dataView.setUint32(8, segment.acknowledgmentNumber);\n\n // Data offset and reserved bits\n dataView.setUint8(12, ((headerLength / 4) << 4) | (segment.reserved << 1));\n\n // Flags\n const flags =\n (segment.flags.urg ? 0x20 : 0) |\n (segment.flags.ack ? 0x10 : 0) |\n (segment.flags.psh ? 0x08 : 0) |\n (segment.flags.rst ? 0x04 : 0) |\n (segment.flags.syn ? 0x02 : 0) |\n (segment.flags.fin ? 0x01 : 0);\n dataView.setUint8(13, flags);\n\n dataView.setUint16(14, segment.windowSize);\n dataView.setUint16(16, 0); // Initial checksum of 0\n dataView.setUint16(18, segment.urgentPointer);\n\n // Copy options and payload\n buffer.set(segment.options, TCP_HEADER_MIN_LENGTH);\n buffer.set(segment.payload, headerLength);\n\n if (pseudoHeader) {\n const pseudoHeaderBuffer = serializeIPv4PseudoHeader(pseudoHeader);\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 + 16\n );\n dataView.setUint16(16, checksum);\n }\n\n return buffer;\n}\n","import { type IPv4PseudoHeader, serializeIPv4PseudoHeader } 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 type IcmpMessage,\n parseIcmpMessage,\n serializeIcmpMessage,\n} from './icmp.js';\nimport {\n type TcpSegment,\n parseTcpSegment,\n serializeTcpSegment,\n} from './tcp.js';\nimport {\n UDP_HEADER_LENGTH,\n type UdpDatagram,\n parseUdpDatagram,\n serializeUdpDatagram,\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: TcpSegment;\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: parseTcpSegment(\n payload,\n serializeIPv4PseudoHeader({\n sourceIP,\n destinationIP,\n protocol,\n length: payload.length,\n })\n ),\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 = serializeTcpSegment(packet.payload, {\n sourceIP: packet.sourceIP,\n destinationIP: packet.destinationIP,\n protocol: packet.protocol,\n length: IPV4_HEADER_LENGTH + packet.payload.payload.length,\n });\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 = Number.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
|
@@ -18,6 +18,43 @@ declare function serializeIcmpType(type: string): 0 | 8 | 3 | 11;
|
|
|
18
18
|
declare function parseIcmpCode(type: string, code: number): "network-unreachable" | "host-unreachable" | "protocol-unreachable" | "ttl-exceeded" | "fragment-reassembly-time-exceeded" | undefined;
|
|
19
19
|
declare function serializeIcmpCode(type: string, code?: string): 0 | 2 | 1;
|
|
20
20
|
|
|
21
|
+
type TcpSegment = {
|
|
22
|
+
sourcePort: number;
|
|
23
|
+
destinationPort: number;
|
|
24
|
+
sequenceNumber: number;
|
|
25
|
+
acknowledgmentNumber: number;
|
|
26
|
+
dataOffset: number;
|
|
27
|
+
reserved: number;
|
|
28
|
+
flags: {
|
|
29
|
+
urg: boolean;
|
|
30
|
+
ack: boolean;
|
|
31
|
+
psh: boolean;
|
|
32
|
+
rst: boolean;
|
|
33
|
+
syn: boolean;
|
|
34
|
+
fin: boolean;
|
|
35
|
+
};
|
|
36
|
+
windowSize: number;
|
|
37
|
+
urgentPointer: number;
|
|
38
|
+
options: Uint8Array;
|
|
39
|
+
payload: Uint8Array;
|
|
40
|
+
};
|
|
41
|
+
declare const TCP_HEADER_MIN_LENGTH = 20;
|
|
42
|
+
/**
|
|
43
|
+
* Parses a TCP segment into an object.
|
|
44
|
+
*
|
|
45
|
+
* Optionally verifies the TCP checksum if an IP pseudo-header is provided
|
|
46
|
+
* (required for TCP checksum verification).
|
|
47
|
+
*/
|
|
48
|
+
declare function parseTcpSegment(data: Uint8Array, pseudoHeader?: Uint8Array): TcpSegment;
|
|
49
|
+
/**
|
|
50
|
+
* Serializes a TCP segment object into a Uint8Array.
|
|
51
|
+
*
|
|
52
|
+
* Optionally calculates the TCP checksum if an IP pseudo-header is provided
|
|
53
|
+
* (required for TCP checksum calculation).
|
|
54
|
+
* If no IP pseudo-header is provided, the checksum field will be set to 0.
|
|
55
|
+
*/
|
|
56
|
+
declare function serializeTcpSegment(segment: TcpSegment, pseudoHeader?: IPv4PseudoHeader): Uint8Array;
|
|
57
|
+
|
|
21
58
|
type UdpDatagram = {
|
|
22
59
|
sourcePort: number;
|
|
23
60
|
destinationPort: number;
|
|
@@ -60,7 +97,7 @@ type IcmpIPv4Packet = IPv4PacketBase & {
|
|
|
60
97
|
};
|
|
61
98
|
type TcpIPv4Packet = IPv4PacketBase & {
|
|
62
99
|
protocol: 'tcp';
|
|
63
|
-
payload:
|
|
100
|
+
payload: TcpSegment;
|
|
64
101
|
};
|
|
65
102
|
type UdpIPv4Packet = IPv4PacketBase & {
|
|
66
103
|
protocol: 'udp';
|
|
@@ -98,17 +135,17 @@ declare function serializeIPv4Protocol(protocol: IPv4Protocol): 1 | 6 | 17;
|
|
|
98
135
|
* Uint8Array IP address and netmask.
|
|
99
136
|
*/
|
|
100
137
|
declare function serializeIPv4Cidr(cidr: string): {
|
|
101
|
-
ipAddress: Uint8Array
|
|
102
|
-
netmask: Uint8Array
|
|
138
|
+
ipAddress: Uint8Array<ArrayBufferLike>;
|
|
139
|
+
netmask: Uint8Array<ArrayBuffer>;
|
|
103
140
|
};
|
|
104
141
|
/**
|
|
105
142
|
* Generates a netmask from a mask size.
|
|
106
143
|
*/
|
|
107
|
-
declare function generateNetmask(maskSize: number): Uint8Array
|
|
144
|
+
declare function generateNetmask(maskSize: number): Uint8Array<ArrayBuffer>;
|
|
108
145
|
/**
|
|
109
146
|
* Serializes a pseudo header for use in calculating transport layer checksums.
|
|
110
147
|
*/
|
|
111
|
-
declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array
|
|
148
|
+
declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array<ArrayBuffer>;
|
|
112
149
|
/**
|
|
113
150
|
* Determines the CIDR prefix length from a netmask Uint8Array.
|
|
114
151
|
*/
|
|
@@ -143,14 +180,14 @@ declare function parseMacAddress(mac: Uint8Array): MacAddress;
|
|
|
143
180
|
/**
|
|
144
181
|
* Serializes a MAC address string into a Uint8Array.
|
|
145
182
|
*/
|
|
146
|
-
declare function serializeMacAddress(mac: string): Uint8Array
|
|
183
|
+
declare function serializeMacAddress(mac: string): Uint8Array<ArrayBuffer>;
|
|
147
184
|
/**
|
|
148
185
|
* Generates a random MAC address.
|
|
149
186
|
*
|
|
150
187
|
* The generated address is locally administered (so won't conflict
|
|
151
188
|
* with real devices) and unicast (so it can be used as a source address).
|
|
152
189
|
*/
|
|
153
|
-
declare function generateMacAddress(): Uint8Array
|
|
190
|
+
declare function generateMacAddress(): Uint8Array<ArrayBuffer>;
|
|
154
191
|
/**
|
|
155
192
|
* Parses an Ethernet type into a string.
|
|
156
193
|
*/
|
|
@@ -158,7 +195,7 @@ declare function parseEthernetType(etherType: Uint8Array): "ipv4" | "arp" | "ipv
|
|
|
158
195
|
/**
|
|
159
196
|
* Serializes an Ethernet type from a string.
|
|
160
197
|
*/
|
|
161
|
-
declare function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp'): Uint8Array
|
|
198
|
+
declare function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp'): Uint8Array<ArrayBuffer>;
|
|
162
199
|
|
|
163
200
|
type ArpMessage = {
|
|
164
201
|
hardwareType: string;
|
|
@@ -233,4 +270,4 @@ declare function parseUint(str: string): number;
|
|
|
233
270
|
*/
|
|
234
271
|
declare function parseHex(hex: string): number;
|
|
235
272
|
|
|
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 };
|
|
273
|
+
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, TCP_HEADER_MIN_LENGTH, type TcpIPv4Packet, type TcpSegment, 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, parseTcpSegment, parseUdpDatagram, parseUint, serializeArpMessage, serializeEthernetFrame, serializeEthernetType, serializeHardwareType, serializeIPv4Address, serializeIPv4Cidr, serializeIPv4Packet, serializeIPv4Protocol, serializeIPv4PseudoHeader, serializeIPv6Address, serializeIcmpCode, serializeIcmpMessage, serializeIcmpType, serializeMacAddress, serializeOpcode, serializeProtocolType, serializeTcpSegment, serializeUdpDatagram };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,43 @@ declare function serializeIcmpType(type: string): 0 | 8 | 3 | 11;
|
|
|
18
18
|
declare function parseIcmpCode(type: string, code: number): "network-unreachable" | "host-unreachable" | "protocol-unreachable" | "ttl-exceeded" | "fragment-reassembly-time-exceeded" | undefined;
|
|
19
19
|
declare function serializeIcmpCode(type: string, code?: string): 0 | 2 | 1;
|
|
20
20
|
|
|
21
|
+
type TcpSegment = {
|
|
22
|
+
sourcePort: number;
|
|
23
|
+
destinationPort: number;
|
|
24
|
+
sequenceNumber: number;
|
|
25
|
+
acknowledgmentNumber: number;
|
|
26
|
+
dataOffset: number;
|
|
27
|
+
reserved: number;
|
|
28
|
+
flags: {
|
|
29
|
+
urg: boolean;
|
|
30
|
+
ack: boolean;
|
|
31
|
+
psh: boolean;
|
|
32
|
+
rst: boolean;
|
|
33
|
+
syn: boolean;
|
|
34
|
+
fin: boolean;
|
|
35
|
+
};
|
|
36
|
+
windowSize: number;
|
|
37
|
+
urgentPointer: number;
|
|
38
|
+
options: Uint8Array;
|
|
39
|
+
payload: Uint8Array;
|
|
40
|
+
};
|
|
41
|
+
declare const TCP_HEADER_MIN_LENGTH = 20;
|
|
42
|
+
/**
|
|
43
|
+
* Parses a TCP segment into an object.
|
|
44
|
+
*
|
|
45
|
+
* Optionally verifies the TCP checksum if an IP pseudo-header is provided
|
|
46
|
+
* (required for TCP checksum verification).
|
|
47
|
+
*/
|
|
48
|
+
declare function parseTcpSegment(data: Uint8Array, pseudoHeader?: Uint8Array): TcpSegment;
|
|
49
|
+
/**
|
|
50
|
+
* Serializes a TCP segment object into a Uint8Array.
|
|
51
|
+
*
|
|
52
|
+
* Optionally calculates the TCP checksum if an IP pseudo-header is provided
|
|
53
|
+
* (required for TCP checksum calculation).
|
|
54
|
+
* If no IP pseudo-header is provided, the checksum field will be set to 0.
|
|
55
|
+
*/
|
|
56
|
+
declare function serializeTcpSegment(segment: TcpSegment, pseudoHeader?: IPv4PseudoHeader): Uint8Array;
|
|
57
|
+
|
|
21
58
|
type UdpDatagram = {
|
|
22
59
|
sourcePort: number;
|
|
23
60
|
destinationPort: number;
|
|
@@ -60,7 +97,7 @@ type IcmpIPv4Packet = IPv4PacketBase & {
|
|
|
60
97
|
};
|
|
61
98
|
type TcpIPv4Packet = IPv4PacketBase & {
|
|
62
99
|
protocol: 'tcp';
|
|
63
|
-
payload:
|
|
100
|
+
payload: TcpSegment;
|
|
64
101
|
};
|
|
65
102
|
type UdpIPv4Packet = IPv4PacketBase & {
|
|
66
103
|
protocol: 'udp';
|
|
@@ -98,17 +135,17 @@ declare function serializeIPv4Protocol(protocol: IPv4Protocol): 1 | 6 | 17;
|
|
|
98
135
|
* Uint8Array IP address and netmask.
|
|
99
136
|
*/
|
|
100
137
|
declare function serializeIPv4Cidr(cidr: string): {
|
|
101
|
-
ipAddress: Uint8Array
|
|
102
|
-
netmask: Uint8Array
|
|
138
|
+
ipAddress: Uint8Array<ArrayBufferLike>;
|
|
139
|
+
netmask: Uint8Array<ArrayBuffer>;
|
|
103
140
|
};
|
|
104
141
|
/**
|
|
105
142
|
* Generates a netmask from a mask size.
|
|
106
143
|
*/
|
|
107
|
-
declare function generateNetmask(maskSize: number): Uint8Array
|
|
144
|
+
declare function generateNetmask(maskSize: number): Uint8Array<ArrayBuffer>;
|
|
108
145
|
/**
|
|
109
146
|
* Serializes a pseudo header for use in calculating transport layer checksums.
|
|
110
147
|
*/
|
|
111
|
-
declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array
|
|
148
|
+
declare function serializeIPv4PseudoHeader(pseudoHeader: IPv4PseudoHeader): Uint8Array<ArrayBuffer>;
|
|
112
149
|
/**
|
|
113
150
|
* Determines the CIDR prefix length from a netmask Uint8Array.
|
|
114
151
|
*/
|
|
@@ -143,14 +180,14 @@ declare function parseMacAddress(mac: Uint8Array): MacAddress;
|
|
|
143
180
|
/**
|
|
144
181
|
* Serializes a MAC address string into a Uint8Array.
|
|
145
182
|
*/
|
|
146
|
-
declare function serializeMacAddress(mac: string): Uint8Array
|
|
183
|
+
declare function serializeMacAddress(mac: string): Uint8Array<ArrayBuffer>;
|
|
147
184
|
/**
|
|
148
185
|
* Generates a random MAC address.
|
|
149
186
|
*
|
|
150
187
|
* The generated address is locally administered (so won't conflict
|
|
151
188
|
* with real devices) and unicast (so it can be used as a source address).
|
|
152
189
|
*/
|
|
153
|
-
declare function generateMacAddress(): Uint8Array
|
|
190
|
+
declare function generateMacAddress(): Uint8Array<ArrayBuffer>;
|
|
154
191
|
/**
|
|
155
192
|
* Parses an Ethernet type into a string.
|
|
156
193
|
*/
|
|
@@ -158,7 +195,7 @@ declare function parseEthernetType(etherType: Uint8Array): "ipv4" | "arp" | "ipv
|
|
|
158
195
|
/**
|
|
159
196
|
* Serializes an Ethernet type from a string.
|
|
160
197
|
*/
|
|
161
|
-
declare function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp'): Uint8Array
|
|
198
|
+
declare function serializeEthernetType(type: 'ipv4' | 'ipv6' | 'arp'): Uint8Array<ArrayBuffer>;
|
|
162
199
|
|
|
163
200
|
type ArpMessage = {
|
|
164
201
|
hardwareType: string;
|
|
@@ -233,4 +270,4 @@ declare function parseUint(str: string): number;
|
|
|
233
270
|
*/
|
|
234
271
|
declare function parseHex(hex: string): number;
|
|
235
272
|
|
|
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 };
|
|
273
|
+
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, TCP_HEADER_MIN_LENGTH, type TcpIPv4Packet, type TcpSegment, 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, parseTcpSegment, parseUdpDatagram, parseUint, serializeArpMessage, serializeEthernetFrame, serializeEthernetType, serializeHardwareType, serializeIPv4Address, serializeIPv4Cidr, serializeIPv4Packet, serializeIPv4Protocol, serializeIPv4PseudoHeader, serializeIPv6Address, serializeIcmpCode, serializeIcmpMessage, serializeIcmpType, serializeMacAddress, serializeOpcode, serializeProtocolType, serializeTcpSegment, 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 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};
|
|
1
|
+
function p(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){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 M(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 z(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(2);if(p(e,2)!==r)throw new Error("invalid icmp checksum");let n=F(t.getUint8(0)),o=_(n,t.getUint8(1)),s=t.getUint16(4),i=t.getUint16(6),a=e.subarray(8);return{type:n,code:o,identifier:s,sequenceNumber:i,payload:a}}function V(e){let t=new Uint8Array(8+e.payload.length),r=new DataView(t.buffer,t.byteOffset,t.byteLength);r.setUint8(0,H(e.type)),r.setUint8(1,G(e.type,e.code)),r.setUint16(4,e.identifier),r.setUint16(6,e.sequenceNumber),t.set(e.payload,8);let n=p(t,2);return r.setUint16(2,n),t}function F(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 H(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 _(e,t){switch(e){case"echo-reply":case"echo-request":{if(t===0)return;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 G(e,t){switch(e){case"echo-reply":case"echo-request":{if(t===void 0)return 0;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 b=20;function D(e,t){if(e.length<b)throw new Error("tcp segment too short");let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=r.getUint16(16);if(t){let c=new Uint8Array(t.length+e.length);if(c.set(t),c.set(e,t.length),p(c,t.length+16)!==n)throw new Error("invalid tcp checksum")}else console.warn("no pseudo header provided: tcp checksum verification skipped");let o=(r.getUint8(12)>>4)*4;if(o<b)throw new Error("invalid tcp data offset");let s=r.getUint8(13),i=e.subarray(b,o),a=e.subarray(o);return{sourcePort:r.getUint16(0),destinationPort:r.getUint16(2),sequenceNumber:r.getUint32(4),acknowledgmentNumber:r.getUint32(8),dataOffset:o,reserved:(r.getUint8(12)&14)>>1,flags:{urg:(s&32)!==0,ack:(s&16)!==0,psh:(s&8)!==0,rst:(s&4)!==0,syn:(s&2)!==0,fin:(s&1)!==0},windowSize:r.getUint16(14),urgentPointer:r.getUint16(18),options:i,payload:a}}function T(e,t){let r=b+e.options.length,n=new Uint8Array(r+e.payload.length),o=new DataView(n.buffer,n.byteOffset,n.byteLength);o.setUint16(0,e.sourcePort),o.setUint16(2,e.destinationPort),o.setUint32(4,e.sequenceNumber),o.setUint32(8,e.acknowledgmentNumber),o.setUint8(12,r/4<<4|e.reserved<<1);let s=(e.flags.urg?32:0)|(e.flags.ack?16:0)|(e.flags.psh?8:0)|(e.flags.rst?4:0)|(e.flags.syn?2:0)|(e.flags.fin?1:0);if(o.setUint8(13,s),o.setUint16(14,e.windowSize),o.setUint16(16,0),o.setUint16(18,e.urgentPointer),n.set(e.options,b),n.set(e.payload,r),t){let i=f(t),a=new Uint8Array(i.length+n.length);a.set(i),a.set(n,i.length);let c=p(a,i.length+16);o.setUint16(16,c)}return n}var h=8;function L(e,t){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.subarray(0,h),o=r.getUint16(6);if(t){let l=new Uint8Array(t.length+e.length);if(l.set(t),l.set(e,t.length),p(l,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),i=e.subarray(8);if(s!==h+i.length)throw new Error("invalid udp length");let a=r.getUint16(0),c=r.getUint16(2);return{sourcePort:a,destinationPort:c,payload:i}}function S(e,t){let r=new Uint8Array(h+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,h+e.payload.length),n.setUint16(6,0),r.set(e.payload,8),t){let o=f(t),s=new Uint8Array(o.length+r.length);s.set(o),s.set(r,o.length);let i=p(s,o.length+6);n.setUint16(6,i)}else console.warn("no pseudo header provided: udp checksum calculation skipped (set to 0)");return r}var w=20;function B(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint16(10),n=e.subarray(0,w);if(p(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),i=s>>4,a=(s&15)*4,c=t.getUint8(1)>>2,l=t.getUint8(1)&3,x=t.getUint16(4),I=t.getUint8(6)>>5,A=(t.getUint8(6)&31)<<8|t.getUint8(7),E=t.getUint8(8),d=R(t.getUint8(9)),g=P(e.subarray(12,16)),y=P(e.subarray(16,20)),m=e.subarray(a);switch(d){case"icmp":return{version:i,dscp:c,ecn:l,identification:x,flags:I,fragmentOffset:A,ttl:E,protocol:d,sourceIP:g,destinationIP:y,payload:z(m)};case"tcp":return{version:i,dscp:c,ecn:l,identification:x,flags:I,fragmentOffset:A,ttl:E,protocol:d,sourceIP:g,destinationIP:y,payload:D(m,f({sourceIP:g,destinationIP:y,protocol:d,length:m.length}))};case"udp":return{version:i,dscp:c,ecn:l,identification:x,flags:I,fragmentOffset:A,ttl:E,protocol:d,sourceIP:g,destinationIP:y,payload:L(m,f({sourceIP:g,destinationIP:y,protocol:d,length:m.length}))};default:throw new Error("unknown ipv4 protocol")}}function N(e){let t;switch(e.protocol){case"icmp":t=V(e.payload);break;case"tcp":t=T(e.payload,{sourceIP:e.sourceIP,destinationIP:e.destinationIP,protocol:e.protocol,length:w+e.payload.payload.length});break;case"udp":t=S(e.payload,{sourceIP:e.sourceIP,destinationIP:e.destinationIP,protocol:e.protocol,length:h+e.payload.payload.length});break;default:throw new Error("unknown ipv4 protocol")}let r=new Uint8Array(w+t.length),n=new DataView(r.buffer,r.byteOffset,r.byteLength),o=w+t.length;n.setUint8(0,e.version<<4|w/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,$(e.protocol)),r.set(u(e.sourceIP),12),r.set(u(e.destinationIP),16);let s=r.subarray(0,w),i=p(s,10);return n.setUint16(10,i),r.set(t,20),r}function P(e){if(e.length!==4)throw new Error("invalid ipv4 address");return e.join(".")}function u(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=k(o);if(s>255)throw new Error(`invalid ipv4 address: octet too large at position ${n}`);r[n]=s}return r}function R(e){switch(e){case 1:return"icmp";case 6:return"tcp";case 17:return"udp";default:throw new Error("unknown ipv4 protocol")}}function $(e){switch(e){case"icmp":return 1;case"tcp":return 6;case"udp":return 17;default:throw new Error("unknown ipv4 protocol")}}function he(e){let[t,r]=e.split("/");if(!t||!r)throw new Error("invalid cidr");let n=Number.parseInt(r,10),o=j(n);return{ipAddress:u(t),netmask:o}}function j(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 f(e){let t=new Uint8Array(12),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=u(e.sourceIP),o=u(e.destinationIP),s=$(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 we(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))!==0)throw new Error("invalid netmask: non-contiguous bits");return r}function be(e){let t=e.subarray(0,6),r=e.subarray(6,12),n=e.subarray(12,14),o=e.subarray(14),s=U(t),i=U(r),a=q(n);switch(a){case"ipv4":return{destinationMac:s,sourceMac:i,type:a,payload:B(o)};case"arp":return{destinationMac:s,sourceMac:i,type:a,payload:O(o)};default:throw new Error("unknown ethernet type")}}function Pe(e){let t;switch(e.type){case"ipv4":t=N(e.payload);break;case"arp":t=C(e.payload);break;default:throw new Error("unknown ethernet type")}let r=new Uint8Array(14+t.length);return r.set(v(e.destinationMac),0),r.set(v(e.sourceMac),6),r.set(Z(e.type),12),r.set(t,14),r}function U(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 v(e){let t=e.split(":");if(t.length!==6)throw new Error("invalid mac address");return new Uint8Array(t.map(r=>{let n=Number.parseInt(r,16);if(Number.isNaN(n))throw new Error("invalid mac address");return n}))}function Ue(){let e=new Uint8Array(6);return crypto.getRandomValues(e),e[0]=e[0]&252|2,e}function q(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 Z(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 O(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=J(t.getUint16(0)),n=Q(t.getUint16(2)),o=X(t.getUint16(6)),s=U(e.subarray(8,14)),i=P(e.subarray(14,18)),a=U(e.subarray(18,24)),c=P(e.subarray(24,28));return{hardwareType:r,protocolType:n,opcode:o,senderMac:s,senderIP:i,targetMac:a,targetIP:c}}function C(e){let t=new Uint8Array(28),r=new DataView(t.buffer,t.byteOffset,t.byteLength);return r.setUint16(0,K(e.hardwareType)),r.setUint16(2,W(e.protocolType)),r.setUint8(4,6),r.setUint8(5,4),r.setUint16(6,Y(e.opcode)),t.set(v(e.senderMac),8),t.set(u(e.senderIP),14),t.set(v(e.targetMac),18),t.set(u(e.targetIP),24),t}function J(e){if(e===1)return"ethernet";throw new Error("unknown hardware type")}function K(e){if(e==="ethernet")return 1;throw new Error("unknown hardware type")}function Q(e){if(e===2048)return"ipv4";throw new Error("unknown protocol type")}function W(e){if(e==="ipv4")return 2048;throw new Error("unknown protocol type")}function X(e){switch(e){case 1:return"request";case 2:return"reply";default:throw new Error("unknown opcode")}}function Y(e){switch(e){case"request":return 1;case"reply":return 2;default:throw new Error("unknown opcode")}}function ke(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 Me(e){let r=ee(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 i=M(s);if(i>65535)throw new Error(`invalid ipv6 address: group value too large at position ${o}`);n[o*2]=i>>8,n[o*2+1]=i&255}return n}function ze(e){let r=e.toLowerCase().split(":").map(a=>a.replace(/^0+(?=\w)/,"")),n=-1,o=0,s=-1,i=0;for(let a=0;a<r.length;a++)r[a]==="0"||r[a]===""?(s===-1&&(s=a),i++,i>o&&(n=s,o=i)):(s=-1,i=0);return o>=2&&(r.splice(n,o),n===0?r.unshift("",""):n===r.length?r.push("",""):r.splice(n,0,"")),r.join(":")}function ee(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 s=8-(r.length+n.length),i=Array(s).fill("0000");return[...r,...i,...n].map(a=>a.padStart(4,"0")).join(":")}export{w as IPV4_HEADER_LENGTH,b as TCP_HEADER_MIN_LENGTH,h as UDP_HEADER_LENGTH,p as calculateChecksum,ze as compressIPv6,ee as expandIPv6,Ue as generateMacAddress,j as generateNetmask,we as getPrefixLength,O as parseArpMessage,be as parseEthernetFrame,q as parseEthernetType,J as parseHardwareType,M as parseHex,P as parseIPv4Address,B as parseIPv4Packet,R as parseIPv4Protocol,ke as parseIPv6Address,_ as parseIcmpCode,z as parseIcmpMessage,F as parseIcmpType,U as parseMacAddress,X as parseOpcode,Q as parseProtocolType,D as parseTcpSegment,L as parseUdpDatagram,k as parseUint,C as serializeArpMessage,Pe as serializeEthernetFrame,Z as serializeEthernetType,K as serializeHardwareType,u as serializeIPv4Address,he as serializeIPv4Cidr,N as serializeIPv4Packet,$ as serializeIPv4Protocol,f as serializeIPv4PseudoHeader,Me as serializeIPv6Address,G as serializeIcmpCode,V as serializeIcmpMessage,H as serializeIcmpType,v as serializeMacAddress,Y as serializeOpcode,W as serializeProtocolType,T as serializeTcpSegment,S 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\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/util.ts","../src/icmp.ts","../src/tcp.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 { type IPv4PseudoHeader, serializeIPv4PseudoHeader } from './ipv4.js';\nimport { calculateChecksum } from './util.js';\n\nexport type TcpSegment = {\n sourcePort: number;\n destinationPort: number;\n sequenceNumber: number;\n acknowledgmentNumber: number;\n dataOffset: number;\n reserved: number;\n flags: {\n urg: boolean;\n ack: boolean;\n psh: boolean;\n rst: boolean;\n syn: boolean;\n fin: boolean;\n };\n windowSize: number;\n urgentPointer: number;\n options: Uint8Array;\n payload: Uint8Array;\n};\n\nexport const TCP_HEADER_MIN_LENGTH = 20;\n\n/**\n * Parses a TCP segment into an object.\n *\n * Optionally verifies the TCP checksum if an IP pseudo-header is provided\n * (required for TCP checksum verification).\n */\nexport function parseTcpSegment(\n data: Uint8Array,\n pseudoHeader?: Uint8Array\n): TcpSegment {\n if (data.length < TCP_HEADER_MIN_LENGTH) {\n throw new Error('tcp segment too short');\n }\n\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const checksum = dataView.getUint16(16);\n\n // If the IP pseudo-header is provided, verify the TCP checksum\n if (pseudoHeader) {\n // Create buffer for checksum verification (pseudo-header + TCP segment)\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 + 16) !== checksum\n ) {\n throw new Error('invalid tcp checksum');\n }\n } else {\n console.warn(\n 'no pseudo header provided: tcp checksum verification skipped'\n );\n }\n\n const dataOffset = (dataView.getUint8(12) >> 4) * 4;\n if (dataOffset < TCP_HEADER_MIN_LENGTH) {\n throw new Error('invalid tcp data offset');\n }\n\n const flagsByte = dataView.getUint8(13);\n const options = data.subarray(TCP_HEADER_MIN_LENGTH, dataOffset);\n const payload = data.subarray(dataOffset);\n\n return {\n sourcePort: dataView.getUint16(0),\n destinationPort: dataView.getUint16(2),\n sequenceNumber: dataView.getUint32(4),\n acknowledgmentNumber: dataView.getUint32(8),\n dataOffset: dataOffset,\n reserved: (dataView.getUint8(12) & 0x0e) >> 1,\n flags: {\n urg: (flagsByte & 0x20) !== 0,\n ack: (flagsByte & 0x10) !== 0,\n psh: (flagsByte & 0x08) !== 0,\n rst: (flagsByte & 0x04) !== 0,\n syn: (flagsByte & 0x02) !== 0,\n fin: (flagsByte & 0x01) !== 0,\n },\n windowSize: dataView.getUint16(14),\n urgentPointer: dataView.getUint16(18),\n options,\n payload,\n };\n}\n\n/**\n * Serializes a TCP segment object into a Uint8Array.\n *\n * Optionally calculates the TCP checksum if an IP pseudo-header is provided\n * (required for TCP checksum calculation).\n * If no IP pseudo-header is provided, the checksum field will be set to 0.\n */\nexport function serializeTcpSegment(\n segment: TcpSegment,\n pseudoHeader?: IPv4PseudoHeader\n): Uint8Array {\n const headerLength = TCP_HEADER_MIN_LENGTH + segment.options.length;\n const buffer = new Uint8Array(headerLength + segment.payload.length);\n const dataView = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n\n dataView.setUint16(0, segment.sourcePort);\n dataView.setUint16(2, segment.destinationPort);\n dataView.setUint32(4, segment.sequenceNumber);\n dataView.setUint32(8, segment.acknowledgmentNumber);\n\n // Data offset and reserved bits\n dataView.setUint8(12, ((headerLength / 4) << 4) | (segment.reserved << 1));\n\n // Flags\n const flags =\n (segment.flags.urg ? 0x20 : 0) |\n (segment.flags.ack ? 0x10 : 0) |\n (segment.flags.psh ? 0x08 : 0) |\n (segment.flags.rst ? 0x04 : 0) |\n (segment.flags.syn ? 0x02 : 0) |\n (segment.flags.fin ? 0x01 : 0);\n dataView.setUint8(13, flags);\n\n dataView.setUint16(14, segment.windowSize);\n dataView.setUint16(16, 0); // Initial checksum of 0\n dataView.setUint16(18, segment.urgentPointer);\n\n // Copy options and payload\n buffer.set(segment.options, TCP_HEADER_MIN_LENGTH);\n buffer.set(segment.payload, headerLength);\n\n if (pseudoHeader) {\n const pseudoHeaderBuffer = serializeIPv4PseudoHeader(pseudoHeader);\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 + 16\n );\n dataView.setUint16(16, checksum);\n }\n\n return buffer;\n}\n","import { type IPv4PseudoHeader, serializeIPv4PseudoHeader } 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 type IcmpMessage,\n parseIcmpMessage,\n serializeIcmpMessage,\n} from './icmp.js';\nimport {\n type TcpSegment,\n parseTcpSegment,\n serializeTcpSegment,\n} from './tcp.js';\nimport {\n UDP_HEADER_LENGTH,\n type UdpDatagram,\n parseUdpDatagram,\n serializeUdpDatagram,\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: TcpSegment;\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: parseTcpSegment(\n payload,\n serializeIPv4PseudoHeader({\n sourceIP,\n destinationIP,\n protocol,\n length: payload.length,\n })\n ),\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 = serializeTcpSegment(packet.payload, {\n sourceIP: packet.sourceIP,\n destinationIP: packet.destinationIP,\n protocol: packet.protocol,\n length: IPV4_HEADER_LENGTH + packet.payload.payload.length,\n });\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 = Number.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 type ArpMessage,\n parseArpMessage,\n serializeArpMessage,\n} from './arp.js';\nimport {\n type IPv4Packet,\n parseIPv4Packet,\n serializeIPv4Packet,\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 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 = Number.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 type MacAddress,\n parseMacAddress,\n serializeMacAddress,\n} from './ethernet.js';\nimport {\n type IPv4Address,\n parseIPv4Address,\n serializeIPv4Address,\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","TCP_HEADER_MIN_LENGTH","parseTcpSegment","data","pseudoHeader","dataView","checksum","checksumBuffer","calculateChecksum","dataOffset","flagsByte","options","payload","serializeTcpSegment","segment","headerLength","buffer","flags","pseudoHeaderBuffer","serializeIPv4PseudoHeader","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","parseTcpSegment","serializeIPv4PseudoHeader","parseUdpDatagram","serializeIPv4Packet","packet","serializeIcmpMessage","serializeTcpSegment","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,29 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tcpip/wire",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Wire protocol utilities for tcpip.js",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/chipmk/tcpip.js.git",
|
|
8
|
+
"directory": "packages/wire"
|
|
9
|
+
},
|
|
5
10
|
"main": "dist/index.cjs",
|
|
6
11
|
"types": "dist/index.d.ts",
|
|
7
12
|
"type": "module",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"build": "tsup --clean",
|
|
10
|
-
"test": "vitest",
|
|
11
|
-
"prepublishOnly": "npm run build"
|
|
12
|
-
},
|
|
13
13
|
"files": [
|
|
14
14
|
"dist/**/*"
|
|
15
15
|
],
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
|
-
"import": "./dist/index.js",
|
|
19
18
|
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
20
|
"default": "./dist/index.cjs"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@total-typescript/tsconfig": "^1.0.4",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
26
|
+
"tsup": "^8.3.5",
|
|
27
|
+
"typescript": "^5.8.3",
|
|
28
|
+
"vitest": "^3.1.4"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup --clean",
|
|
32
|
+
"clean": "rm -rf dist",
|
|
33
|
+
"test": "vitest"
|
|
28
34
|
}
|
|
29
|
-
}
|
|
35
|
+
}
|