Original post

hello everyone,
hope you all are doing well,
can anyone help me to converting github.com/openrdap/rdap code to gRPC,
I am using this code for extracting data from network using RDAP, now I want to do same but using gRPC, but don’t have any idea to get start with gRPC.
just give me demo about how to covert this RDAP code to gRPC.

package main

import (
        "encoding/json"
        "errors"
        "io"
        "log"
        "net"
        "net/http"
        "os"
        "strings"

        "github.com/openrdap/rdap"
)

const IPSET_FILE = "output.json"

var blockips BlockIP

// var blockips = NewBlockIP(IPSET_INTVAL)
type AnaylsisResult map[string]bool

type BlockIP map[string][]string

type NetworkInfo struct {
        Ip       string `json:"ip"`
        Hostname string `json:"hostname"`
        Reverse  string `json:"reverse"`
}

//ArinInfo data
type ArinInfo struct {
        Name         string   `json:"name,omitempty"`
        Handle       string   `json:"handle,omitempty"`
        Parent       string   `json:"parent,omitempty"`
        Type         string   `json:"type,omitempty"`
        Range        string   `json:"range,omitempty"`
        Cidr         string   `json:"cidr,omitempty"`
        Status       []string `json:"status,omitempty"`
        Registration string   `json:"registration,omitempty"`
        Updated      string   `json:"updated,omitempty"`
}

//OrgnizationInfo data
type OrgnizationInfo struct {
        Name         string `json:"name,omitempty"`
        Handle       string `json:"handle,omitempty"`
        Street       string `json:"street,omitempty"`
        City         string `json:"city,omitempty"`
        Province     string `json:"province,omitempty"`
        Postal       string `json:"postal,omitempty"`
        Country      string `json:"country,omitempty"`
        Registration string `json:"registration,omitempty"`
        Updated      string `json:"updated,omitempty"`
}

//ContactInfo data
type ContactInfo struct {
        Name         string `json:"name,omitempty"`
        Handle       string `json:"handle,omitempty"`
        Company      string `json:"company,omitempty"`
        Street       string `json:"street,omitempty"`
        City         string `json:"city,omitempty"`
        Province     string `json:"province,omitempty"`
        Postal       string `json:"postal,omitempty"`
        Country      string `json:"country,omitempty"`
        Registration string `json:"registration,omitempty"`
        Updated      string `json:"updated,omitempty"`
        Phone        string `json:"phone,omitempty"`
        Email        string `json:"email,omitempty"`
}

//Response data
type Response struct {
        Network     NetworkInfo     `json:"network,omitempty"`
        Arin        ArinInfo        `json:"arin,omitempty"`
        Orgnization OrgnizationInfo `json:"orgnization,omitempty"`
        Contact     ContactInfo     `json:"contact,omitempty"`
        Abuse       ContactInfo     `json:"abuse,omitempty"`
        Anaylsis    AnaylsisResult  `json:"anaylsis,omitempty"`
}

func init() {
        log.SetFlags(log.Lshortfile)
        // init blockip datasource
        // open blockip file
        f, e := os.OpenFile(IPSET_FILE, os.O_RDONLY, 0666)
        if e != nil {
                log.Println(e)
                return
        }
        blockips = NewBlockIP(f)

}

func main() {
        //router
        r := http.NewServeMux()
        //routes
        r.HandleFunc("/", reverseIpHandler)
        r.HandleFunc("/ip/", ipHandler)
        //http server
        http.ListenAndServe(":8080", r)
}

func NewResponse(ip string) (rsp *Response) {
        rsp = new(Response)
        // process
        rsp.parseNetWork(ip)
        rsp.Parse(ip)
        return
}

func (rsp *Response) parseNetWork(ip string) {
        // set default value
        rsp.Network = NetworkInfo{}
        rsp.Network.Ip = ip

        host, err := net.LookupAddr(ip)
        if err != nil || len(host) == 0 {
                log.Println(err, ip)
                return
        }

        revIP, err := net.LookupIP(host[0])
        if err != nil || len(revIP) == 0 {
                return
        }
        // update network value
        rsp.Network.Hostname = host[0]
        rsp.Network.Reverse = revIP[0].String()
}

func (rsp *Response) Parse(ip string) {
        // read whois information
        c := &rdap.Client{}
        rs, e := c.QueryIP(ip)
        if e != nil {
                log.Println(e)
                return
        }
        // arinfo
        rsp.Arin.Name = rs.Name
        rsp.Arin.Cidr = rs.Handle
        rsp.Arin.Handle = rs.Handle
        rsp.Arin.Parent = rs.ParentHandle
        rsp.Arin.Range = rs.StartAddress + "-" + rs.EndAddress
        rsp.Arin.Type = rs.Type
        // update registration and updated
        for _, v := range rs.Events {
                switch v.Action {
                case "registration":
                        rsp.Arin.Registration = v.Date
                case "last changed":
                        rsp.Arin.Updated = v.Date
                }
        }

        for _, ett := range rs.Entities {
                if ett.VCard == nil {
                        continue
                }
                switch {
                // orgnization infomation
                case isExists(ett.Roles, "registrant"):
                        rsp.Orgnization.Country = ett.VCard.Country()
                        rsp.Orgnization.City = ett.VCard.ExtendedAddress()
                        rsp.Orgnization.Handle = ett.Handle
                        rsp.Orgnization.Name = ett.VCard.Name()
                        rsp.Orgnization.Postal = ett.VCard.PostalCode()
                        rsp.Orgnization.Province = ett.VCard.Region()
                        for _, v := range ett.Events {
                                switch v.Action {
                                case "registration":
                                        rsp.Orgnization.Registration = v.Date
                                case "last changed":
                                        rsp.Orgnization.Updated = v.Date
                                }
                        }
                        rsp.Orgnization.Street = ett.VCard.StreetAddress()
                // abuse information
                case isExists(ett.Roles, "abuse"):
                        rsp.Abuse.Country = ett.VCard.Country()
                        rsp.Abuse.City = ett.VCard.ExtendedAddress()
                        rsp.Abuse.Email = ett.VCard.Email()
                        rsp.Abuse.Handle = ett.Handle
                        rsp.Abuse.Name = ett.VCard.Name()
                        rsp.Abuse.Phone = ett.VCard.Tel()
                        rsp.Abuse.Postal = ett.VCard.PostalCode()
                        rsp.Abuse.Province = ett.VCard.Region()
                        for _, v := range ett.Events {
                                switch v.Action {
                                case "registration":
                                        rsp.Abuse.Registration = v.Date
                                case "last changed":
                                        rsp.Abuse.Updated = v.Date
                                }
                        }
                        rsp.Abuse.Street = ett.VCard.StreetAddress()
                        fallthrough
                // contact
                case isExists(ett.Roles, "administrative"):
                        rsp.Contact.City = ett.VCard.ExtendedAddress()
                        rsp.Contact.Country = ett.VCard.Country()
                        rsp.Contact.Email = ett.VCard.Email()
                        rsp.Contact.Handle = ett.Handle
                        rsp.Contact.Name = ett.VCard.Name()
                        rsp.Contact.Phone = ett.VCard.Tel()
                        rsp.Contact.Postal = ett.VCard.PostalCode()
                        rsp.Contact.Province = ett.VCard.Region()
                        for _, v := range ett.Events {
                                switch v.Action {
                                case "registration":
                                        rsp.Contact.Registration = v.Date
                                case "last changed":
                                        rsp.Contact.Updated = v.Date
                                }
                        }
                        rsp.Contact.Street = ett.VCard.StreetAddress()
                }
        }
}

func isExists(src []string, item string) (r bool) {
        for _, v := range src {
                if v == item {
                        r = true
                        break
                }
        }
        return
}

func getContent(ct string) (r string) {
        idx := strings.Index(ct, ":")
        r = strings.Trim(ct[idx+1:], " ")
        r = strings.Trim(r, "n")
        return
}

func reverseIpHandler(w http.ResponseWriter, r *http.Request) {
        //reverse ip
        rip := getReverseIp(r)
        rsp := NewResponse(rip)
        e := json.NewEncoder(w).Encode(rsp)
        if e != nil {
                log.Println(e)
        }

}

func getReverseIp(r *http.Request) string {
        ff := r.Header.Get("CF-Connecting-IP")
        if ff != "" {
                return ff
        }
        //fall back to request's remote address
        ip := getIp(r.RemoteAddr)
        return ip
}

func getIp(remoteAddress string) string {
        i := strings.Index(remoteAddress, ":")
        return remoteAddress[0:i]
}

func ipHandler(w http.ResponseWriter, r *http.Request) {
        //ip
        ip, err := getIpParam(r)
        if err != nil {
                log.Println(err)
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
                return
        }
        rsp := NewResponse(ip)
        // anaylsis
        rsp.Anaylsis = blockips.Anaylsis(ip)

        e := json.NewEncoder(w).Encode(rsp)
        if e != nil {
                log.Println(e)
        }
}

func getIpParam(r *http.Request) (string, error) {
        //url path: /ip/:ip
        ip := r.URL.Path[4:]
        i := strings.Index(ip, "/")
        if i == -1 {
                return ip, nil
        } else {
                return "", errors.New("Failed to get ip parameter!")
        }
}

func NewBlockIP(f io.Reader) (bip BlockIP) {
        bip = make(BlockIP)
        bip.load(f)
        return
}

func (bip *BlockIP) load(f io.Reader) {
        dc := json.NewDecoder(f)
        e := dc.Decode(bip)
        if e != nil {
                log.Println(e)
                return
        }
}

func (bip BlockIP) Anaylsis(ip string) (rs AnaylsisResult) {
        rs = make(AnaylsisResult)
        for k, v := range bip {
                // detect if ip in v
                rs[k] = false
                for _, va := range v {
                        if va == ip {
                                rs[k] = true
                                break
                        }
                        // if v contains "/" in the last 3 pst
                        if strings.Contains(va, "/") {
                                if ipinet(ip, va) {
                                        rs[k] = true
                                        break
                                }
                                va = va[:len(va)-3]
                        }

                        // compare the ip value
                        // when va greate than ip then break
                        ipi, e := IPString2Long(ip)
                        if e != nil {
                                log.Println(ip, e)
                        }
                        ipv, e := IPString2Long(va)
                        if e != nil {
                                log.Println(va, e)
                        }
                        // log.Println(ipi, ipv, va)
                        if ipv > ipi {
                                break
                        }
                }
        }
        return
}

func ipinet(ip string, cidr string) (r bool) {
        ipx, subnet, _ := net.ParseCIDR(cidr)
        ipa := net.ParseIP(ip)
        // if netip eq ip then check ip existing
        if subnet.IP.Equal(ipx) {
                r = subnet.Contains(ipa)
                return
        }
        r = ipa.Equal(ipx)
        return
}

func IPString2Long(ip string) (uint, error) {
        b := net.ParseIP(ip).To4()
        if b == nil {
                return 0, errors.New("invalid ipv4 format")
        }

        return uint(b[3]) | uint(b[2])<<8 | uint(b[1])<<16 | uint(b[0])<<24, nil
}

As it is your question has some problems.

  • This forum can automatically format code. Select all your code and hit the </> button at the top of the edit window.
  • You won’t get much help if you just dump your complete code here without adding any explanation what the code does, how it does it, what you want it to do after the converstion to gRPC.

@lutzhorn thanks for guiding me, actually I am using this code for extracting data from network using RDAP, now I want to do same but using gRPC, but don’t have any idea to get start with gRPC.
Kindly help me if you can.