diff --git a/peer.go b/peer.go
index c4499a67fe93c0b08cfed06706a930b75e597120..c91df79dbc1063b7118d1f05271c21d8c452af85 100644
--- a/peer.go
+++ b/peer.go
@@ -7,6 +7,7 @@ import (
 	"log"
 	"net"
 	"strconv"
+	"strings"
 	"sync/atomic"
 	"time"
 )
@@ -16,6 +17,36 @@ const (
 	outputBufferSize = 50
 )
 
+// Peer capabillities
+type Caps byte
+
+const (
+	CapDiscoveryTy = 0x01
+	CapTxTy        = 0x02
+	CapChainTy     = 0x04
+)
+
+var capsToString = map[Caps]string{
+	CapDiscoveryTy: "Peer discovery",
+	CapTxTy:        "Transaction relaying",
+	CapChainTy:     "Block chain relaying",
+}
+
+func (c Caps) String() string {
+	var caps []string
+	if c&CapDiscoveryTy > 0 {
+		caps = append(caps, capsToString[CapDiscoveryTy])
+	}
+	if c&CapChainTy > 0 {
+		caps = append(caps, capsToString[CapChainTy])
+	}
+	if c&CapTxTy > 0 {
+		caps = append(caps, capsToString[CapTxTy])
+	}
+
+	return strings.Join(caps, " | ")
+}
+
 type Peer struct {
 	// Ethereum interface
 	ethereum *Ethereum
@@ -45,6 +76,10 @@ type Peer struct {
 
 	// Determines whether this is a seed peer
 	seed bool
+
+	host []byte
+	port uint16
+	caps Caps
 }
 
 func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
@@ -56,6 +91,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
 		inbound:     inbound,
 		disconnect:  0,
 		connected:   1,
+		port:        30303,
 	}
 }
 
@@ -223,7 +259,8 @@ out:
 					peers := make([]string, data.Length())
 					// Parse each possible peer
 					for i := 0; i < data.Length(); i++ {
-						peers[i] = data.Get(i).Get(0).AsString() + ":" + strconv.Itoa(int(data.Get(i).Get(1).AsUint()))
+						peers[i] = unpackAddr(data.Get(i).Get(0).AsBytes(), data.Get(i).Get(1).AsUint())
+						log.Println(peers[i])
 					}
 
 					// Connect to the list of peers
@@ -277,20 +314,52 @@ out:
 	p.Stop()
 }
 
+func packAddr(address, port string) ([]byte, uint16) {
+	addr := strings.Split(address, ".")
+	a, _ := strconv.Atoi(addr[0])
+	b, _ := strconv.Atoi(addr[1])
+	c, _ := strconv.Atoi(addr[2])
+	d, _ := strconv.Atoi(addr[3])
+	host := []byte{byte(a), byte(b), byte(c), byte(d)}
+	prt, _ := strconv.Atoi(port)
+
+	return host, uint16(prt)
+}
+
+func unpackAddr(h []byte, p uint64) string {
+	if len(h) != 4 {
+		return ""
+	}
+
+	a := strconv.Itoa(int(h[0]))
+	b := strconv.Itoa(int(h[1]))
+	c := strconv.Itoa(int(h[2]))
+	d := strconv.Itoa(int(h[3]))
+	host := strings.Join([]string{a, b, c, d}, ".")
+	port := strconv.Itoa(int(p))
+
+	return net.JoinHostPort(host, port)
+}
+
 func (p *Peer) Start(seed bool) {
 	p.seed = seed
 
-	peerHost, _, _ := net.SplitHostPort(p.conn.LocalAddr().String())
-	servHost, _, _ := net.SplitHostPort(p.conn.RemoteAddr().String())
+	peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String())
+	servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String())
 	if peerHost == servHost {
 		log.Println("Connected to self")
 
-		p.Stop()
+		//p.Stop()
 
-		return
+		//return
+	}
+
+	if p.inbound {
+		p.host, p.port = packAddr(peerHost, peerPort)
+	} else {
+		p.host, p.port = packAddr(servHost, servPort)
 	}
 
-	//if !p.inbound {
 	err := p.pushHandshake()
 	if err != nil {
 		log.Printf("Peer can't send outbound version ack", err)
@@ -299,7 +368,6 @@ func (p *Peer) Start(seed bool) {
 
 		return
 	}
-	//}
 
 	// Run the outbound handler in a new goroutine
 	go p.HandleOutbound()
@@ -324,7 +392,7 @@ func (p *Peer) Stop() {
 
 func (p *Peer) pushHandshake() error {
 	msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{
-		uint32(0), uint32(0), "/Ethereum(G) v0.0.1/",
+		uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", CapChainTy | CapTxTy | CapDiscoveryTy, p.port,
 	})
 
 	p.QueueMessage(msg)
@@ -354,41 +422,27 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
 	var istr string
 	// If this is an inbound connection send an ack back
 	if p.inbound {
-		/*
-			err := p.pushHandshake()
-			if err != nil {
-				log.Println("Peer can't send ack back")
+		if port := c.Get(4).AsUint(); port != 0 {
+			p.port = uint16(port)
+		}
 
-				p.Stop()
-			}
-		*/
 		istr = "inbound"
 	} else {
-		//msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)})
-		//p.QueueMessage(msg)
+		msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)})
+		p.QueueMessage(msg)
 
 		istr = "outbound"
 	}
 
-	log.Printf("peer connect (%s) %v %s\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString())
-}
-
-func (p *Peer) RlpData() []interface{} {
-	host, _, err := net.SplitHostPort(p.conn.RemoteAddr().String())
-	if err != nil {
-		return nil
-	}
-
-	/* FIXME
-	port, err := strconv.Atoi(prt)
-	if err != nil {
-		return nil
+	if caps := Caps(c.Get(3).AsByte()); caps != 0 {
+		p.caps = caps
 	}
-	*/
 
-	//port := ethutil.NumberToBytes(uint16(i), 16)
+	log.Printf("peer connect (%s) %v %s [%s]\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString(), p.caps)
+}
 
-	return []interface{}{host, uint16(30303) /*port*/}
+func (p *Peer) RlpData() []interface{} {
+	return []interface{}{p.host, p.port /*port*/}
 }
 
 func (p *Peer) RlpEncode() []byte {