• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Ullaakut / nmap / 11294670448

11 Oct 2024 03:01PM UTC coverage: 94.51% (-0.3%) from 94.76%
11294670448

push

github

web-flow
fix: remove outdated example test (#135)

878 of 929 relevant lines covered (94.51%)

1.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.67
/xml.go
1
package nmap
2

3
import (
4
        "bytes"
5
        "encoding/xml"
6
        "io"
7
        "os"
8
        "strconv"
9
        "time"
10

11
        family "github.com/Ullaakut/nmap/v3/pkg/osfamilies"
12
)
13

14
// Run represents an nmap scanning run.
15
type Run struct {
16
        XMLName xml.Name `xml:"nmaprun"`
17

18
        Args             string         `xml:"args,attr" json:"args"`
19
        ProfileName      string         `xml:"profile_name,attr" json:"profile_name"`
20
        Scanner          string         `xml:"scanner,attr" json:"scanner"`
21
        StartStr         string         `xml:"startstr,attr" json:"start_str"`
22
        Version          string         `xml:"version,attr" json:"version"`
23
        XMLOutputVersion string         `xml:"xmloutputversion,attr" json:"xml_output_version"`
24
        Debugging        Debugging      `xml:"debugging" json:"debugging"`
25
        Stats            Stats          `xml:"runstats" json:"run_stats"`
26
        ScanInfo         ScanInfo       `xml:"scaninfo" json:"scan_info"`
27
        Start            Timestamp      `xml:"start,attr" json:"start"`
28
        Verbose          Verbose        `xml:"verbose" json:"verbose"`
29
        Hosts            []Host         `xml:"host" json:"hosts"`
30
        PostScripts      []Script       `xml:"postscript>script" json:"post_scripts"`
31
        PreScripts       []Script       `xml:"prescript>script" json:"pre_scripts"`
32
        Targets          []Target       `xml:"target" json:"targets"`
33
        TaskBegin        []Task         `xml:"taskbegin" json:"task_begin"`
34
        TaskProgress     []TaskProgress `xml:"taskprogress" json:"task_progress"`
35
        TaskEnd          []Task         `xml:"taskend" json:"task_end"`
36

37
        NmapErrors []string
38
        rawXML     []byte
39
}
40

41
// ToFile writes a Run as XML into the specified file path.
42
func (r Run) ToFile(filePath string) error {
1✔
43
        file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0644)
1✔
44
        if err != nil {
1✔
45
                return err
×
46
        }
×
47
        _, err = file.Write(r.rawXML)
1✔
48
        if err != nil {
1✔
49
                return err
×
50
        }
×
51
        return err
1✔
52
}
53

54
// ToReader writes the raw XML into an streamable buffer.
55
func (r Run) ToReader() io.Reader {
1✔
56
        return bytes.NewReader(r.rawXML)
1✔
57
}
1✔
58

59
func (r *Run) FromFile(filename string) error {
×
60
        readFile, err := os.ReadFile(filename)
×
61
        if err != nil {
×
62
                return err
×
63
        }
×
64
        return Parse(readFile, r)
×
65
}
66

67
// ScanInfo represents the scan information.
68
type ScanInfo struct {
69
        NumServices int    `xml:"numservices,attr" json:"num_services"`
70
        Protocol    string `xml:"protocol,attr" json:"protocol"`
71
        ScanFlags   string `xml:"scanflags,attr" json:"scan_flags"`
72
        Services    string `xml:"services,attr" json:"services"`
73
        Type        string `xml:"type,attr" json:"type"`
74
}
75

76
// Verbose contains the verbosity level of the scan.
77
type Verbose struct {
78
        Level int `xml:"level,attr" json:"level"`
79
}
80

81
// Debugging contains the debugging level of the scan.
82
type Debugging struct {
83
        Level int `xml:"level,attr" json:"level"`
84
}
85

86
// Task contains information about a task.
87
type Task struct {
88
        Time      Timestamp `xml:"time,attr" json:"time"`
89
        Task      string    `xml:"task,attr" json:"task"`
90
        ExtraInfo string    `xml:"extrainfo,attr" json:"extra_info"`
91
}
92

93
// TaskProgress contains information about the progression of a task.
94
type TaskProgress struct {
95
        Percent   float32   `xml:"percent,attr" json:"percent"`
96
        Remaining int       `xml:"remaining,attr" json:"remaining"`
97
        Task      string    `xml:"task,attr" json:"task"`
98
        Etc       Timestamp `xml:"etc,attr" json:"etc"`
99
        Time      Timestamp `xml:"time,attr" json:"time"`
100
}
101

102
// Target represents a target, how it was specified when passed to nmap,
103
// its status and the reason for its status. Example:
104
// <target specification="domain.does.not.exist" status="skipped" reason="invalid"/>
105
type Target struct {
106
        Specification string `xml:"specification,attr" json:"specification"`
107
        Status        string `xml:"status,attr" json:"status"`
108
        Reason        string `xml:"reason,attr" json:"reason"`
109
}
110

111
// Host represents a host that was scanned.
112
type Host struct {
113
        Distance      Distance      `xml:"distance" json:"distance"`
114
        EndTime       Timestamp     `xml:"endtime,attr,omitempty" json:"end_time"`
115
        IPIDSequence  IPIDSequence  `xml:"ipidsequence" json:"ip_id_sequence"`
116
        OS            OS            `xml:"os" json:"os"`
117
        StartTime     Timestamp     `xml:"starttime,attr,omitempty" json:"start_time"`
118
        TimedOut      bool          `xml:"timedout,attr,omitempty" json:"timed_out"`
119
        Status        Status        `xml:"status" json:"status"`
120
        TCPSequence   TCPSequence   `xml:"tcpsequence" json:"tcp_sequence"`
121
        TCPTSSequence TCPTSSequence `xml:"tcptssequence" json:"tcp_ts_sequence"`
122
        Times         Times         `xml:"times" json:"times"`
123
        Trace         Trace         `xml:"trace" json:"trace"`
124
        Uptime        Uptime        `xml:"uptime" json:"uptime"`
125
        Comment       string        `xml:"comment,attr" json:"comment"`
126
        Addresses     []Address     `xml:"address" json:"addresses"`
127
        ExtraPorts    []ExtraPort   `xml:"ports>extraports" json:"extra_ports"`
128
        Hostnames     []Hostname    `xml:"hostnames>hostname" json:"hostnames"`
129
        HostScripts   []Script      `xml:"hostscript>script" json:"host_scripts"`
130
        Ports         []Port        `xml:"ports>port" json:"ports"`
131
        Smurfs        []Smurf       `xml:"smurf" json:"smurfs"`
132
}
133

134
// Status represents a host's status.
135
type Status struct {
136
        State     string  `xml:"state,attr" json:"state"`
137
        Reason    string  `xml:"reason,attr" json:"reason"`
138
        ReasonTTL float32 `xml:"reason_ttl,attr" json:"reason_ttl"`
139
}
140

141
func (s Status) String() string {
1✔
142
        return s.State
1✔
143
}
1✔
144

145
// Address contains a IPv4 or IPv6 address for a host.
146
type Address struct {
147
        Addr     string `xml:"addr,attr" json:"addr"`
148
        AddrType string `xml:"addrtype,attr" json:"addr_type"`
149
        Vendor   string `xml:"vendor,attr" json:"vendor"`
150
}
151

152
func (a Address) String() string {
1✔
153
        return a.Addr
1✔
154
}
1✔
155

156
// Hostname is a name for a host.
157
type Hostname struct {
158
        Name string `xml:"name,attr" json:"name"`
159
        Type string `xml:"type,attr" json:"type"`
160
}
161

162
func (h Hostname) String() string {
1✔
163
        return h.Name
1✔
164
}
1✔
165

166
// Smurf contains responses from a smurf attack.
167
type Smurf struct {
168
        Responses string `xml:"responses,attr" json:"responses"`
169
}
170

171
// ExtraPort contains the information about the closed and filtered ports.
172
type ExtraPort struct {
173
        State   string   `xml:"state,attr" json:"state"`
174
        Count   int      `xml:"count,attr" json:"count"`
175
        Reasons []Reason `xml:"extrareasons" json:"reasons"`
176
}
177

178
// Reason represents a reason why a port is closed or filtered.
179
// This won't be in the scan results unless WithReason is used.
180
type Reason struct {
181
        Reason string `xml:"reason,attr" json:"reason"`
182
        Count  int    `xml:"count,attr" json:"count"`
183
}
184

185
// Port contains all the information about a scanned port.
186
type Port struct {
187
        ID       uint16   `xml:"portid,attr" json:"id"`
188
        Protocol string   `xml:"protocol,attr" json:"protocol"`
189
        Owner    Owner    `xml:"owner" json:"owner"`
190
        Service  Service  `xml:"service" json:"service"`
191
        State    State    `xml:"state" json:"state"`
192
        Scripts  []Script `xml:"script" json:"scripts"`
193
}
194

195
// PortStatus represents a port's state.
196
type PortStatus string
197

198
// Enumerates the different possible state values.
199
const (
200
        Open       PortStatus = "open"
201
        Closed     PortStatus = "closed"
202
        Filtered   PortStatus = "filtered"
203
        Unfiltered PortStatus = "unfiltered"
204
)
205

206
// Status returns the status of a port.
207
func (p Port) Status() PortStatus {
×
208
        return PortStatus(p.State.State)
×
209
}
×
210

211
// State contains information about a given port's status.
212
// State will be open, closed, etc.
213
type State struct {
214
        State     string  `xml:"state,attr" json:"state"`
215
        Reason    string  `xml:"reason,attr" json:"reason"`
216
        ReasonIP  string  `xml:"reason_ip,attr" json:"reason_ip"`
217
        ReasonTTL float32 `xml:"reason_ttl,attr" json:"reason_ttl"`
218
}
219

220
func (s State) String() string {
1✔
221
        return s.State
1✔
222
}
1✔
223

224
// Owner contains the name of a port's owner.
225
type Owner struct {
226
        Name string `xml:"name,attr" json:"name"`
227
}
228

229
func (o Owner) String() string {
1✔
230
        return o.Name
1✔
231
}
1✔
232

233
// Service contains detailed information about a service on an open port.
234
type Service struct {
235
        DeviceType  string `xml:"devicetype,attr" json:"device_type"`
236
        ExtraInfo   string `xml:"extrainfo,attr" json:"extra_info"`
237
        HighVersion string `xml:"highver,attr" json:"high_version"`
238
        Hostname    string `xml:"hostname,attr" json:"hostname"`
239
        LowVersion  string `xml:"lowver,attr" json:"low_version"`
240
        Method      string `xml:"method,attr" json:"method"`
241
        Name        string `xml:"name,attr" json:"name"`
242
        OSType      string `xml:"ostype,attr" json:"os_type"`
243
        Product     string `xml:"product,attr" json:"product"`
244
        Proto       string `xml:"proto,attr" json:"proto"`
245
        RPCNum      string `xml:"rpcnum,attr" json:"rpc_num"`
246
        ServiceFP   string `xml:"servicefp,attr" json:"service_fp"`
247
        Tunnel      string `xml:"tunnel,attr" json:"tunnel"`
248
        Version     string `xml:"version,attr" json:"version"`
249
        Confidence  int    `xml:"conf,attr" json:"confidence"`
250
        CPEs        []CPE  `xml:"cpe" json:"cpes"`
251
}
252

253
func (s Service) String() string {
1✔
254
        return s.Name
1✔
255
}
1✔
256

257
// CPE (Common Platform Enumeration) is a standardized way to name software
258
// applications, operating systems and hardware platforms.
259
type CPE string
260

261
// Script represents an Nmap Scripting Engine script.
262
// The inner elements can be an arbitrary collection of Tables and Elements. Both of them can also be empty.
263
type Script struct {
264
        ID       string    `xml:"id,attr" json:"id"`
265
        Output   string    `xml:"output,attr" json:"output"`
266
        Elements []Element `xml:"elem,omitempty" json:"elements,omitempty"`
267
        Tables   []Table   `xml:"table,omitempty" json:"tables,omitempty"`
268
}
269

270
// Table is an arbitrary collection of (sub-)Tables and Elements. All its fields can be empty.
271
type Table struct {
272
        Key      string    `xml:"key,attr,omitempty" json:"key,omitempty"`
273
        Tables   []Table   `xml:"table,omitempty" json:"tables,omitempty"`
274
        Elements []Element `xml:"elem,omitempty" json:"elements,omitempty"`
275
}
276

277
// Element is the smallest building block for scripts/tables. It can optionally(!) have a key.
278
type Element struct {
279
        Key   string `xml:"key,attr,omitempty" json:"key,omitempty"`
280
        Value string `xml:",innerxml" json:"value"`
281
}
282

283
// OS contains the fingerprinted operating system for a host.
284
type OS struct {
285
        PortsUsed    []PortUsed      `xml:"portused" json:"ports_used"`
286
        Matches      []OSMatch       `xml:"osmatch" json:"os_matches"`
287
        Fingerprints []OSFingerprint `xml:"osfingerprint" json:"os_fingerprints"`
288
}
289

290
// PortUsed is the port used to fingerprint an operating system.
291
type PortUsed struct {
292
        State string `xml:"state,attr" json:"state"`
293
        Proto string `xml:"proto,attr" json:"proto"`
294
        ID    int    `xml:"portid,attr" json:"port_id"`
295
}
296

297
// OSMatch contains detailed information regarding an operating system fingerprint.
298
type OSMatch struct {
299
        Name     string    `xml:"name,attr" json:"name"`
300
        Accuracy int       `xml:"accuracy,attr" json:"accuracy"`
301
        Line     int       `xml:"line,attr" json:"line"`
302
        Classes  []OSClass `xml:"osclass" json:"os_classes"`
303
}
304

305
// OSClass contains vendor information about an operating system.
306
type OSClass struct {
307
        Vendor       string `xml:"vendor,attr" json:"vendor"`
308
        OSGeneration string `xml:"osgen,attr" json:"os_generation"`
309
        Type         string `xml:"type,attr" json:"type"`
310
        Accuracy     int    `xml:"accuracy,attr" json:"accuracy"`
311
        Family       string `xml:"osfamily,attr" json:"os_family"`
312
        CPEs         []CPE  `xml:"cpe" json:"cpes"`
313
}
314

315
// OSFamily returns the OS family in an enumerated format.
316
func (o OSClass) OSFamily() family.OSFamily {
1✔
317
        return family.OSFamily(o.Family)
1✔
318
}
1✔
319

320
// OSFingerprint is the actual fingerprint string of an operating system.
321
type OSFingerprint struct {
322
        Fingerprint string `xml:"fingerprint,attr" json:"fingerprint"`
323
}
324

325
// Distance is the amount of hops to a particular host.
326
type Distance struct {
327
        Value int `xml:"value,attr" json:"value"`
328
}
329

330
// Uptime is the amount of time the host has been up.
331
type Uptime struct {
332
        Seconds  int    `xml:"seconds,attr" json:"seconds"`
333
        Lastboot string `xml:"lastboot,attr" json:"last_boot"`
334
}
335

336
// Sequence represents a detected sequence.
337
type Sequence struct {
338
        Class  string `xml:"class,attr" json:"class"`
339
        Values string `xml:"values,attr" json:"values"`
340
}
341

342
// TCPSequence represents a detected TCP sequence.
343
type TCPSequence struct {
344
        Index      int    `xml:"index,attr" json:"index"`
345
        Difficulty string `xml:"difficulty,attr" json:"difficulty"`
346
        Values     string `xml:"values,attr" json:"values"`
347
}
348

349
// IPIDSequence represents a detected IP ID sequence.
350
type IPIDSequence Sequence
351

352
// TCPTSSequence represents a detected TCP TS sequence.
353
type TCPTSSequence Sequence
354

355
// Trace represents the trace to a host, including the hops.
356
type Trace struct {
357
        Proto string `xml:"proto,attr" json:"proto"`
358
        Port  int    `xml:"port,attr" json:"port"`
359
        Hops  []Hop  `xml:"hop" json:"hops"`
360
}
361

362
// Hop is an IP hop to a host.
363
type Hop struct {
364
        TTL    float32 `xml:"ttl,attr" json:"ttl"`
365
        RTT    string  `xml:"rtt,attr" json:"rtt"`
366
        IPAddr string  `xml:"ipaddr,attr" json:"ip_addr"`
367
        Host   string  `xml:"host,attr" json:"host"`
368
}
369

370
// Times contains time statistics for an nmap scan.
371
type Times struct {
372
        SRTT string `xml:"srtt,attr" json:"srtt"`
373
        RTT  string `xml:"rttvar,attr" json:"rttv"`
374
        To   string `xml:"to,attr" json:"to"`
375
}
376

377
// Stats contains statistics for an nmap scan.
378
type Stats struct {
379
        Finished Finished  `xml:"finished" json:"finished"`
380
        Hosts    HostStats `xml:"hosts" json:"hosts"`
381
}
382

383
// Finished contains detailed statistics regarding a finished scan.
384
type Finished struct {
385
        Time     Timestamp `xml:"time,attr" json:"time"`
386
        TimeStr  string    `xml:"timestr,attr" json:"time_str"`
387
        Elapsed  float32   `xml:"elapsed,attr" json:"elapsed"`
388
        Summary  string    `xml:"summary,attr" json:"summary"`
389
        Exit     string    `xml:"exit,attr" json:"exit"`
390
        ErrorMsg string    `xml:"errormsg,attr" json:"error_msg"`
391
}
392

393
// HostStats contains the amount of up and down hosts and the total count.
394
type HostStats struct {
395
        Up    int `xml:"up,attr" json:"up"`
396
        Down  int `xml:"down,attr" json:"down"`
397
        Total int `xml:"total,attr" json:"total"`
398
}
399

400
// Timestamp represents time as a UNIX timestamp in seconds.
401
type Timestamp time.Time
402

403
// ParseTime converts a UNIX timestamp string to a time.Time.
404
func (t *Timestamp) ParseTime(s string) error {
1✔
405
        timestamp, err := strconv.ParseInt(s, 10, 64)
1✔
406
        if err != nil {
2✔
407
                return err
1✔
408
        }
1✔
409

410
        *t = Timestamp(time.Unix(timestamp, 0))
1✔
411

1✔
412
        return nil
1✔
413
}
414

415
// FormatTime formats the time.Time value as a UNIX timestamp string.
416
func (t Timestamp) FormatTime() string {
1✔
417
        return strconv.FormatInt(time.Time(t).Unix(), 10)
1✔
418
}
1✔
419

420
// MarshalJSON implements the json.Marshaler interface.
421
func (t Timestamp) MarshalJSON() ([]byte, error) {
1✔
422
        return []byte(t.FormatTime()), nil
1✔
423
}
1✔
424

425
// UnmarshalJSON implements the json.Unmarshaler interface.
426
func (t *Timestamp) UnmarshalJSON(b []byte) error {
1✔
427
        return t.ParseTime(string(b))
1✔
428
}
1✔
429

430
// MarshalXMLAttr implements the xml.MarshalerAttr interface.
431
func (t Timestamp) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
1✔
432
        if time.Time(t).IsZero() {
2✔
433
                return xml.Attr{}, nil
1✔
434
        }
1✔
435

436
        return xml.Attr{Name: name, Value: t.FormatTime()}, nil
1✔
437
}
438

439
// UnmarshalXMLAttr implements the xml.UnmarshalXMLAttr interface.
440
func (t *Timestamp) UnmarshalXMLAttr(attr xml.Attr) (err error) {
1✔
441
        return t.ParseTime(attr.Value)
1✔
442
}
1✔
443

444
// Parse takes a byte array of nmap xml data and unmarshal it into a Run struct.
445
func Parse(content []byte, result *Run) error {
1✔
446
        result.rawXML = content
1✔
447

1✔
448
        err := xml.Unmarshal(content, result)
1✔
449

1✔
450
        return err
1✔
451
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc