summary refs log tree commit diff stats
path: root/tests/stdlib/tnet.nim
blob: 06ff44c3dba2f5a5211d5901a7c1858d01a4eeb3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
discard """
outputsub: ""
"""

import net, nativesockets
import unittest
import std/assertions

block: # isIpAddress tests
  block: # 127.0.0.1 is valid
    check isIpAddress("127.0.0.1") == true

  block: # ipv6 localhost is valid
    check isIpAddress("::1") == true

  block: # fqdn is not an ip address
    check isIpAddress("example.com") == false

  block: # random string is not an ipaddress
    check isIpAddress("foo bar") == false

  block: # 5127.0.0.1 is invalid
    check isIpAddress("5127.0.0.1") == false

  block: # ipv6 is valid
    check isIpAddress("2001:cdba:0000:0000:0000:0000:3257:9652") == true

  block: # invalid ipv6
    check isIpAddress("gggg:cdba:0000:0000:0000:0000:3257:9652") == false


block: # parseIpAddress tests
  block: # 127.0.0.1 is valid
    discard parseIpAddress("127.0.0.1")

  block: # ipv6 localhost is valid
    discard parseIpAddress("::1")

  block: # fqdn is not an ip address
    expect(ValueError):
      discard parseIpAddress("example.com")

  block: # random string is not an ipaddress
    expect(ValueError):
      discard parseIpAddress("foo bar")

  block: # ipv6 is valid
    discard parseIpAddress("2001:cdba:0000:0000:0000:0000:3257:9652")

  block: # invalid ipv6
    expect(ValueError):
      discard parseIpAddress("gggg:cdba:0000:0000:0000:0000:3257:9652")

  block: # ipv4-compatible ipv6 address (embedded ipv4 address)
    check parseIpAddress("::ffff:10.0.0.23") == parseIpAddress("::ffff:0a00:0017")

  block: # octal number in ipv4 address
    expect(ValueError):
      discard parseIpAddress("010.8.8.8")
    expect(ValueError):
      discard parseIpAddress("8.010.8.8")

  block: # hexadecimal number in ipv4 address
    expect(ValueError):
      discard parseIpAddress("0xc0.168.0.1")
    expect(ValueError):
      discard parseIpAddress("192.0xa8.0.1")

  block: # less than 4 numbers in ipv4 address
    expect(ValueError):
      discard parseIpAddress("127.0.1")

  block: # octal number in embedded ipv4 address
    expect(ValueError):
      discard parseIpAddress("::ffff:010.8.8.8")
    expect(ValueError):
      discard parseIpAddress("::ffff:8.010.8.8")

  block: # hexadecimal number in embedded ipv4 address
    expect(ValueError):
      discard parseIpAddress("::ffff:0xc0.168.0.1")
    expect(ValueError):
      discard parseIpAddress("::ffff:192.0xa8.0.1")

  block: # less than 4 numbers in embedded ipv4 address
    expect(ValueError):
      discard parseIpAddress("::ffff:127.0.1")

block: # "IpAddress/Sockaddr conversion"
  proc test(ipaddrstr: string) =
    var ipaddr_1 = parseIpAddress(ipaddrstr)
    # echo ipaddrstr, " ", $ipaddr_1

    doAssert($ipaddrstr == $ipaddr_1)

    var sockaddr: Sockaddr_storage
    var socklen: SockLen
    var ipaddr_2: IpAddress
    var port_2: Port

    toSockAddr(ipaddr_1, Port(0), sockaddr, socklen)
    fromSockAddr(sockaddr, socklen, ipaddr_2, port_2)

    doAssert(ipaddrstr == $ipaddr_1)

    doAssert(ipaddr_1 == ipaddr_2)
    doAssert($ipaddr_1 == $ipaddr_2)

    if sockaddr.ss_family.cint == AF_INET.toInt:
      var sockaddr4: Sockaddr_in
      copyMem(addr sockaddr4, addr sockaddr, sizeof(sockaddr4))
      fromSockAddr(sockaddr4, socklen, ipaddr_2, port_2)
    elif sockaddr.ss_family.cint == AF_INET6.toInt:
      var sockaddr6: Sockaddr_in6
      copyMem(addr sockaddr6, addr sockaddr, sizeof(sockaddr6))
      fromSockAddr(sockaddr6, socklen, ipaddr_2, port_2)

    doAssert(ipaddr_1 == ipaddr_2)
    doAssert($ipaddr_1 == $ipaddr_2)


  # ipv6 address of example.com
  test("2606:2800:220:1:248:1893:25c8:1946")
  # ipv6 address of localhost
  test("::1")
  # ipv4 address of example.com
  test("93.184.216.34")
  # ipv4 address of localhost
  test("127.0.0.1")
/ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - apps/ex12.subx</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="none">
<meta name="settings" content="number_lines,use_css,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.subxComment { color: #005faf; }
.subxS2Comment { color: #8a8a8a; }
.LineNr { }
.subxS1Comment { color: #0000af; }
.SpecialChar { color: #d70000; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
-->
</style>

<script type='text/javascript'>
<!--

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/apps/ex12.subx'>https://github.com/akkartik/mu/blob/master/apps/ex12.subx</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="subxComment"># Example showing mmap syscall.</span>
<span id="L2" class="LineNr"> 2 </span><span class="subxComment"># Create a new segment using mmap, save the address, write to it.</span>
<span id="L3" class="LineNr"> 3 </span><span class="subxComment">#</span>
<span id="L4" class="LineNr"> 4 </span><span class="subxComment"># To run:</span>
<span id="L5" class="LineNr"> 5 </span><span class="subxComment">#   $ ./bootstrap translate init.linux apps/ex12.subx -o apps/ex12</span>
<span id="L6" class="LineNr"> 6 </span><span class="subxComment">#   $ ./bootstrap run apps/ex12</span>
<span id="L7" class="LineNr"> 7 </span><span class="subxComment"># You shouldn't get a segmentation fault.</span>
<span id="L8" class="LineNr"> 8 </span>
<span id="L9" class="LineNr"> 9 </span>== code
<span id="L10" class="LineNr">10 </span><span class="subxComment">#   instruction                     effective address                                                   register    displacement    immediate</span>
<span id="L11" class="LineNr">11 </span><span class="subxS1Comment"># . op          subop               mod             rm32          base        index         scale       r32</span>
<span id="L12" class="LineNr">12 </span><span class="subxS1Comment"># . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes</span>
<span id="L13" class="LineNr">13 </span>
<span id="L14" class="LineNr">14 </span><span class="SpecialChar">Entry</span>:
<span id="L15" class="LineNr">15 </span>    <span class="subxComment"># mmap(Mmap-new-segment-&gt;len)</span>
<span id="L16" class="LineNr">16 </span>    bb/copy-to-ebx  <span class="SpecialChar"><a href='ex12.subx.html#L29'>Mmap-new-segment</a></span>/imm32
<span id="L17" class="LineNr">17 </span>    e8/call  syscall_mmap/disp32
<span id="L18" class="LineNr">18 </span>
<span id="L19" class="LineNr">19 </span>    <span class="subxComment"># write to *eax to check that we have access to the newly-allocated segment</span>
<span id="L20" class="LineNr">20 </span>    c7          0/subop/copy        0/mod/direct    0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>         <span class="Normal"> . </span>         <span class="Normal"> . </span>              0x34/imm32        <span class="subxComment"># copy to *eax</span>
<span id="L21" class="LineNr">21 </span>
<span id="L22" class="LineNr">22 </span>    <span class="subxComment"># exit(eax)</span>
<span id="L23" class="LineNr">23 </span>    89/copy                         3/mod/direct    3/rm32/ebx   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          0/r32/eax  <span class="Normal"> . </span>             <span class="Normal"> . </span>                <span class="subxComment"># copy eax to ebx</span>
<span id="L24" class="LineNr">24 </span>    e8/call  syscall_exit/disp32
<span id="L25" class="LineNr">25 </span>
<span id="L26" class="LineNr">26 </span>== data
<span id="L27" class="LineNr">27 </span>
<span id="L28" class="LineNr">28 </span><span class="subxComment"># various constants used here were found in the Linux sources (search for file mman-common.h)</span>
<span id="L29" class="LineNr">29 </span><span class="SpecialChar">Mmap-new-segment</span>:  <span class="subxComment"># type mmap_arg_struct</span>
<span id="L30" class="LineNr">30 </span>    <span class="subxComment"># addr</span>
<span id="L31" class="LineNr">31 </span>    0/imm32
<span id="L32" class="LineNr">32 </span>    <span class="subxComment"># len</span>
<span id="L33" class="LineNr">33 </span>    0x100/imm32
<span id="L34" class="LineNr">34 </span>    <span class="subxComment"># protection flags</span>
<span id="L35" class="LineNr">35 </span>    3/imm32  <span class="subxComment"># PROT_READ | PROT_WRITE</span>
<span id="L36" class="LineNr">36 </span>    <span class="subxComment"># sharing flags</span>
<span id="L37" class="LineNr">37 </span>    0x22/imm32  <span class="subxComment"># MAP_PRIVATE | MAP_ANONYMOUS</span>
<span id="L38" class="LineNr">38 </span>    <span class="subxComment"># fd</span>
<span id="L39" class="LineNr">39 </span>    -1/imm32  <span class="subxComment"># since MAP_ANONYMOUS is specified</span>
<span id="L40" class="LineNr">40 </span>    <span class="subxComment"># offset</span>
<span id="L41" class="LineNr">41 </span>    0/imm32  <span class="subxComment"># since MAP_ANONYMOUS is specified</span>
<span id="L42" class="LineNr">42 </span>
<span id="L43" class="LineNr">43 </span><span class="subxS2Comment"># . . vim&#0058;nowrap:textwidth=0</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->