feat: validate synchronized ASN prefix snapshots

This commit is contained in:
spiritlhl 2026-07-21 03:18:31 +08:00
parent a32a1067d3
commit 577871a7df
20 changed files with 8987 additions and 2983 deletions

View File

@ -37,7 +37,7 @@ jobs:
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add bk/prefix/*.txt
git add bk/prefix/*.txt bk/prefix/*.txt.manifest.json
if git diff --cached --quiet; then
echo "无变更,跳过提交。"
else

View File

@ -1,30 +1,28 @@
2400:9380:9002
2400:9380:9115
2400:9380:9116
2400:9380:9206
2400:9380:9262
2400:9380:a003
2400:9380:a00a
2400:9380:a00c
2400:9380:a014
2400:9380:a016
2400:9380:a01f
2400:9380:a022
2400:9380:a026
2400:9380:a028
2400:9380:a042
2400:9380:a110
240e:97d:8000
2804:1e48:9003
2a04:f580:9001
2a04:f580:9090
2a04:f581:110b
2a04:f581:a123
2a04:f581:a125
2c0f:f7a8:1
2c0f:f7a8:2
2c0f:f7a8:24
2c0f:f7a8:29
2c0f:f7a8:37
2c0f:f7a8:47
2c0f:f7a8:9011
2400:9380:9002::/48
2400:9380:9115::/48
2400:9380:9116::/48
2400:9380:9206::/48
2400:9380:a003::/48
2400:9380:a00a::/48
2400:9380:a00c::/48
2400:9380:a014::/48
2400:9380:a016::/48
2400:9380:a01f::/48
2400:9380:a022::/48
2400:9380:a028::/48
2400:9380:a042::/48
2400:9380:a110::/48
240e:97d:8000::/48
2804:1e48:9003::/48
2a04:f580:9001::/48
2a04:f580:9090::/48
2a04:f581:110b::/48
2a04:f581:a123::/48
2a04:f581:a125::/48
2c0f:f7a8:1::/48
2c0f:f7a8:24::/48
2c0f:f7a8:29::/48
2c0f:f7a8:2::/48
2c0f:f7a8:37::/48
2c0f:f7a8:47::/48
2c0f:f7a8:9011::/48

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as23764.txt",
"count": 28,
"sha256": "d853ef48792875af80682ebfb9817bbbcfefd0f904cf057568664d3bdb9373bb",
"generated_at": "2026-07-20T19:12:53Z"
}

View File

@ -1,256 +1,628 @@
2400:9380:8001
2400:9380:8003
2400:9380:8021
2400:9380:8040
2400:9380:8140
2400:9380:8201
2400:9380:8301
240e
240e:1
240e:100
240e:101
240e:103
240e:104
240e:106
240e:108
240e:11
240e:11:8001
240e:12
240e:144
240e:16:1001
240e:16:1008
240e:16:1009
240e:184
240e:1a
240e:1c7
240e:1c:112
240e:2
240e:218
240e:219
240e:21a
240e:21b
240e:224
240e:225
240e:226
240e:227
240e:24
240e:240
240e:241
240e:242
240e:243
240e:244
240e:245
240e:246
240e:247
240e:2c
240e:318
240e:319
240e:31a
240e:31b
240e:324
240e:325
240e:326
240e:327
240e:340
240e:341
240e:342
240e:343
240e:350:205
240e:41
240e:418
240e:419
240e:41a
240e:41b
240e:42
240e:424
240e:425
240e:426
240e:427
240e:42:4000
240e:43
240e:43:8000
240e:44
240e:440
240e:441
240e:442
240e:443
240e:444
240e:445
240e:446
240e:447
240e:45
240e:45:8000
240e:46
240e:46:5008
240e:47
240e:47:4
240e:48
240e:49
240e:4a
240e:4a:4100
240e:4b
240e:4b:1
240e:4b:2
240e:4c
240e:4c:4006
240e:4d
240e:4d:50ff
240e:4e
240e:4e:4000
240e:4f
240e:50
240e:51
240e:518
240e:519
240e:51a
240e:51b
240e:52
240e:524
240e:525
240e:526
240e:527
240e:52:4802
240e:53
240e:54
240e:540
240e:541
240e:542
240e:543
240e:544
240e:545
240e:546
240e:547
240e:55
240e:56
240e:56:4807
240e:57
240e:5a
240e:5a:6800
240e:5b
240e:5c
240e:5d
240e:5e
240e:5f
240e:618
240e:619
240e:61a
240e:61b
240e:61d:1401
240e:624
240e:625
240e:626
240e:627
240e:630:b83
240e:638
240e:638:b00
240e:638:b02
240e:64
240e:640
240e:641
240e:642
240e:643
240e:64c:340
240e:650:2540
240e:650:280
240e:650:4400
240e:658:6c20
240e:658:6c31
240e:658:a00
240e:659:1160
240e:659:11e0
240e:659:1b0
240e:661:6180
240e:699
240e:6a0
240e:6a0:10
240e:6a0:100
240e:6a0:105
240e:6a0:b0c
240e:7
240e:718
240e:719
240e:71a
240e:71b
240e:724
240e:725
240e:726
240e:727
240e:740
240e:741
240e:742
240e:743
240e:767
240e:840
240e:841
240e:9
240e:918
240e:919
240e:91a
240e:91b
240e:924
240e:925
240e:926
240e:927
240e:940
240e:941
240e:942
240e:943
240e:944
240e:945
240e:946
240e:947
240e:980
240e:981
240e:982
240e:983
240e:9f:8340
240e:9f:8400
240e:9f:8440
240e:9f:8880
240e:9f:88c0
240e:a0c
240e:a0d
240e:a0e
240e:a0f
240e:a18
240e:a19
240e:a1a
240e:a1b
240e:a24
240e:a25
240e:a26
240e:a27
240e:a40
240e:a41
240e:a42
240e:a43
240e:a44
240e:a45
240e:a46
240e:a47
240e:a5:8000
240e:a5:a100
240e:a5:a140
240e:a9:8010
240e:ab:b202
240e:b
240e:bd:8000
240e:cd:8000
2605:9d80:8001
2605:9d80:8011
2605:9d80:8021
2605:9d80:8031
2605:9d80:8041
2605:9d80:8081
2a04:f580:8010
2a04:f580:8011
2a04:f580:8090
2a04:f580:8210
2a04:f580:8211
2a04:f580:8290
2c0f:f7a8:8011
2c0f:f7a8:8050
2c0f:f7a8:805f
2c0f:f7a8:8150
2c0f:f7a8:815f
2c0f:f7a8:8211
2400:9380:8001::/48
2400:9380:8003::/48
2400:9380:8021::/48
2400:9380:8040::/48
2400:9380:8140::/48
2400:9380:8201::/48
2400:9380:8301::/48
240e:100:8000::/34
240e:100:c000::/34
240e:101::/34
240e:103:c000::/34
240e:104:4000::/36
240e:104:7000::/36
240e:104:c000::/34
240e:106:4000::/34
240e:108:1100::/44
240e:108:1110::/44
240e:108:1120::/44
240e:108:1130::/44
240e:108:1140::/44
240e:108:1150::/44
240e:108:1160::/44
240e:108:1180::/44
240e:108:1190::/44
240e:108:11a0::/44
240e:108:11b0::/44
240e:108:11c0::/44
240e:108:11d0::/44
240e:108:11e0::/44
240e:108:1200::/44
240e:108:1210::/44
240e:108:12a0::/44
240e:108:12c0::/44
240e:108:12d0::/44
240e:108:1300::/44
240e:108:1310::/44
240e:108:1320::/44
240e:108:1330::/44
240e:108:1340::/44
240e:108:1350::/44
240e:108:1360::/44
240e:108:1370::/44
240e:108:1380::/44
240e:108:1390::/44
240e:108:13a0::/44
240e:108:13b0::/44
240e:108:13c0::/44
240e:108:13d0::/44
240e:108:13e0::/44
240e:11:8001::/48
240e:12::/32
240e:144:c000::/34
240e:14::/31
240e:16:1001::/48
240e:16:1008::/48
240e:184:c000::/34
240e:1:8000::/33
240e:1::/33
240e:1c:112::/48
240e:1c::/31
240e:204::/30
240e:208::/30
240e:20c::/30
240e:210::/30
240e:214::/30
240e:218::/32
240e:219::/32
240e:21a::/32
240e:21b::/32
240e:21c::/30
240e:220::/30
240e:224::/32
240e:225::/32
240e:226::/32
240e:227::/32
240e:22c::/30
240e:230::/30
240e:234::/30
240e:238::/30
240e:23c::/30
240e:240::/32
240e:241::/32
240e:242::/32
240e:243::/32
240e:244::/32
240e:245::/32
240e:246::/32
240e:247::/32
240e:248::/30
240e:24:8000::/34
240e:24c::/30
240e:250::/30
240e:254::/30
240e:258::/30
240e:25c::/30
240e:260::/30
240e:264::/30
240e:268::/30
240e:26c::/30
240e:270::/30
240e:274::/30
240e:278::/30
240e:27c::/30
240e:2::/33
240e:2c:8000::/34
240e:304::/30
240e:308::/30
240e:30c::/30
240e:310::/30
240e:314::/30
240e:318::/32
240e:319::/32
240e:31a::/32
240e:31b::/32
240e:31c::/30
240e:320::/30
240e:324::/32
240e:325::/32
240e:326::/32
240e:327::/32
240e:32c::/30
240e:330::/30
240e:334::/30
240e:338::/30
240e:33c::/30
240e:340::/32
240e:341::/32
240e:342::/32
240e:343::/32
240e:344::/30
240e:348::/30
240e:34c::/30
240e:350:205::/48
240e:350::/29
240e:358::/29
240e:360::/29
240e:368::/29
240e:370::/29
240e:378::/29
240e:380::/29
240e:388::/29
240e:390::/29
240e:398::/29
240e:3a0::/28
240e:3b0::/28
240e:404::/30
240e:408::/30
240e:414::/30
240e:418::/32
240e:419::/32
240e:41:8000::/33
240e:41::/33
240e:41a::/32
240e:41b::/32
240e:41c::/30
240e:420::/30
240e:424::/32
240e:425::/32
240e:426::/32
240e:427::/32
240e:42:4000::/48
240e:42:8000::/33
240e:42::/33
240e:42c::/30
240e:430::/30
240e:434::/30
240e:438::/30
240e:43:8000::/33
240e:43:8000::/48
240e:43::/33
240e:43c::/30
240e:440::/32
240e:441::/32
240e:442::/32
240e:443::/32
240e:444::/32
240e:445::/32
240e:446::/32
240e:447::/32
240e:448::/30
240e:44:8000::/33
240e:44::/33
240e:44c::/30
240e:450::/30
240e:454::/30
240e:458::/30
240e:45:8000::/33
240e:45:8000::/48
240e:45c::/30
240e:460::/30
240e:464::/30
240e:468::/30
240e:46:5008::/48
240e:46:8000::/33
240e:46::/33
240e:46c::/30
240e:470::/30
240e:474::/30
240e:478::/30
240e:47::/32
240e:47c::/30
240e:48:8000::/33
240e:48::/33
240e:49:8000::/33
240e:49::/33
240e:4a:4100::/48
240e:4a:8000::/33
240e:4a::/33
240e:4b:1::/48
240e:4b:8000::/33
240e:4b::/33
240e:4c:4006::/48
240e:4c:8000::/33
240e:4c::/33
240e:4d:50ff::/48
240e:4d:8000::/33
240e:4d::/33
240e:4e:4000::/48
240e:4e:8000::/33
240e:4e::/33
240e:4f:8000::/33
240e:4f::/33
240e:504::/30
240e:508::/30
240e:50:8000::/33
240e:50::/33
240e:514::/30
240e:518::/32
240e:519::/32
240e:51::/32
240e:51a::/32
240e:51b::/32
240e:51c::/30
240e:520::/30
240e:524::/32
240e:525::/32
240e:526::/32
240e:527::/32
240e:52:4802::/48
240e:52:8000::/33
240e:52::/33
240e:52c::/30
240e:530::/30
240e:534::/30
240e:538::/30
240e:53:8000::/33
240e:53::/33
240e:53c::/30
240e:540::/32
240e:541::/32
240e:542::/32
240e:543::/32
240e:544::/32
240e:545::/32
240e:546::/32
240e:547::/32
240e:548::/30
240e:54:8000::/33
240e:54::/33
240e:54c::/30
240e:550::/30
240e:554::/30
240e:558::/30
240e:55:8000::/33
240e:55::/33
240e:55c::/30
240e:560::/30
240e:564::/30
240e:568::/30
240e:56:4807::/48
240e:56:8000::/33
240e:56::/33
240e:56c::/30
240e:570::/30
240e:574::/30
240e:578::/30
240e:57:8000::/33
240e:57::/33
240e:57c::/30
240e:5a:6800::/48
240e:5a:8000::/33
240e:5a::/33
240e:5b:8000::/33
240e:5b::/33
240e:5c:8000::/33
240e:5c::/33
240e:5d:8000::/33
240e:5d::/33
240e:5e:8000::/33
240e:5e::/33
240e:5f:8000::/33
240e:5f::/33
240e:604::/30
240e:608::/30
240e:60::/30
240e:60c::/30
240e:610::/30
240e:614::/30
240e:618::/32
240e:619::/32
240e:61a::/32
240e:61b::/32
240e:61c::/30
240e:61d:1401::/48
240e:620::/30
240e:624::/32
240e:625::/32
240e:626::/32
240e:627::/32
240e:62c::/30
240e:630::/30
240e:634::/30
240e:638::/30
240e:638::/48
240e:63c::/30
240e:640::/32
240e:641::/32
240e:642::/32
240e:643::/32
240e:644::/30
240e:648::/30
240e:64::/32
240e:64c::/30
240e:650::/29
240e:658::/29
240e:659:1160::/48
240e:660::/29
240e:668::/29
240e:670::/29
240e:678::/29
240e:680::/29
240e:688::/29
240e:690::/29
240e:698::/29
240e:6a0::/28
240e:6b0::/28
240e:704::/30
240e:708::/30
240e:70c::/30
240e:710::/30
240e:714::/30
240e:718::/32
240e:719::/32
240e:71a::/32
240e:71b::/32
240e:71c::/30
240e:720::/30
240e:724::/32
240e:725::/32
240e:726::/32
240e:727::/32
240e:72c::/30
240e:730::/30
240e:734::/30
240e:738::/30
240e:73c::/30
240e:740::/32
240e:741::/32
240e:742::/32
240e:743::/32
240e:744::/30
240e:748::/30
240e:74c::/30
240e:750::/29
240e:758::/29
240e:760::/29
240e:768::/29
240e:770::/29
240e:778::/29
240e:780::/29
240e:788::/29
240e:790::/29
240e:798::/29
240e:7::/32
240e:7a0::/28
240e:7b0::/28
240e:804::/30
240e:814::/30
240e:81c::/30
240e:820::/30
240e:82c::/30
240e:830::/30
240e:834::/30
240e:838::/30
240e:83c::/30
240e:840::/32
240e:841::/32
240e:848::/30
240e:84::/31
240e:84c::/30
240e:850::/30
240e:854::/30
240e:858::/30
240e:85c::/30
240e:860::/30
240e:864::/30
240e:868::/30
240e:86::/31
240e:86c::/30
240e:870::/30
240e:874::/30
240e:878::/30
240e:87c::/30
240e:88::/31
240e:8a::/31
240e:8c::/31
240e:8e::/31
240e:904::/30
240e:908::/30
240e:90::/31
240e:90c::/30
240e:910::/30
240e:914::/30
240e:918::/32
240e:919::/32
240e:91a::/32
240e:91b::/32
240e:91c::/30
240e:920::/30
240e:924::/32
240e:925::/32
240e:926::/32
240e:927::/32
240e:92::/31
240e:92c::/30
240e:930::/30
240e:934::/30
240e:938::/30
240e:93c::/30
240e:940::/32
240e:941::/32
240e:942::/32
240e:943::/32
240e:944::/32
240e:945::/32
240e:946::/32
240e:947::/32
240e:948::/30
240e:94c::/30
240e:950::/30
240e:954::/30
240e:958::/30
240e:95c::/30
240e:960::/30
240e:964::/30
240e:968::/30
240e:96::/31
240e:96c::/30
240e:970::/30
240e:974::/30
240e:978::/30
240e:97c::/30
240e:980:9400::/40
240e:981:f000::/36
240e:982:1000::/36
240e:982:2000::/36
240e:982:3000::/36
240e:982:4000::/36
240e:982:5000::/36
240e:982:6000::/36
240e:982:7000::/36
240e:982:8000::/36
240e:982:9000::/36
240e:982::/36
240e:982:a000::/36
240e:982:b000::/36
240e:982:c000::/36
240e:982:d000::/36
240e:982:e000::/36
240e:983:1000::/40
240e:983:100::/40
240e:983:1100::/40
240e:983:1200::/40
240e:983:1300::/40
240e:983:1400::/40
240e:983:1500::/40
240e:983:1600::/40
240e:983:1700::/40
240e:983:1800::/40
240e:983:1900::/40
240e:983:1a00::/40
240e:983:1b00::/40
240e:983:1c00::/40
240e:983:1d00::/40
240e:983:1e00::/40
240e:983::/40
240e:983:a00::/40
240e:983:c00::/40
240e:983:d00::/40
240e:983:f00::/40
240e:98::/31
240e:9::/32
240e:9a::/31
240e:9c::/30
240e::/20
240e::/24
240e:a04::/30
240e:a08::/30
240e:a0::/31
240e:a0c::/32
240e:a0d::/32
240e:a0e::/32
240e:a0f::/32
240e:a14::/30
240e:a18::/32
240e:a19::/32
240e:a1a::/32
240e:a1b::/32
240e:a1c::/30
240e:a20::/30
240e:a24::/32
240e:a25::/32
240e:a26::/32
240e:a27::/32
240e:a2::/31
240e:a2c::/30
240e:a30::/30
240e:a34::/30
240e:a38::/30
240e:a40::/32
240e:a41::/32
240e:a42::/32
240e:a43::/32
240e:a44::/32
240e:a45::/32
240e:a46::/32
240e:a47::/32
240e:a48::/30
240e:a4::/31
240e:a4c::/30
240e:a50::/30
240e:a54::/30
240e:a58::/30
240e:a5:8000::/48
240e:a5c::/30
240e:a60::/30
240e:a64::/30
240e:a68::/30
240e:a6::/31
240e:a6c::/30
240e:a70::/30
240e:a74::/30
240e:a78::/30
240e:a7c::/30
240e:a8::/31
240e:aa::/31
240e:ac::/31
240e:ae::/31
240e:b04::/30
240e:b0::/31
240e:b0c::/30
240e:b14::/30
240e:b1c::/30
240e:b20::/30
240e:b2::/31
240e:b2c::/30
240e:b30::/30
240e:b34::/30
240e:b38::/30
240e:b44::/30
240e:b48::/30
240e:b4::/31
240e:b4c::/30
240e:b50::/29
240e:b60::/29
240e:b68::/29
240e:b6::/31
240e:b70::/29
240e:b78::/29
240e:b80::/29
240e:b88::/29
240e:b8::/31
240e:b90::/29
240e:b98::/29
240e:b:8000::/33
240e:b::/33
240e:ba::/31
240e:bb0::/28
240e:bc::/31
240e:bd:8000::/48
240e:be::/31
240e:c0::/31
240e:c2::/31
240e:c4::/30
240e:c60::/30
240e:c8::/31
240e:ca::/31
240e:cc::/31
240e:cd:8000::/48
240e:ce::/31
240e:d0::/31
240e:d2::/31
240e:d4::/31
240e:d6::/31
240e:d8::/31
240e:da::/31
240e:dc::/31
240e:de::/31
240e:e8::/31
240e:ea::/31
240e:ec::/31
240e:ee::/31
240e:f0::/31
240e:f2::/31
240e:f4::/31
240e:f6::/31
240e:f8::/31
240e:fa::/31
240e:fc::/31
240e:fe::/31
2605:9d80:8001::/48
2605:9d80:8011::/48
2605:9d80:8021::/48
2605:9d80:8031::/48
2605:9d80:8041::/48
2605:9d80:8081::/48
2a04:f580:8010::/48
2a04:f580:8011::/48
2a04:f580:8090::/48
2a04:f580:8210::/48
2a04:f580:8211::/48
2a04:f580:8290::/48
2c0f:f7a8:8011::/48
2c0f:f7a8:8050::/48
2c0f:f7a8:805f::/48
2c0f:f7a8:8150::/48
2c0f:f7a8:815f::/48
2c0f:f7a8:8211::/48

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as4134.txt",
"count": 628,
"sha256": "9e032d30479db6c5bd167681048922765c23d1a35b01ed9e6968b2099b8b916f",
"generated_at": "2026-07-20T19:12:53Z"
}

View File

@ -1,180 +1,179 @@
2400:9380:9001
2400:9380:9009
2400:9380:9020
2400:9380:9021
2400:9380:9050
2400:9380:9051
2400:9380:9060
2400:9380:9071
2400:9380:9080
2400:9380:9081
2400:9380:90b1
2400:9380:90b2
2400:9380:90b3
2400:9380:90b4
2400:9380:90b5
2400:9380:90b6
2400:9380:90b7
2400:9380:9121
2400:9380:9220
2400:9380:9221
2400:9380:9250
2400:9380:9251
2400:9380:9260
2400:9380:9271
2400:9380:9280
2400:9380:9281
2400:9380:9282
2400:9380:92b1
2400:9380:92b2
2400:9380:92b3
2400:9380:92b4
2400:9380:92b5
2400:9380:92b6
2400:9380:92b7
240e
240e:182:5401
240e:182:5501
240e:409:9000
240e:409:9001
240e:410:ff00
240e:411:ff00
240e:414
240e:43d:fff1
240e:43d:fff3
240e:43d:fff4
240e:43d:fff7
240e:440:ac00
240e:440:ac01
240e:440:ac02
240e:441:ac00
240e:441:ac01
240e:441:ac02
240e:445:3f00
240e:446:3f00
240e:451:bfc0
240e:451:bfe0
240e:451:ffa0
240e:451:ffc0
240e:451:ffe0
240e:456:fe00
240e:457:fe00
240e:469:f400
240e:476:febf
240e:476:feff
240e:604:314
240e:604:319
240e:60e
240e:60e:8000
240e:60e:8001
240e:615
240e:61d
240e:628
240e:62c
240e:62f
240e:638:f
240e:63c
240e:640:178
240e:640:179
240e:640:17a
240e:640:17b
240e:645
240e:648:1e
240e:648:c00f
240e:648:c40f
240e:648:c80f
240e:648:cc0f
240e:648:d00f
240e:648:d40f
240e:648:d80f
240e:648:dc0f
240e:649:c00f
240e:649:c40f
240e:649:c80f
240e:649:cc0f
240e:649:d00f
240e:649:d40f
240e:649:d80f
240e:649:dc0f
240e:64e
240e:64e:de0
240e:64e:dec
240e:64e:ded
240e:650
240e:659:f100
240e:65f
240e:669
240e:670
240e:679:1001
240e:679:800
240e:688:ed00
240e:699
240e:699:7a00
240e:699:7a01
240e:699:7b00
240e:699:7b06
240e:699:7b07
240e:699:7b08
240e:699:7b0a
240e:699:7b0c
240e:699:7b0d
240e:699:7b0f
240e:699:7b11
240e:699:7b12
240e:6a0:d00
240e:6a0:d03
240e:6a0:d04
240e:6a0:d07
240e:6a0:d0a
240e:713:f020
240e:713:f021
240e:733:4c0
240e:733:4c1
240e:767:f000
240e:787:7000
240e:787:7001
240e:790
240e:965:822
240e:eb
240e:f6:8002
240e:f6:8003
240e:ff:c020
240e:ff:c022
240e:ff:c024
240e:ff:c027
240e:ff:c029
2605:9d80:9003
2605:9d80:9013
2605:9d80:9023
2605:9d80:9033
2605:9d80:9042
2605:9d80:9071
2605:9d80:9092
2804:1e48
2804:1e48:9001
2804:1e48:9002
2a04:f580:9010
2a04:f580:9012
2a04:f580:9013
2a04:f580:9020
2a04:f580:9030
2a04:f580:9040
2a04:f580:9050
2a04:f580:9060
2a04:f580:9070
2a04:f580:9080
2a04:f580:9210
2a04:f580:9212
2a04:f580:9213
2a04:f580:9220
2a04:f580:9230
2a04:f580:9240
2a04:f580:9250
2a04:f580:9260
2a04:f580:9270
2a04:f580:9280
2a04:f580:9290
2c0f:f7a8:9020
2c0f:f7a8:9041
2c0f:f7a8:9211
2c0f:f7a8:9220
2400:9380:9001::/48
2400:9380:9009::/48
2400:9380:9020::/48
2400:9380:9021::/48
2400:9380:9050::/48
2400:9380:9051::/48
2400:9380:9060::/48
2400:9380:9071::/48
2400:9380:9080::/48
2400:9380:9081::/48
2400:9380:90b1::/48
2400:9380:90b2::/48
2400:9380:90b3::/48
2400:9380:90b4::/48
2400:9380:90b5::/48
2400:9380:90b6::/48
2400:9380:90b7::/48
2400:9380:9121::/48
2400:9380:9220::/48
2400:9380:9221::/48
2400:9380:9250::/48
2400:9380:9251::/48
2400:9380:9260::/48
2400:9380:9271::/48
2400:9380:9280::/48
2400:9380:9281::/48
2400:9380:9282::/48
2400:9380:92b1::/48
2400:9380:92b2::/48
2400:9380:92b3::/48
2400:9380:92b4::/48
2400:9380:92b5::/48
2400:9380:92b6::/48
2400:9380:92b7::/48
240e:182:5401::/48
240e:182:5501::/48
240e:409:9000::/48
240e:409:9001::/48
240e:410:ff00::/48
240e:411:ff00::/48
240e:414:e710::/45
240e:414:e718::/45
240e:43d:fff1::/48
240e:43d:fff3::/48
240e:43d:fff4::/48
240e:43d:fff7::/48
240e:440:ac00::/48
240e:440:ac01::/48
240e:440:ac02::/48
240e:441:ac00::/48
240e:441:ac01::/48
240e:441:ac02::/48
240e:445:3f00::/48
240e:446:3f00::/48
240e:451:bfc0::/48
240e:451:bfe0::/48
240e:451:ffa0::/48
240e:451:ffc0::/48
240e:451:ffe0::/48
240e:456:fe00::/48
240e:457:fe00::/48
240e:469:f400::/48
240e:476:febf::/48
240e:476:feff::/48
240e:604:314::/48
240e:604:319::/48
240e:60e:8000::/48
240e:60e:8001::/48
240e:60e:e000::/35
240e:615:7000::/40
240e:61d:e600::/40
240e:628:10::/45
240e:62c:1f0::/44
240e:62f::/48
240e:638:f::/48
240e:63c:3f00::/44
240e:640:178::/48
240e:640:179::/48
240e:640:17a::/48
240e:640:17b::/48
240e:645:1000::/36
240e:648:1e::/48
240e:648:c00f::/48
240e:648:c40f::/48
240e:648:c80f::/48
240e:648:cc0f::/48
240e:648:d00f::/48
240e:648:d40f::/48
240e:648:d80f::/48
240e:648:dc0f::/48
240e:649:c00f::/48
240e:649:c40f::/48
240e:649:c80f::/48
240e:649:cc0f::/48
240e:649:d00f::/48
240e:649:d40f::/48
240e:649:d80f::/48
240e:649:dc0f::/48
240e:64e:d00::/44
240e:64e:de0::/48
240e:64e:dec::/48
240e:64e:ded::/48
240e:650:8000::/38
240e:659:f100::/48
240e:65f:e000::/36
240e:669:b000::/40
240e:670:d000::/36
240e:679:1001::/48
240e:688:ed00::/48
240e:699:7a00::/48
240e:699:7a01::/48
240e:699:7b00::/48
240e:699:7b06::/48
240e:699:7b07::/48
240e:699:7b08::/48
240e:699:7b0a::/48
240e:699:7b0c::/48
240e:699:7b0d::/48
240e:699:7b0f::/48
240e:699:7b11::/48
240e:699:7b12::/48
240e:699:bc00::/38
240e:6a0:d00::/48
240e:6a0:d03::/48
240e:6a0:d04::/48
240e:6a0:d07::/48
240e:6a0:d0a::/48
240e:713:f020::/48
240e:713:f021::/48
240e:733:4c0::/48
240e:733:4c1::/48
240e:767:f000::/48
240e:787:7000::/48
240e:787:7001::/48
240e:790:ff00::/40
240e:7b6::/31
240e:965:822::/48
240e:eb:e800::/37
240e:eb:f000::/37
240e:f6:8002::/48
240e:f6:8003::/48
240e:ff:c020::/48
240e:ff:c022::/48
240e:ff:c024::/48
240e:ff:c027::/48
240e:ff:c029::/48
2605:9d80:9003::/48
2605:9d80:9013::/48
2605:9d80:9023::/48
2605:9d80:9033::/48
2605:9d80:9042::/48
2605:9d80:9071::/48
2605:9d80:9092::/48
2804:1e48:9001::/48
2804:1e48:9002::/48
2a04:f580:9010::/48
2a04:f580:9012::/48
2a04:f580:9013::/48
2a04:f580:9020::/48
2a04:f580:9030::/48
2a04:f580:9040::/48
2a04:f580:9050::/48
2a04:f580:9060::/48
2a04:f580:9070::/48
2a04:f580:9080::/48
2a04:f580:9210::/48
2a04:f580:9212::/48
2a04:f580:9213::/48
2a04:f580:9220::/48
2a04:f580:9230::/48
2a04:f580:9240::/48
2a04:f580:9250::/48
2a04:f580:9260::/48
2a04:f580:9270::/48
2a04:f580:9280::/48
2a04:f580:9290::/48
2c0f:f7a8:9020::/48
2c0f:f7a8:9041::/48
2c0f:f7a8:9220::/48

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as4809.txt",
"count": 179,
"sha256": "1b43123532881e6dc9b08cfd56216a9eda028ff41b8ac6dfb4e8c51cb38d873c",
"generated_at": "2026-07-20T19:12:53Z"
}

View File

@ -1,418 +1,470 @@
2001:4510
2001:4511
2402:18a0
2402:f140:ff13
2402:f140:ff14
2404:6500:dcb3
2405:1480
2406:1e40
2406:cac0
2407:6c40
2407:6c40:1500
2408
2408:8000
2408:8000:10fe
2408:8000:10ff
2408:8000:2
2408:8000:3
2408:8000:5005
2408:8001
2408:802a
2408:802c
2408:803e
2408:8056
2408:80c2
2408:80c5
2408:80e2
2408:80e9
2408:80f5
2408:80f9
2408:815f
2408:8181
2408:8182
2408:8183
2408:81a2
2408:81a3
2408:8210
2408:8211
2408:8212
2408:8213
2408:8214
2408:8215
2408:821a
2408:821b
2408:8220
2408:8221
2408:8226
2408:822a
2408:822b
2408:822e
2408:822f
2408:8230
2408:8231
2408:8232
2408:8233
2408:8234
2408:8235
2408:8236
2408:8237
2408:8238
2408:8239
2408:823c
2408:823d
2408:8240
2408:8248
2408:8249
2408:824a
2408:824b
2408:824c
2408:824e
2408:824f
2408:8250
2408:8251
2408:8252
2408:8253
2408:8254
2408:825c
2408:825d
2408:825f
2408:8260
2408:8262
2408:8263
2408:8264
2408:8265
2408:8266
2408:826a
2408:826c
2408:826d
2408:826e
2408:826f
2408:8270
2408:8274
2408:8275
2408:8276
2408:8277
2408:8278
2408:8279
2408:827a
2408:8310
2408:8311
2408:8312
2408:8313
2408:832a
2408:832e
2408:832f
2408:8330
2408:8331
2408:8332
2408:8333
2408:8338
2408:8340
2408:8348
2408:8349
2408:834a
2408:834b
2408:834e
2408:834f
2408:8350
2408:8351
2408:8352
2408:8353
2408:8354
2408:8360
2408:8361
2408:8362
2408:8363
2408:8364
2408:8365
2408:836c
2408:836d
2408:836e
2408:836f
2408:8374
2408:8375
2408:8376
2408:8377
2408:8378
2408:8379
2408:837a
2408:8410
2408:8411
2408:8412
2408:8413
2408:8414
2408:8415
2408:8417
2408:8418
2408:841a
2408:841b
2408:841c
2408:841d
2408:841e
2408:8420
2408:8421
2408:8422
2408:8426
2408:8427
2408:842a
2408:842b
2408:842c
2408:842e
2408:8430
2408:8431
2408:8434
2408:8435
2408:8436
2408:8437
2408:8438
2408:8439
2408:843c
2408:843d
2408:843e
2408:843f
2408:8440
2408:8441
2408:8448
2408:844b
2408:844c
2408:844d
2408:844e
2408:844f
2408:8452
2408:8453
2408:8454
2408:8459
2408:845c
2408:845d
2408:8460
2408:8461
2408:8462
2408:8463
2408:8464
2408:8465
2408:8466
2408:8469
2408:846a
2408:846b
2408:846c
2408:846d
2408:846e
2408:846f
2408:8470
2408:8471
2408:8474
2408:8475
2408:8476
2408:8477
2408:8478
2408:8479
2408:847a
2408:84e3
2408:84e4
2408:84e5
2408:84e6
2408:84e7
2408:84e9
2408:84eb
2408:84ec
2408:84ed
2408:84ee
2408:84ef
2408:84f0
2408:84f1
2408:84f2
2408:84f4
2408:84f5
2408:84f6
2408:84f7
2408:84f8
2408:84f9
2408:84fa
2408:84fb
2408:84fc
2408:84fd
2408:84fe
2408:84ff
2408:856c
2408:856d
2408:8610
2408:8611
2408:8612
2408:8613
2408:8614
2408:8614:e20
2408:8615
2408:861a
2408:861b
2408:861c
2408:8620
2408:8621
2408:8624
2408:8625
2408:8626
2408:862a
2408:862b
2408:862d
2408:862e
2408:862f
2408:8630
2408:8631
2408:8632
2408:8633
2408:8634
2408:8635
2408:8636
2408:8637
2408:8638
2408:8639
2408:863c
2408:863d
2408:8640
2408:8642
2408:8648
2408:8649
2408:8649:5a00
2408:864c
2408:864e
2408:864f
2408:8650
2408:8651
2408:8652
2408:8653
2408:865c
2408:865d
2408:865f
2408:8660
2408:8662
2408:8663
2408:8664
2408:8665
2408:8666
2408:866a
2408:866b
2408:866c
2408:866d
2408:866e
2408:866f
2408:8670
2408:8674
2408:8675
2408:8676
2408:8677
2408:8678
2408:8679
2408:867a
2408:8710
2408:8711
2408:8712
2408:8713
2408:8719
2408:871a
2408:871b
2408:8720
2408:8721
2408:8722
2408:8723
2408:8726
2408:872b
2408:872f
2408:8730
2408:8731
2408:8732
2408:8733
2408:8734
2408:8735
2408:8736
2408:8738
2408:873c
2408:873d
2408:8740
2408:8742
2408:8748
2408:8749
2408:874a
2408:874b
2408:874c
2408:874d
2408:874e
2408:874f
2408:8752
2408:875c
2408:8760
2408:8762
2408:8763
2408:8764
2408:8765
2408:8766
2408:8768
2408:876a
2408:876c
2408:876d
2408:876e
2408:876f
2408:8770
2408:8772
2408:8773
2408:8774
2408:8776
2408:8777
2408:8778
2408:8779
2408:877a
2408:8812
2408:8813
2408:8814
2408:8815
2408:8818
2408:8819
2408:882c
2408:883a
2408:8862
2408:8863
2408:8864
2408:8865
2408:8866
2408:886e
2408:886f
2408:8872
2408:8878
2408:8879
2408:887e
2408:8912
2408:8913
2408:8914
2408:8915
2408:8916
2408:8917
2408:891c
2408:8920
2408:8924
2408:892c
2408:8936
2408:893a
2408:8940
2408:8948
2408:894c
2408:894e
2408:8956
2408:8957
2408:8962
2408:8963
2408:8964
2408:8965
2408:8966
2408:896c
2408:896e
2408:896f
2408:8972
2408:8978
2408:8979
2408:897a
2408:897b
2408:897e
2408:8a21
2408:8a22
2408:8a23
2408:8a24
2408:8a26
2408:8a27
2001:4510:1480::/41
2001:4511:1480::/41
2402:18a0::/32
2402:f140:ff13::/48
2402:f140:ff14::/48
2404:6500:dcb3::/48
2405:1480:3000::/47
2406:1e40:f012::/47
2406:cac0:200::/40
2406:cac0::/40
2407:6c40:1500::/48
2407:6c40:1600::/40
2408:8000:10fe::/48
2408:8000:10ff::/48
2408:8000:2000::/36
2408:8000:2::/48
2408:8000:3000::/36
2408:8000:3::/48
2408:8000:4000::/36
2408:8000:5000::/36
2408:8000:6000::/36
2408:8000:7000::/36
2408:8000:8000::/36
2408:8000:8010::/47
2408:8000::/48
2408:8000:a000::/36
2408:8000:b000::/36
2408:8000:c000::/36
2408:8000:d000::/36
2408:8000:e000::/36
2408:8000:f000::/36
2408:8001:1000::/36
2408:8001:2000::/36
2408:8001:4000::/36
2408:8001:5000::/36
2408:8001:6000::/36
2408:8001:7000::/36
2408:8001:8000::/36
2408:8001:9000::/36
2408:8001::/36
2408:8001:a000::/36
2408:8001:b000::/36
2408:8001:c000::/36
2408:8001:d000::/36
2408:8001:e000::/36
2408:8001:f000::/36
2408:802a:8000::/33
2408:802c::/32
2408:803e::/32
2408:8056::/32
2408:80c2::/33
2408:80c5::/33
2408:80e2::/33
2408:80e9:4000::/34
2408:80f5:4000::/34
2408:80f9:4000::/34
2408:815f:e000::/35
2408:8181:6000::/40
2408:8181:8000::/40
2408:8181::/40
2408:8181:a000::/40
2408:8181:a220::/44
2408:8181:e000::/40
2408:8182:c000::/40
2408:8183:4000::/40
2408:8183:8000::/40
2408:81a2:2000::/35
2408:81a2:4000::/35
2408:81a3:6000::/35
2408:8210::/32
2408:8211::/32
2408:8212::/32
2408:8213::/32
2408:8214::/32
2408:8215::/32
2408:821a::/32
2408:821b::/32
2408:8220::/32
2408:8221::/32
2408:8226::/32
2408:822a::/32
2408:822b::/32
2408:822e::/32
2408:822f::/32
2408:8230::/32
2408:8231::/32
2408:8232::/32
2408:8233::/32
2408:8234::/32
2408:8235::/32
2408:8236::/32
2408:8237::/32
2408:8238::/32
2408:8239::/32
2408:823c::/32
2408:823d::/32
2408:8240::/32
2408:8244::/30
2408:8248::/32
2408:8249::/32
2408:824a::/32
2408:824b::/32
2408:824c::/32
2408:824e::/32
2408:824f::/32
2408:8250::/32
2408:8251::/32
2408:8252::/32
2408:8253::/32
2408:8254::/32
2408:825c::/32
2408:825d::/32
2408:825f::/32
2408:8260::/32
2408:8262::/32
2408:8263::/32
2408:8264::/32
2408:8265::/32
2408:8266::/32
2408:826a::/32
2408:826c::/32
2408:826d::/32
2408:826e::/32
2408:826f::/32
2408:8270::/32
2408:8274::/32
2408:8275::/32
2408:8276::/32
2408:8277::/32
2408:8278::/32
2408:8279::/32
2408:827a::/32
2408:8310::/32
2408:8311::/32
2408:8312::/32
2408:8313::/32
2408:832a::/32
2408:832e::/32
2408:832f::/32
2408:8330::/32
2408:8331::/32
2408:8332::/32
2408:8333::/32
2408:8338::/32
2408:8340::/32
2408:8344::/30
2408:8348::/32
2408:8349::/32
2408:834a::/32
2408:834b::/32
2408:834e::/32
2408:834f::/32
2408:8350::/32
2408:8351::/32
2408:8352::/32
2408:8353::/32
2408:8354::/32
2408:8360::/32
2408:8361::/32
2408:8362::/32
2408:8363::/32
2408:8364::/32
2408:8365::/32
2408:836c::/32
2408:836d::/32
2408:836e::/32
2408:836f::/32
2408:8374::/32
2408:8375::/32
2408:8376::/32
2408:8377::/32
2408:8378::/32
2408:8379::/32
2408:837a::/32
2408:8410::/32
2408:8411::/32
2408:8412::/32
2408:8413::/32
2408:8414::/32
2408:8415::/32
2408:8417::/32
2408:8418::/32
2408:841a::/32
2408:841b::/32
2408:841c::/32
2408:841d::/32
2408:841e::/32
2408:8420::/32
2408:8421::/32
2408:8422::/32
2408:8426::/32
2408:8427::/32
2408:842a::/32
2408:842b::/32
2408:842c::/32
2408:842e::/32
2408:8430::/32
2408:8431::/32
2408:8434::/32
2408:8435::/32
2408:8436::/32
2408:8437::/32
2408:8438::/32
2408:8439::/32
2408:843c::/32
2408:843d::/32
2408:843e::/32
2408:843f::/32
2408:8440::/32
2408:8441::/32
2408:8444::/30
2408:8448::/32
2408:844b::/32
2408:844c::/32
2408:844d::/32
2408:844e::/32
2408:844f::/32
2408:8452::/32
2408:8453::/32
2408:8454::/32
2408:845c::/32
2408:845d::/32
2408:8460::/32
2408:8461::/32
2408:8462::/32
2408:8463::/32
2408:8464::/32
2408:8465::/32
2408:8466::/32
2408:8469::/32
2408:846a::/32
2408:846b::/32
2408:846c::/32
2408:846d::/32
2408:846e::/32
2408:846f::/32
2408:8470::/32
2408:8471::/32
2408:8474::/32
2408:8475::/32
2408:8476::/32
2408:8477::/32
2408:8478::/32
2408:8479::/32
2408:847a::/32
2408:84e3::/32
2408:84e4::/32
2408:84e5::/32
2408:84e6::/32
2408:84e7::/32
2408:84e9::/32
2408:84eb::/32
2408:84ec::/32
2408:84ed::/32
2408:84ee::/32
2408:84ef::/32
2408:84f0::/32
2408:84f1::/32
2408:84f2::/32
2408:84f4::/32
2408:84f5::/32
2408:84f6::/32
2408:84f7::/32
2408:84f8::/32
2408:84f9::/32
2408:84fa::/32
2408:84fb::/32
2408:84fc::/32
2408:84fd::/32
2408:84fe::/32
2408:84ff::/32
2408:856c::/32
2408:856d::/32
2408:8610::/32
2408:8611::/32
2408:8612::/32
2408:8613::/32
2408:8614::/32
2408:8614:e20::/48
2408:8615::/32
2408:861a::/32
2408:861b::/32
2408:861c::/32
2408:8620::/32
2408:8621::/32
2408:8624::/32
2408:8625::/32
2408:8626::/32
2408:862a::/32
2408:862b::/32
2408:862d::/32
2408:862e::/32
2408:862f::/32
2408:8630::/32
2408:8631::/32
2408:8632::/32
2408:8633::/32
2408:8634::/32
2408:8635::/32
2408:8636::/32
2408:8637::/32
2408:8638::/32
2408:8639::/32
2408:863c::/32
2408:863d::/32
2408:8640::/32
2408:8642::/32
2408:8644::/30
2408:8648::/32
2408:8649::/32
2408:864c::/32
2408:864e::/32
2408:864f::/32
2408:8650::/32
2408:8651::/32
2408:8652::/32
2408:8653::/32
2408:865c::/32
2408:865d::/32
2408:865f::/32
2408:8660::/32
2408:8662::/32
2408:8663::/32
2408:8664::/32
2408:8665::/32
2408:8666::/32
2408:866a::/32
2408:866b::/32
2408:866c:200::/42
2408:866c::/32
2408:866d::/32
2408:866e::/32
2408:866f::/32
2408:8670::/32
2408:8674::/32
2408:8675::/32
2408:8676::/32
2408:8677::/32
2408:8678::/32
2408:8679::/32
2408:867a::/32
2408:8710::/32
2408:8711::/32
2408:8712::/32
2408:8713::/32
2408:8719::/32
2408:871a::/32
2408:871b::/32
2408:8720::/32
2408:8721::/32
2408:8722::/32
2408:8723::/32
2408:8726::/32
2408:872b::/32
2408:872b:e00::/47
2408:872f::/32
2408:8730::/32
2408:8731::/32
2408:8732::/32
2408:8733::/32
2408:8734::/32
2408:8735::/32
2408:8736::/32
2408:8738::/32
2408:873c::/32
2408:873d::/32
2408:8740::/32
2408:8742::/32
2408:8744::/30
2408:8748::/32
2408:8749::/32
2408:874a::/32
2408:874b::/32
2408:874c::/32
2408:874d::/32
2408:874e::/32
2408:874f::/32
2408:8752::/32
2408:875c::/32
2408:8760::/32
2408:8762::/32
2408:8763::/32
2408:8764::/32
2408:8765::/32
2408:8766::/32
2408:8768::/32
2408:876a::/32
2408:876c:1700::/44
2408:876c:1740::/44
2408:876c:17c0::/44
2408:876c::/32
2408:876d::/32
2408:876e::/32
2408:876f::/32
2408:8770::/32
2408:8772::/32
2408:8773::/32
2408:8774::/32
2408:8776::/32
2408:8777::/32
2408:8778::/32
2408:8779::/32
2408:877a::/32
2408:8812::/32
2408:8813::/32
2408:8814::/32
2408:8815::/32
2408:8818::/32
2408:8819::/32
2408:882c::/32
2408:883a::/32
2408:8862::/32
2408:8863::/32
2408:8864::/32
2408:8865::/32
2408:8866::/32
2408:886e::/32
2408:886f::/32
2408:8872::/32
2408:8878::/32
2408:8879::/32
2408:887e::/32
2408:8912::/32
2408:8913::/32
2408:8914::/32
2408:8915::/32
2408:8916::/32
2408:8917::/32
2408:891c::/32
2408:8920::/32
2408:8924::/32
2408:892c::/32
2408:8936::/32
2408:893a::/32
2408:8940::/32
2408:8948::/32
2408:894c::/32
2408:894e::/32
2408:8962::/32
2408:8963::/32
2408:8964::/32
2408:8965::/32
2408:8966::/32
2408:896c::/32
2408:896e::/32
2408:896f::/32
2408:8972::/32
2408:8978::/32
2408:8979::/32
2408:897a::/32
2408:897b::/32
2408:897e::/32
2408:8a21:4000::/36
2408:8a21:5000::/36
2408:8a22:1000::/36
2408:8a22::/36
2408:8a23:4000::/36
2408:8a23:5000::/36
2408:8a23:6000::/36
2408:8a23:7000::/36
2408:8a24:4000::/36
2408:8a24:5000::/36
2408:8a24:6000::/36
2408:8a24:7000::/36
2408:8a26:c000::/36
2408:8a26:d000::/36
2408:8a26:e000::/36
2408:8a26:f000::/36
2408:8a27:4000::/36
2408:8a27:5000::/36

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as4837.txt",
"count": 470,
"sha256": "d109b070f48e97a39e94dc831aab2923b6c440de80621a58319b1ba5926fd60c",
"generated_at": "2026-07-20T19:12:53Z"
}

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as58453.txt",
"count": 17,
"sha256": "e7e579da764e9dedf84145b5c4cdc51c4b2841517adbc6edb206896b40710119",
"generated_at": "2026-07-20T19:12:53Z"
}

View File

@ -1,2 +1,2 @@
2402:4f00
2402:4f00:f000
2402:4f00:f000::/36
2402:4f00:f000::/48

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as58807.txt",
"count": 2,
"sha256": "0765c7eefa122984fe69678b60ba99aa605d52601ef4ebf988c4e691e91c5361",
"generated_at": "2026-07-20T19:12:53Z"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as9808.txt",
"count": 7171,
"sha256": "c362e447b515ca510b10fd37ba50189c3551a35dede88399190bc869b6fbe66b",
"generated_at": "2026-07-20T19:12:54Z"
}

View File

@ -1,93 +1,144 @@
2408:8120
2408:8120:1
2408:8120:2
2408:8256:226d
2408:8256:228b
2408:827a:8ff
2408:8411:c0c0
2408:8411:c0c1
2408:8411:c0c2
2408:8411:c0c3
2408:8411:c0c4
2408:8411:c0c5
2408:8417
2408:8418
2408:841d
2408:841e
2408:8435
2408:843e:e010
2408:843e:e011
2408:843e:e012
2408:843e:e080
2408:843e:e081
2408:843e:e082
2408:8441
2408:8444
2408:844c:cb09
2408:844c:cb0a
2408:844c:cb0b
2408:844d:cb09
2408:844d:cb0a
2408:844d:cb0b
2408:844f
2408:8462
2408:8463
2408:8469:fc00
2408:846a
2408:846b
2408:8471:fa00
2408:8471:fa01
2408:8471:fa02
2408:8471:fb00
2408:8471:fb01
2408:8471:fb02
2408:8474
2408:8478
2408:847a:ff20
2408:847a:ff21
2408:847a:ff22
2408:847a:ff40
2408:847a:ff41
2408:847a:ff42
2408:8610:3bff
2408:8614:1f0
2408:8614:af0
2408:861c:1fff
2408:8625:10fb
2408:8625:fe
2408:8626:f200
2408:862b
2408:862e:2ff
2408:8634:1015
2408:8638:116
2408:8640
2408:8649:1a00
2408:8649:2a00
2408:864c:10ff
2408:8651:ff00
2408:8652:ff00
2408:8656:a52
2408:865c
2408:8660:100
2408:8660:a100
2408:8660:ab00
2408:8660:b500
2408:8660:bf00
2408:8666:ff00
2408:866a:a05
2408:866c:ff00
2408:8670:800
2408:8678:1400
2408:8756:3efd
2408:8a00
2408:8a01
2408:8a02
2408:8a04
2408:8a06
2408:8a06:1
2408:8a06:100
2408:8a06:101
2408:8a07
2408:8a26:ee10
2408:8a26:f020
2408:8a26:f950
2408:8120:1::/48
2408:8120:2::/48
2408:8120:7000::/36
2408:8256:226d::/48
2408:8256:228b::/48
2408:827a:8ff::/48
2408:8411:c0c0::/48
2408:8411:c0c1::/48
2408:8411:c0c2::/48
2408:8411:c0c3::/48
2408:8411:c0c4::/48
2408:8411:c0c5::/48
2408:8417:f000::/44
2408:8417:f010::/44
2408:8417:f020::/44
2408:8418:f000::/44
2408:8418:f010::/44
2408:8418:f020::/44
2408:841d:ef20::/44
2408:841d:ef30::/44
2408:841e:ef10::/44
2408:841e:ef20::/44
2408:841e:ef30::/44
2408:8435:b490::/47
2408:8435:b492::/47
2408:8435:b494::/47
2408:8435:b496::/47
2408:8435:b498::/47
2408:8435:b49a::/47
2408:843e:e010::/48
2408:843e:e011::/48
2408:843e:e012::/48
2408:843e:e080::/48
2408:843e:e081::/48
2408:843e:e082::/48
2408:8441:fe00::/44
2408:8441:fe10::/44
2408:8441:fe20::/44
2408:8441:ff00::/44
2408:8441:ff10::/44
2408:8441:ff20::/44
2408:8444:d500::/44
2408:8444:d580::/44
2408:8444:d700::/44
2408:8444:d780::/44
2408:8444:d900::/44
2408:8444:d980::/44
2408:844c:cb09::/48
2408:844c:cb0a::/48
2408:844c:cb0b::/48
2408:844d:cb09::/48
2408:844d:cb0a::/48
2408:844d:cb0b::/48
2408:844f:d408::/47
2408:844f:d40a::/47
2408:844f:d40c::/47
2408:844f:d500::/47
2408:844f:d502::/47
2408:844f:d504::/47
2408:8462:ff00::/44
2408:8462:ff10::/44
2408:8462:ff20::/44
2408:8463:ff00::/44
2408:8463:ff10::/44
2408:8463:ff20::/44
2408:8469:fc00::/48
2408:846a:b600::/44
2408:846a:b610::/44
2408:846a:b620::/44
2408:846b:b600::/44
2408:846b:b610::/44
2408:846b:b620::/44
2408:8471:fa00::/48
2408:8471:fa01::/48
2408:8471:fa02::/48
2408:8471:fb00::/48
2408:8471:fb01::/48
2408:8471:fb02::/48
2408:8474:fb10::/44
2408:8474:fb20::/44
2408:8474:fb30::/44
2408:8474:fc10::/44
2408:8474:fc20::/44
2408:8474:fc30::/44
2408:8478:fb10::/44
2408:8478:fb20::/44
2408:8478:fb30::/44
2408:8478:fc10::/44
2408:8478:fc20::/44
2408:8478:fc30::/44
2408:847a:ff20::/48
2408:847a:ff21::/48
2408:847a:ff22::/48
2408:847a:ff40::/48
2408:847a:ff41::/48
2408:847a:ff42::/48
2408:8610:3bff::/48
2408:8614:1f0::/48
2408:8614:af0::/48
2408:861c:1fff::/48
2408:8625:10fb::/48
2408:8625:fe::/48
2408:8626:f200::/48
2408:862b::/48
2408:862e:2ff::/48
2408:8634:1015::/48
2408:8638:116::/48
2408:8640:f100::/40
2408:8649:1a00::/48
2408:8649:2a00::/48
2408:864c:10ff::/48
2408:8651:ff00::/48
2408:8652:ff00::/48
2408:8656:a52::/48
2408:865c:f0::/44
2408:8660:100::/48
2408:8660:a100::/48
2408:8660:ab00::/48
2408:8660:b500::/48
2408:8660:bf00::/48
2408:8666:ff00::/48
2408:866a:a05::/48
2408:866c:ff00::/48
2408:8670:800::/48
2408:8678:1400::/48
2408:8756:3efd::/48
2408:8a00:c000::/36
2408:8a00:d000::/38
2408:8a00:d400::/38
2408:8a00:e000::/36
2408:8a00:f000::/36
2408:8a01::/36
2408:8a02:b110::/44
2408:8a02:b120::/44
2408:8a04:8000::/36
2408:8a04:e000::/40
2408:8a06:100::/48
2408:8a06:101::/48
2408:8a06:1::/48
2408:8a06::/48
2408:8a07::/40
2408:8a26:ee10::/48
2408:8a26:f020::/48
2408:8a26:f950::/48

View File

@ -0,0 +1,7 @@
{
"schema": "backtrace.asn-prefixes/v1",
"file": "as9929.txt",
"count": 144,
"sha256": "a5f65f08a447982cd2c8611005261deab3400f1232ae594fb98f6bfb3fe09084",
"generated_at": "2026-07-20T19:12:54Z"
}

View File

@ -2,7 +2,10 @@ package backtrace
import (
"context"
_ "embed"
"crypto/sha256"
"embed"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
@ -18,6 +21,7 @@ import (
)
const (
ASNPrefixRegistrySchema = "backtrace.asn-prefixes/v1"
ASNPrefixRegistryRawBaseURL = "https://raw.githubusercontent.com/oneclickvirt/backtrace/main/bk/prefix"
ASNPrefixRegistryCDNBaseURL = "https://cdn.spiritlhl.net/" + ASNPrefixRegistryRawBaseURL
)
@ -26,8 +30,9 @@ var knownPrefixASNs = []string{"AS23764", "AS4134", "AS4809", "AS4837", "AS58453
var prefixFragmentPattern = regexp.MustCompile(`^[0-9a-fA-F:]+$`)
type ASNPrefixRegistrySource struct {
Name string
Base string
Name string
Base string
ValidateManifest bool
}
type ASNPrefixRegistryLoadResult struct {
@ -39,14 +44,17 @@ type ASNPrefixRegistryLoadResult struct {
var activeASNPrefixes atomic.Value // stores map[string][]string; maps are immutable after publication
var refreshASNPrefixesOnce sync.Once
//go:embed prefix/*.txt.manifest.json
var embeddedPrefixManifestFS embed.FS
func init() {
activeASNPrefixes.Store(cloneASNPrefixes(asnPrefixes))
}
func DefaultASNPrefixRegistrySources() []ASNPrefixRegistrySource {
return []ASNPrefixRegistrySource{
{Name: "cdn", Base: ASNPrefixRegistryCDNBaseURL},
{Name: "raw", Base: ASNPrefixRegistryRawBaseURL},
{Name: "cdn", Base: ASNPrefixRegistryCDNBaseURL, ValidateManifest: true},
{Name: "raw", Base: ASNPrefixRegistryRawBaseURL, ValidateManifest: true},
}
}
@ -59,7 +67,7 @@ func LoadASNPrefixRegistry(ctx context.Context, client *http.Client, sources []A
}
var lastErr error
for index, source := range sources {
prefixes, err := fetchASNPrefixSource(ctx, client, source.Base)
prefixes, err := fetchASNPrefixSource(ctx, client, source)
if err != nil {
lastErr = fmt.Errorf("load %s ASN prefixes: %w", source.Name, err)
continue
@ -68,6 +76,9 @@ func LoadASNPrefixRegistry(ctx context.Context, client *http.Client, sources []A
}
embedded := cloneASNPrefixes(asnPrefixes)
if len(embedded) > 0 {
if err := validateEmbeddedPrefixManifests(); err != nil {
return ASNPrefixRegistryLoadResult{}, fmt.Errorf("validate embedded ASN prefix manifests: %w", err)
}
return ASNPrefixRegistryLoadResult{Prefixes: embedded, Source: "embedded", Fallback: true}, nil
}
if lastErr == nil {
@ -97,7 +108,16 @@ func StartASNPrefixRefresh() {
})
}
func fetchASNPrefixSource(ctx context.Context, client *http.Client, base string) (map[string][]string, error) {
type prefixManifest struct {
Schema string `json:"schema"`
File string `json:"file"`
Count int `json:"count"`
SHA256 string `json:"sha256"`
GeneratedAt string `json:"generated_at"`
}
func fetchASNPrefixSource(ctx context.Context, client *http.Client, source ASNPrefixRegistrySource) (map[string][]string, error) {
base := source.Base
parsed, err := url.Parse(strings.TrimRight(base, "/"))
if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") || parsed.Hostname() == "" {
return nil, errors.New("invalid ASN prefix source")
@ -111,27 +131,25 @@ func fetchASNPrefixSource(ctx context.Context, client *http.Client, base string)
for _, asn := range knownPrefixASNs {
go func(asn string) {
endpoint := strings.TrimRight(base, "/") + "/" + strings.ToLower(asn) + ".txt"
request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
var manifestData []byte
if source.ValidateManifest {
fetchedManifest, fetchErr := fetchPrefixResource(ctx, client, endpoint+".manifest.json")
if fetchErr != nil {
results <- prefixResult{asn: asn, err: fmt.Errorf("manifest: %w", fetchErr)}
return
}
manifestData = fetchedManifest
}
data, err := fetchPrefixResource(ctx, client, endpoint)
if err != nil {
results <- prefixResult{asn: asn, err: err}
return
}
request.Header.Set("Accept", "text/plain")
request.Header.Set("User-Agent", "oneclickvirt-backtrace/asn-prefix-registry-v1")
response, err := client.Do(request)
if err != nil {
results <- prefixResult{asn: asn, err: err}
return
}
data, readErr := io.ReadAll(io.LimitReader(response.Body, 4<<20))
response.Body.Close()
if readErr != nil {
results <- prefixResult{asn: asn, err: readErr}
return
}
if response.StatusCode != http.StatusOK {
results <- prefixResult{asn: asn, err: fmt.Errorf("HTTP %d", response.StatusCode)}
return
if source.ValidateManifest {
if err := validatePrefixManifest(manifestData, data, strings.ToLower(asn)+".txt"); err != nil {
results <- prefixResult{asn: asn, err: err}
return
}
}
values, parseErr := parseASNPrefixLines(data)
results <- prefixResult{asn: asn, values: values, err: parseErr}
@ -148,6 +166,88 @@ func fetchASNPrefixSource(ctx context.Context, client *http.Client, base string)
return result, nil
}
func fetchPrefixResource(ctx context.Context, client *http.Client, endpoint string) ([]byte, error) {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return nil, err
}
request.Header.Set("Accept", "text/plain, application/json")
request.Header.Set("User-Agent", "oneclickvirt-backtrace/asn-prefix-registry-v1")
response, err := client.Do(request)
if err != nil {
return nil, err
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP %d", response.StatusCode)
}
return io.ReadAll(io.LimitReader(response.Body, 4<<20))
}
func validatePrefixManifest(data, snapshot []byte, expectedFile string) error {
var manifest prefixManifest
decoder := json.NewDecoder(strings.NewReader(string(data)))
decoder.DisallowUnknownFields()
if err := decoder.Decode(&manifest); err != nil {
return fmt.Errorf("decode manifest: %w", err)
}
var extra any
if err := decoder.Decode(&extra); err != io.EOF {
return errors.New("manifest contains trailing JSON")
}
if manifest.Schema != ASNPrefixRegistrySchema || manifest.File != expectedFile || manifest.Count < 1 {
return errors.New("manifest schema, file, or count is invalid")
}
if _, err := time.Parse(time.RFC3339, manifest.GeneratedAt); err != nil {
return fmt.Errorf("manifest generated_at is invalid: %w", err)
}
hash := sha256.Sum256(snapshot)
if !strings.EqualFold(manifest.SHA256, hex.EncodeToString(hash[:])) {
return errors.New("manifest SHA-256 does not match snapshot")
}
values, err := parseASNPrefixLines(snapshot)
if err != nil {
return err
}
if len(values) != manifest.Count {
return fmt.Errorf("manifest count %d does not match snapshot count %d", manifest.Count, len(values))
}
return nil
}
func validateEmbeddedPrefixManifests() error {
for _, asn := range knownPrefixASNs {
name := strings.ToLower(asn) + ".txt"
manifest, err := embeddedPrefixManifestFS.ReadFile("prefix/" + name + ".manifest.json")
if err != nil {
return err
}
var snapshot []byte
switch asn {
case "AS23764":
snapshot = []byte(as23764Data)
case "AS4134":
snapshot = []byte(as4134Data)
case "AS4809":
snapshot = []byte(as4809Data)
case "AS4837":
snapshot = []byte(as4837Data)
case "AS58453":
snapshot = []byte(as58453Data)
case "AS58807":
snapshot = []byte(as58807Data)
case "AS9808":
snapshot = []byte(as9808Data)
case "AS9929":
snapshot = []byte(as9929Data)
}
if err := validatePrefixManifest(manifest, snapshot, name); err != nil {
return fmt.Errorf("%s: %w", asn, err)
}
}
return nil
}
func parseASNPrefixLines(data []byte) ([]string, error) {
seen := make(map[string]struct{})
values := make([]string, 0)

View File

@ -2,8 +2,13 @@ package backtrace
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"
)
@ -16,20 +21,61 @@ func TestParseASNPrefixLinesNormalizesAndDeduplicates(t *testing.T) {
func TestLoadASNPrefixRegistryUsesRawAfterCDNFailure(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if request.URL.Path == "/bad/as23764.txt" {
http.Error(writer, "bad", http.StatusBadGateway)
path := strings.TrimPrefix(request.URL.Path, "/")
parts := strings.Split(path, "/")
if len(parts) != 2 {
http.NotFound(writer, request)
return
}
_, _ = writer.Write([]byte("2409:8000\n"))
base, file := parts[0], parts[1]
snapshot := []byte("2409:8000\n")
if base == "bad" && file == "as23764.txt.manifest.json" {
_, _ = writer.Write([]byte(`{}`))
return
}
if strings.HasSuffix(file, ".manifest.json") {
hash := sha256.Sum256(snapshot)
manifest, _ := json.Marshal(prefixManifest{Schema: ASNPrefixRegistrySchema, File: strings.TrimSuffix(file, ".manifest.json"), Count: 1, SHA256: hex.EncodeToString(hash[:]), GeneratedAt: "2026-01-01T00:00:00Z"})
_, _ = writer.Write(manifest)
return
}
_, _ = writer.Write(snapshot)
}))
defer server.Close()
sources := []ASNPrefixRegistrySource{{Name: "cdn", Base: server.URL + "/bad"}, {Name: "raw", Base: server.URL + "/good"}}
sources := []ASNPrefixRegistrySource{{Name: "cdn", Base: server.URL + "/bad", ValidateManifest: true}, {Name: "raw", Base: server.URL + "/good", ValidateManifest: true}}
loaded, err := LoadASNPrefixRegistry(context.Background(), server.Client(), sources)
if err != nil || loaded.Source != "raw" || !loaded.Fallback || len(loaded.Prefixes) != len(knownPrefixASNs) {
t.Fatalf("unexpected load: %+v, %v", loaded, err)
}
}
func TestValidatePrefixManifestRejectsHashAndCountMismatch(t *testing.T) {
snapshot := []byte("2409:8000\n")
manifest := prefixManifest{Schema: ASNPrefixRegistrySchema, File: "as23764.txt", Count: 2, SHA256: strings.Repeat("0", 64), GeneratedAt: "2026-01-01T00:00:00Z"}
data, err := json.Marshal(manifest)
if err != nil {
t.Fatal(err)
}
if err := validatePrefixManifest(data, snapshot, "as23764.txt"); err == nil {
t.Fatal("invalid manifest unexpectedly accepted")
}
}
func TestValidateEmbeddedPrefixManifests(t *testing.T) {
if err := validateEmbeddedPrefixManifests(); err != nil {
t.Fatal(err)
}
}
func TestEmbeddedManifestFilesArePresent(t *testing.T) {
for _, asn := range knownPrefixASNs {
name := strings.ToLower(asn) + ".txt.manifest.json"
if _, err := embeddedPrefixManifestFS.ReadFile(filepath.Join("prefix", name)); err != nil {
t.Fatalf("missing embedded manifest %s: %v", name, err)
}
}
}
func TestLoadASNPrefixRegistryEmbeddedFallback(t *testing.T) {
loaded, err := LoadASNPrefixRegistry(context.Background(), nil, nil)
if err != nil || loaded.Source != "embedded" || !loaded.Fallback || len(loaded.Prefixes) == 0 {

View File

@ -3,6 +3,8 @@ package main
import (
"bytes"
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"flag"
@ -87,17 +89,109 @@ func updatePrefixes(ctx context.Context, client *http.Client, config updateConfi
valuesByASN[asn] = values
}
for _, asn := range knownASNs {
if err := writePrefixFile(filepath.Join(config.OutputDir, strings.ToLower(asn)+".txt"), valuesByASN[asn]); err != nil {
path := filepath.Join(config.OutputDir, strings.ToLower(asn)+".txt")
if err := writePrefixFile(path, valuesByASN[asn]); err != nil {
if errors.Is(err, errPrefixCountDrop) {
fmt.Fprintf(os.Stderr, "skip %s: %v\n", asn, err)
continue
current, readErr := os.ReadFile(path)
if readErr != nil {
return readErr
}
valuesByASN[asn] = prefixValuesFromFile(current)
} else {
return err
}
}
if err := writePrefixManifest(path); err != nil {
return err
}
}
return nil
}
type prefixManifest struct {
Schema string `json:"schema"`
File string `json:"file"`
Count int `json:"count"`
SHA256 string `json:"sha256"`
GeneratedAt string `json:"generated_at"`
}
func prefixValuesFromFile(data []byte) []string {
values := make([]string, 0)
for _, line := range strings.Split(string(data), "\n") {
if value := strings.TrimSpace(line); value != "" {
values = append(values, value)
}
}
return values
}
func writePrefixManifest(snapshotPath string) error {
snapshot, err := os.ReadFile(snapshotPath)
if err != nil {
return err
}
values := prefixValuesFromFile(snapshot)
if len(values) == 0 {
return errors.New("prefix snapshot is empty")
}
hash := sha256.Sum256(snapshot)
fileName := filepath.Base(snapshotPath)
sha256Value := hex.EncodeToString(hash[:])
manifestPath := snapshotPath + ".manifest.json"
if current, readErr := os.ReadFile(manifestPath); readErr == nil {
var existing prefixManifest
decoder := json.NewDecoder(bytes.NewReader(current))
decoder.DisallowUnknownFields()
var extra any
if decoder.Decode(&existing) == nil && decoder.Decode(&extra) == io.EOF &&
existing.Schema == "backtrace.asn-prefixes/v1" && existing.File == fileName &&
existing.Count == len(values) && strings.EqualFold(existing.SHA256, sha256Value) {
if _, timeErr := time.Parse(time.RFC3339, existing.GeneratedAt); timeErr == nil {
return nil
}
}
} else if !errors.Is(readErr, os.ErrNotExist) {
return readErr
}
manifest := prefixManifest{Schema: "backtrace.asn-prefixes/v1", File: fileName, Count: len(values), SHA256: sha256Value, GeneratedAt: time.Now().UTC().Format(time.RFC3339)}
data, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}
data = append(data, '\n')
return writeAtomicFile(manifestPath, data)
}
func writeAtomicFile(output string, data []byte) error {
if err := os.MkdirAll(filepath.Dir(output), 0o755); err != nil {
return err
}
temporary, err := os.CreateTemp(filepath.Dir(output), ".prefix-manifest-*")
if err != nil {
return err
}
temporaryName := temporary.Name()
defer os.Remove(temporaryName)
if err := temporary.Chmod(0o644); err != nil {
_ = temporary.Close()
return err
}
if _, err := temporary.Write(data); err != nil {
_ = temporary.Close()
return err
}
if err := temporary.Sync(); err != nil {
_ = temporary.Close()
return err
}
if err := temporary.Close(); err != nil {
return err
}
return os.Rename(temporaryName, output)
}
func extractIPv6Prefixes(data []byte) ([]string, error) {
var response struct {
Status string `json:"status"`

View File

@ -1,6 +1,10 @@
package main
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"os"
"path/filepath"
@ -30,3 +34,37 @@ func TestWritePrefixFileProtectsLargeCountDrop(t *testing.T) {
t.Fatalf("count drop error = %v", err)
}
}
func TestWritePrefixManifestPreservesGeneratedAtWhenSnapshotIsUnchanged(t *testing.T) {
directory := t.TempDir()
snapshotPath := filepath.Join(directory, "as64500.txt")
if err := os.WriteFile(snapshotPath, []byte("2001:db8::/48\n"), 0o644); err != nil {
t.Fatal(err)
}
manifestPath := snapshotPath + ".manifest.json"
old := prefixManifest{Schema: "backtrace.asn-prefixes/v1", File: "as64500.txt", Count: 1, SHA256: "", GeneratedAt: "2020-01-02T03:04:05Z"}
data, err := os.ReadFile(snapshotPath)
if err != nil {
t.Fatal(err)
}
// Seed a valid manifest with an old timestamp. The updater must retain it.
hash := sha256.Sum256(data)
old.SHA256 = hex.EncodeToString(hash[:])
encoded, err := json.Marshal(old)
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(manifestPath, append(encoded, '\n'), 0o644); err != nil {
t.Fatal(err)
}
if err := writePrefixManifest(snapshotPath); err != nil {
t.Fatal(err)
}
actual, err := os.ReadFile(manifestPath)
if err != nil {
t.Fatal(err)
}
if !bytes.Contains(actual, []byte(`"generated_at":"2020-01-02T03:04:05Z"`)) {
t.Fatalf("generated_at was not preserved: %s", actual)
}
}