You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: trace.go
    path of file: ./repos/mylg/icmp
    
    the code of the file until where you have to start completion: // Copyright 2016 Mehrdad Arshad Rad <arshad.rad@gmail.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.

package icmp

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math/rand"
	"net"
	"os"
	"os/signal"
	"sort"
	"strings"
	"sync"
	"syscall"
	"time"

	"golang.org/x/net/ipv4"

	"github.com/mehrdadrad/mylg/cli"
	"github.com/mehrdadrad/mylg/ripe"
)

// TCPOption represents TCP option
type TCPOption struct {
	kind   uint8
	length uint8
	data   []byte
}

// MHopResp represents multi hop's responses
type MHopResp []Hop
    
func (i *Trace) Sendv4(id, seq, rport int) error {
	var (
		b     []byte
		proto int
		lport int
	)

	switch {
	case i.icmp:
		proto = 1 // icmp v4
		b, _ = icmpV4Message(os.Getpid()&0xffff, seq, i.pSize)
	case i.udp:
		proto = 17 // udp
		lport = 64000 + rand.Intn(3)*100
		b = udpMessage(lport, rport, i.pSize, true)
	case i.tcp:
		proto = 6 // tcp
		b = tcpMessage(0, 33434, 64, true)
		setTCPCheckSum(i.src, i.ip, b)
	}

	c, err := net.ListenPacket(fmt.Sprintf("ip4:%d", proto), "0.0.0.0")
	if err != nil {
		return err
	}
	defer c.Close()

	p, err := ipv4.NewRawConn(c)
	if err != nil {
		return err
	}

	h := &ipv4.Header{
		Version:  ipv4.Version,
		Len:      ipv4.HeaderLen,
		TotalLen: ipv4.HeaderLen + len(b),
		Protocol: proto,
		ID:       id,
		TTL:      i.ttl,
		Dst:      i.ip.To4(),
	}

	if err := p.WriteTo(h, b, nil); err != nil {
		return err
	}
	return nil
}