Ver Mensaje Individual
  #4  
Antiguo 06-08-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Reputación: 24
seoane Va por buen camino
Supongo que cuando dices que te puedes conectar por "DOS" te refieres a que lo haces por telnet, si no es así ignora todo lo que pongo a continuación. El protocolo que usa el telnet es bastante sencillo y puede ser todavía mas sencillo si ignoramos algunos detalles. Aquí te dejo una pequeña aplicación que permite reiniciar el router con el comando reboot, pero modificando el script podrías ejecutar la secuencia de comandos que quisieras. El script esta preparado para un Router ADSL COMTREND de los que pone telefónica, para otras marcas y modelos hay que ajustar el script.

Código Delphi [-]
program TelScript;

uses Windows, Sysutils, WinSock;

// Crea un socket y lo conecta a la direccion indicada.
function Conectar(Host: string; Puerto: Integer): TSocket;
var
  Address: u_long;
  HostEnt: phostent;
  Addr: sockaddr_in;
begin
  Result:= INVALID_SOCKET;
  Address:= inet_addr(Pchar(Host));
  if Address = INADDR_NONE then
  begin
    HostEnt:= gethostbyname(PChar(Host));
    if HostEnt <> nil then
      Address:= u_long(HostEnt.h_addr_list^);
  end;
  if Address <> INADDR_NONE then
  begin
    Result:= socket(AF_INET, SOCK_STREAM, 0);
    if Result <> INVALID_SOCKET then
    begin
      Addr.sin_family:= AF_INET;
      Addr.sin_addr.S_addr:= Address;
      Addr.sin_port:= htons(Puerto);
      if connect(Result, Addr, Sizeof(Addr)) = SOCKET_ERROR then
      begin
        closesocket(Result);
        Result:= INVALID_SOCKET;
      end;
    end;
  end;
end;

// Envia un texto al router
function Enviar(Socket: TSocket; Str: string): Boolean;
begin
  Result:= send(Socket,PChar(Str)^,Length(Str),0) <> SOCKET_ERROR;
end;

// Esta funcion espera hasta que recibe una respuesta, si transcurrido
// un tiempo prudencial no se recibe la respuesta esperada la
// funcion termina y devuelve FALSE
const
  Alfanumericos = ['A'..'Z','a'..'z','0'..'9',':','-','<','>',' ','.'];

function EsperarStr(Socket: TSocket; Str: string; TimeOut: Cardinal): boolean;
var
  i,j: integer;
  s: string;
  Tick: DWORD;
  FDSet: TFDSet;
  TimeVal: TTimeVal;
  Buffer: array[0..1024] of Char;
begin
  s:= '';
  Tick := GetTickCount;
  while not (pos(Str, s) > 0) do
  begin
    TimeVal.tv_sec := 0;
    TimeVal.tv_usec := 500;
    FD_ZERO(FDSet);
    FD_SET(Socket, FDSet);
    if select(0, @FDSet, nil, nil, @TimeVal) > 0 then
    begin
      fillchar(Buffer, sizeof(Buffer), 0);
      i := recv(Socket, Buffer, sizeof(Buffer) - 1, 0);
      if (i > 0) then
      begin
        for j:= 0 to i-1 do
          if Buffer[j] in Alfanumericos then
            s:= s + Buffer[j];
      end else
        break;
    end
    else if (GetTickCount - Tick) > TimeOut then
      break;
  end;
  Result:= pos(Str, s) > 0;
end;

// Este es el script que se ejecuta en el router, dependiendo del router,
// puede que sea necesario cambiar alguna cosa. Este esta diseñado
// para un router ADSL CONTREND de telefonica.
function Script(Socket: TSocket): Boolean;
begin
  Result:= FALSE;
  // Esperamos a que nos pida el login
  if EsperarStr(Socket,'ogin:',5000) then
  begin
    // Enviamos el login (1234 en mi caso)
    Enviar(Socket,'1234'+#13);
    // Esperamos a que nos pida el password
    if EsperarStr(Socket,'assword:',5000) then
    begin
      // Enviamos el password (1234 en mi caso)
      Enviar(Socket,'1234'+#13);
      // Esperamos hasta ver el prompt
      if EsperarStr(Socket,'->',5000) then
      begin
        // Enviamos el comando reboot
        Enviar(Socket,'reboot'+#13);
        // Esperamos hasta que el router comienza con el reset
        if EsperarStr(Socket,'wait...',5000) then
        begin
          Result:= TRUE;
        end;
      end;
    end;
  end;
end;

// Esta funcion la usamos para mostrar mensajes
procedure Mensaje(Str: string);
begin
  Messagebox(0,PChar(Str),'TelScript',MB_OK);
end;

procedure Vamos;
var
  WSAData: TWSADATA;
  Socket: TSocket;
begin
  if WSAStartup(MAKEWORD(1, 1), WSADATA) = 0 then
  begin
    // Conectamos con el router, en mi caso, la direccion es 192.168.1.1
    Socket:= Conectar('192.168.1.1',23);
    if Socket <> INVALID_SOCKET then
    begin
      // Ejecutamos el script
      if Script(Socket) then
        Mensaje('El script termino con exito')
      else
        Mensaje('El script no pudo completarse');
      closesocket(Socket);
    end else
      Mensaje('No puedo establecer la conexion con el router');
    WSACleanup;
  end;
end;

begin
  Vamos;
end.

Edito:

El programa adjunto tiene un fallo en la función Conectar si se le pasa un nombre en vez de la ip, la función corregida seria la siguiente:
Código Delphi [-]
function Conectar(Host: string; Puerto: Integer): TSocket;
var
  Address: u_long;
  HostEnt: phostent;
  Addr: sockaddr_in;
begin
  Result:= INVALID_SOCKET;
  Address:= inet_addr(Pchar(Host));
  if Address = INADDR_NONE then
  begin
    HostEnt:= gethostbyname(PChar(Host));
    if HostEnt <> nil then
      Address:= PInAddr(HostEnt.h_addr_list^)^.S_addr;
  end;
  if Address <> INADDR_NONE then
  begin
    Result:= socket(AF_INET, SOCK_STREAM, 0);
    if Result <> INVALID_SOCKET then
    begin
      Addr.sin_family:= AF_INET;
      Addr.sin_addr.S_addr:= Address;
      Addr.sin_port:= htons(Puerto);
      if connect(Result, Addr, Sizeof(Addr)) = SOCKET_ERROR then
      begin
        closesocket(Result);
        Result:= INVALID_SOCKET;
      end;
    end;
  end;
end;
Archivos Adjuntos
Tipo de Archivo: zip TelScript.zip (26,6 KB, 58 visitas)

Última edición por seoane fecha: 21-05-2007 a las 19:12:04.
Responder Con Cita