#!C:\bin\perl # enitel.pl - Convierte ASN.1 de R10 a R8. # David Moreno Garza # GPL, blah blah. my $time1 = localtime; print "Empezando el script a las ".$time1."\n"; my @borrar_a0 = ('9f41','9f42','9f44','9f45','9f46','9f47','9f48','9f49','9f4a','9f4b','9f4c','9f4d','9f4e','9f4f','9f50','9f51','9f52','9f53','9f54','9f55','9f56','9f57','9f58','9f59','9f5a','9f5b','9f5c','bf5d','9f66'); my @borrar_a1 = ('9f5d','9f63','9f64','9f65','9f66','9f67','9f68','9f69','9f6a','9f6b','9f6c','9f6d','9f6e','9f6f','9f70','9f71','9f72','9f73','9f74','9f75','9f76','9f77','9f78','9f7c','9f7d','9f7e','9f7f','9f8100','9f8101','9f8102','9f8103','9f8104','9f8105','9f8106','9f8107','9f8108','9f8109','9f810a','9f810b','9f810c','9f810d'); my @borrar_a2 = ('9f37','9f38','9f39','9f3a','9f3b','9f3c','9f3d','9f3e','9f3f','9f40','9f41','9f42','9f43','9f44','9f66'); my @borrar_a3 = ('9f4b','9f4c','9f4d','9f4e','9f4f','9f50','9f51','9f52','9f53','9f54','9f55','9f56','9f57','9f58','9f59','9f5a','95b','9f5c','9f5d','9f5e','9f5f','9f60','9f61','9f62','9f63','9f64','9f66'); my @borrar_a4 = ('9f50','9f56','9f57','9f58','9f59','9f5a','9f5b','9f5C','9f5d','9f5e','9f5f','9f60','9f61','9f62','9f63','9f64','9f65','9f66','9f67','9f68','9f69','9f6a','9f6b','9f6c','9f6d','9f6e','9f6f','9f70','9f71','9f72','9f73'); my @borrar_a5 = ('9f20','9f21','9f22','9f23','bf24','9f25','9f26','9f27','9f28','9f29','9f2a','9f2b','9f2c','9f66'); my @borrar_a7 = ('9f21','9f22','9f23','9f66'); my @borrar_a8 = ('9f66'); my @borrar_a9 = ('9f24','9f66'); my @arr; my %res; my $i = 0; my $bloop = 1; my $ciclo = 0; my $size = -s $ARGV[0]; my($sec, $min, $hr, $day, $mon, $year, $week, $doy, $isdst) = localtime(time); $mon++; $year += 1900; my $secuencia = $1 if $ARGV[0] =~ (/.+(....)$/); my $destfile = "SWINCSEMULTI0".$secuencia."_".$year.$mon.$day.".dat"; open(OUT, ">> $destfile") or die("Problemas al abrir el archivo destino.\n"); binmode(OUT); print "Abriendo el archivo origen...\n"; open(FILE, "< $ARGV[0]") or die("Problemas para leer el archivo origen: $!"); print "Cambiando el modo a ASN1...\n"; binmode(FILE); print "Empezando a leer el contenido y guardandolo en buffer...\n"; read(FILE, $buffer, $size); print "Archivo leido. Comenzando parseo....\n"; #close(FILE); print "Agregando \$buffer al arreglo..."; foreach (split(//, $buffer)) { $arr[$i] = sprintf("%02x", ord($_)); $i++; } print " Hecho.\n"; $i = 0; open(OUT, ">> $destfile") or die("Problemas al abrir el archivo destino.\n"); binmode(OUT); foreach(@arr) { # sleep 0.25 if $debug; $i++; if($act) { $hex = sprintf('%x', $reallong) unless $res{$ciclo}; $res{$ciclo}[0] = $hex unless $res{$ciclo}; $res{$ciclo}[$bloop] = $_; $bloop++; next if $reallong+1 != $bloop; $ciclo++; undef $act; $bloop = 1; undef $reallong; next; } if($longlength) { $loop++; $reallong .= $_; next if $longlength != $loop; $reallong = hex $reallong; $act = 1; undef $longlength; undef $head; undef $loop; } if($head) { $long = hex $_; if($long < 128) { $reallong = $long; $act = 1; undef $head; } else { $longlength = $1 if $_ =~ (/^.(.)$/); } } elsif($head == 2) { $toya1 = 1; undef $head; } if($_ eq 'a0') { $head = 1; } elsif($_ eq 'a1') { $toyencomp = 1; $res{$ciclo}[0] = 'X'; $ciclo++; $head = 2; } elsif($_ eq '00') { if($toyencomp and $toyendob) { $res{$ciclo}[0] = 'X'; $ciclo++; undef $toyendob; undef $toyencomp; } else { $toyendob = 1; } undef $toya1; } } $quest = 'fin'; for($kk = 0; $kk < keys %res; $kk++) { my $verificar = pruebaverificar($res{$kk}[1]); if($verificar ne '0') { my %cdr = leemodulo($res{$kk}) or die($!); my $ver = verificaimsi(\%cdr, $verificar); if($ver eq '1') { %cdrr8 = convierte_r8(\%cdr, $verificar) or die("Algo paso al convertir a R8\n"); $len = longitud_cdr(\%cdrr8) or die("Peeeeeeeeeeeeedos\n"); $head = proc_head($len, $verificar) or die("Problemas en proc_head\n"); $body = proc_body(\%cdrr8) or die("Problemas en proc_body\n"); $total = proc_cdr($head.$body) or die("Problemas en proc_cdr\n"); print OUT $total; } } undef %cdr; } sub proc_cdr { my($regresame) = shift; $long = length($regresame)/2; if($long < 128) { $regresa = 'a0'.$tipo.sprintf('%x', $long); } else { $hexa = sprintf('%x', $long); $test = length($hexa); if(($test % 2) == 1) { $almost = '0'.$hexa; } else { $almost = "$hexa"; } $headcount = length($almost)/2; $regresa = 'a0'.'8'.$headcount.$almost; } return $regresa.$regresame; } sub proc_body { my(%cdrr8) = %{$_[0]}; $infi = scalar keys %cdrr8; my $regresame = ''; for($pl = 0; $pl < $infi; $pl++) { if($cdrr8{$pl}) { $regresame .= $cdrr8{$pl}{'tag'}; my $hexsize = sprintf('%x', $cdrr8{$pl}{'size'}); my $lenghexsize = length($hexsize); my $dif = $lenghexsize % 2; $hexsize = "0".$hexsize if($dif == 1); $regresame .= $hexsize; $regresame .= $cdrr8{$pl}{'cont'}; } } return $regresame; } sub proc_head { my($long, $tipo) = @_; if($long < 128) { $regresa = $tipo.sprintf('%x', $long); } else { $hexa = sprintf('%x', $long); $test = length($hexa); if(($test % 2) == 1) { $almost = '0'.$hexa; } else { $almost = "$hexa"; } $headcount = length($almost)/2; $regresa = $tipo.'8'.$headcount.$almost; } return $regresa; } sub longitud_cdr { my(%cdr) = %{$_[0]}; my $long = 0; my $tam = 0; my $tamlen = 0; $hasta = scalar keys %cdr; for($eni = 0; $eni < $hasta; $eni++) { if($cdr{$eni}) { $long += $cdr{$eni}{'size'}; $long += length($cdr{$eni}{'tag'})/2; $tam = sprintf('%x', $cdr{$eni}{'size'}); $tamlen = length($tam); if($tamlen == 1 || $tamlen == 2) { $long += 1; } elsif($tamlen == 3 || $tamlen == 4) { $long += 2; } else { die("Algo bien feo paso en longitud_cdr\n"); } } } return($long); } sub convierte_r8 { my(%cdr) = %{$_[0]}; my($tipo) = $_[1]; if($tipo eq 'a0') { @arr = @borrar_a0; } elsif($tipo eq 'a1') { @arr = @borrar_a1; } elsif($tipo eq 'a2') { @arr = @borrar_a2; } elsif($tipo eq 'a3') { @arr = @borrar_a3; } elsif($tipo eq 'a4') { @arr = @borrar_a4; } elsif($tipo eq 'a5') { @arr = @borrar_a5; } elsif($tipo eq 'a7') { @arr = @borrar_a7; } elsif($tipo eq 'a8') { @arr = @borrar_a8; } elsif($tipo eq 'a9') { @arr = @borrar_a9; } else { die("Algo durisimo paso en sub convierte_r8.\n"); } $volt = scalar keys %cdr ; $arr = @arr; $sizemocha = 0; $mocha = 0; $iconv = 0; $xconv = 0; for($iconv = 0; $iconv < $volt; $iconv++) { for($xconv = 0; $xconv < $arr; $xconv++) { if($cdr{$iconv}{'tag'} eq $arr[$xconv]) { undef $cdr{$iconv}; $xconv = 0; last; } } } return %cdr; } sub verificaimsi { my(%cdrv) = %{$_[0]}; my($tipo) = $_[1]; $equiv = imsi_modulo($tipo) or die("problemas aquiiiiiiiii\n"); $vueltas = scalar keys %cdrv; undef $regresa; for($o = 0; $o < $vueltas; $o++) { if($cdrv{$o}{'tag'} eq $equiv) { $prueba1 = $2.$1 if $cdrv{$o}{'cont'} =~ (/^(.)(.).+/); $prueba2 = $2.$1 if $cdrv{$o}{'cont'} =~ (/^..(.)(.).+/); $prueba3 = $2.$1 if $cdrv{$o}{'cont'} =~ (/^....(.)(.).+/); $prueba = $prueba1.$prueba2.$prueba3; $omsi = $prueba; $omsi =~ s/.$//g; die("Problemas al obtener los 5 digitos del IMSI\n") unless $omsi; if($omsi eq '71021' or $omsi eq '71073') { # IMSIs de ENITEL o PCS $regresa = '0'; last; } else { # Si tiene que cambiarse :( $regresa = '1'; last; } } else { # Este no es el tag del IMSI } } return $regresa; } sub imsi_modulo { undef $tag; my($tipo) = @_; if($tipo eq 'a0') { $tag = '86'; } elsif($tipo eq 'a1') { $tag = '85'; } elsif($tipo eq 'a2') { $tag = '86'; } elsif($tipo eq 'a3') { $tag = '8a'; } elsif($tipo eq 'a4') { $tag = '86'; } elsif($tipo eq 'a5') { $tag = '85'; } elsif($tipo eq 'a7') { $tag = '84'; } elsif($tipo eq 'a8') { $tag = '84'; } elsif($tipo eq 'a9') { $tag = '85'; } else { die("Problemas durisimos en sub imsi_modulo: $tipo\n"); } undef $tipo; return $tag; } sub pruebaverificar { my($tipo) = @_; if($tipo eq 'a0') { return 'a0'; } elsif($tipo eq 'a1') { return 'a1'; } elsif($tipo eq 'a2') { return 'a2'; } elsif($tipo eq 'a3') { return 'a3'; } elsif($tipo eq 'a4') { return 'a4'; } elsif($tipo eq 'a5') { return 'a5'; } elsif($tipo eq 'a7') { return 'a7'; } elsif($tipo eq 'a8') { return 'a8'; } elsif($tipo eq 'a9') { return 'a9'; } else { return '0'; } } sub leemodulo { my (@cdrm) = @{$_[0]}; my $w = 0; # Empiezo en uno el ciclo debido a que el 0 es la longitud del arreglo. $arrlong = @cdrm; $yatagm = 0; $yam = 0; $loopmod = 0; $longmod = 0; $nolongmod = 0; $caca = 0; $u = 0; if(%regresamod) { $yuju = scalar keys %regresamod; for($ite = 0; $ite < $yuju; $ite++) { delete $regresamod{$ite}; } } for($u = 2; $u <= $arrlong; $u++) { $hexm = hex $cdrm[$u]; if($yatagm == 1) { $regresamod{$w}{'tag'} = $tagm; $regresamod{$w}{'size'} = hex $cdrm[$u]; for($caca = 1; $caca <= $regresamod{$w}{'size'}; $caca++) { $regresamod{$w}{'cont'} .= $cdrm[$u+$caca]; } $u += $regresamod{$w}{'size'}; $w++; $yatagm = 0; next; } if($yam) { if($hexm >= 159) { $tagm = $cdrm[$u].$cdrm[$u+1]; $u++; $yatagm = 1; } else { $tagm = $cdrm[$u]; $yatagm = 1; } next; } next if $yam; if($nolongmod) { $loopmod++; $longmod .= $cdrm[$u]; next if $nolongmod != $loopmod; $longmod = hex $longmod; $yam = 1; undef $nolongmod; next; } if($hexm >= 128) { $nolongmod = $1 if $cdrm[$u] =~ (/^.(.)$/); next; } else { $longmod = hex $cdrm[$u]; $yam = 1; next; } } return %regresamod; } close OUT; my $time2 = localtime; print "Terminando el script a las ".$time2."\n";