From: LuisGLopez
Subject: help: sample code for telnet connection in CMUCL
Date: 
Message-ID: <1143381444.016878.58510@e56g2000cwe.googlegroups.com>
Hi!

I'm using CMUCL under linux.

With some friends we found this site:
http://www.pulltheplug.org/wargames/vortex/level00.html
It's kind of a 'hacker' game :) You have to telnet a server, get 4
unsigned integers, and return the sum.

One of my friends is doing it in C... and challenge me to do it in
lisp. But I've never done socket programming in lisp before... Would
you be so kind to point me some directions, please?

Thank you very much,

Luis.

From: Pascal Bourguignon
Subject: Re: help: sample code for telnet connection in CMUCL
Date: 
Message-ID: <87acbdgpbc.fsf@thalassa.informatimago.com>
"LuisGLopez" <············@gmail.com> writes:

> Hi!
>
> I'm using CMUCL under linux.
>
> With some friends we found this site:
> http://www.pulltheplug.org/wargames/vortex/level00.html
> It's kind of a 'hacker' game :) You have to telnet a server, get 4
> unsigned integers, and return the sum.
>
> One of my friends is doing it in C... and challenge me to do it in
> lisp. But I've never done socket programming in lisp before... Would
> you be so kind to point me some directions, please?


There's no difficulty.  Here is a version for clisp.  
Just add #+cmu and the corresponding form where there are #+clisp
I guess theproper direction is CMUCL documentation.

Note, there is a bug in the vortex server: it cannot stand unbuffered
input!  It sends the unsigned integer "unbuffered" (one packet with
the first, then one packet with the next three), and if you send back
the result byte by byte, it returns "bzzzt, wrong".   Standard flaky C
programming I'd say.  Anyway, with a buffered socket stream it accepts
to speak to us.


That said, you can browse level 1 without any password...
 http://www.pulltheplug.org/wargames/vortex/level01.html  

------------------------------------------------------------------------------
;; -*- coding:utf-8 -*-
#|
Location: http://www.pulltheplug.org/wargames/vortex/level00.html                    
[skin-menu]                                                          [commun]
[hline]   Location  PullThePlug : Wargames : Vortex : Level 00                      

A Simple Programming Exercise                                                       

Your goal is to connect to port 5842 on vortex.labs.pulltheplug.org
and read in 4 unsigned integers.  Add these integers together and send
back the results to get a  username and password for level 1.  Note
that vortex is on an x86 machine (meaning, a little endian
architecture).                                 
       
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Reading Material                                                                    
C Programming Introduction                                                          
Network Programming Introduction                                                    
                                                                    Level 1 >
|#

(defparameter *server*  "vortex.labs.pulltheplug.org")
(defparameter *port*    5842)
(defparameter *timeout*   20 "timeout in seconds")

(defun read-little-endian-unsigned-integer (stream)
  (let ((A (read-byte stream))
        (b (read-byte stream))
        (c (read-byte stream))
        (d (read-byte stream)))
    #+debug (print (list :read a b c d (dpb d (byte 8 24)
                                            (dpb c (byte 8 16)
                                                 (dpb b (byte 8 8) a)))))
    (dpb d (byte 8 24) (dpb c (byte 8 16) (dpb b (byte 8 8) a)))))

(defun write-little-endian-unsigned-integer (unsigned-integer stream)
  (let ((buffer (vector (ldb (byte 8  0) unsigned-integer) 
                        (ldb (byte 8  8) unsigned-integer) 
                        (ldb (byte 8 16) unsigned-integer) 
                        (ldb (byte 8 24) unsigned-integer))))
    #+debug (print (list :write unsigned-integer buffer))
    (write-sequence buffer stream)))

(defun read-byte-line (stream &optional (eof-error-p t) (eof-value nil)
                       &key (encoding #+clisp charset:ascii))
  (loop
     for byte = (read-byte stream nil nil)
     until (or (null byte) (eql byte 13 #|CR|#) (eql byte 10 #|LF|#))
     collect byte into line
     finally (if (null byte)
                 (if eof-error-p
                     (error "EOF while reading a line of bytes on stream ~S ~
                             Already read: ~A"  stream line)
                     (progn (when line (warn "Already read: ~A" line))
                            (return eof-value)))
                 (progn
                   (when (eql byte 13) (read-byte stream nil nil))
                   (return #+clisp (ext:convert-string-from-bytes
                                    (coerce line 'vector) charset:ascii)
                           #-clisp (error "Cannot convert bytes to string in ~A"
                                          (lisp-implementation-type)))))))

(defun level-00 ()
  (with-open-stream (sock 
                      #+clisp (socket:socket-connect *port* *server*
                                                 :element-type '(unsigned-byte 8)
                                                 :buffered t
                                                 :timeout *timeout*)
                      #-clisp (error "Cannot open a socket in ~A"
                                     (lisp-implementation-type)))
    (when (eq :eof #+clisp (socket:socket-status (cons sock :input))
                   #-clisp (error "Cannot get a socket status in ~A"
                                  (lisp-implementation-type)))
      (error "The server ~A didn't respond in ~A seconds" *server* *timeout*))
    (write-little-endian-unsigned-integer
     (+ (read-little-endian-unsigned-integer sock)
        (read-little-endian-unsigned-integer sock)
        (read-little-endian-unsigned-integer sock)
        (read-little-endian-unsigned-integer sock)) sock)
    (finish-output sock)
    (values (read-byte-line sock nil)
            (read-byte-line sock nil))))

(print (multiple-value-list (level-00)))



-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: LuisGLopez
Subject: Re: help: sample code for telnet connection in CMUCL
Date: 
Message-ID: <1143596370.385878.112530@i40g2000cwc.googlegroups.com>
Pascal Bourguignon wrote:
>
>
> There's no difficulty.  Here is a version for clisp.
> Just add #+cmu and the corresponding form where there are #+clisp
> I guess theproper direction is CMUCL documentation.
>

Dear Pascal and Ralf,

Thank you very much!!! I still couldn't get it to work under CMUCL, but
I think I'll be able to do it.

Thank you,

Luis.
From: R. Mattes
Subject: Re: help: sample code for telnet connection in CMUCL
Date: 
Message-ID: <pan.2006.03.26.19.17.24.823440@hobbes.mh-freiburg.de>
On Sun, 26 Mar 2006 05:57:24 -0800, LuisGLopez wrote:

> Hi!
> 
> I'm using CMUCL under linux.
> 
> With some friends we found this site:
> http://www.pulltheplug.org/wargames/vortex/level00.html
> It's kind of a 'hacker' game :) You have to telnet a server, get 4
> unsigned integers, and return the sum.

Just reading the specs: this is certainly not 'telneting' - telnet
is a virtual terminal protocol that uses control characters ...
I guess the just want you to connect to the tcp socket and read a
certain amount of data and then convert it to integers and sum them up.
Peter Seibel's PCL has a really nice chapter on binary IO :-)

 Cheers, RalfD

> One of my friends is doing it in C... and challenge me to do it in
> lisp. But I've never done socket programming in lisp before... Would
> you be so kind to point me some directions, please?
> 
> Thank you very much,
> 
> Luis.