<Middlebox name="nat_fullcone">
  <Description> 
    Full cone NAT with source port translation
  </Description>
  <Zones>
    <Zone name="int" description="Internal private network" />
    <Zone name="ext" description="External network" />
  </Zones>

  <TransformationFns>
    <TransformationFn name="Snat_fwd">
      <Param description="new source port">sp</Param>
      <Rewrite field="srcport" value="sp" />
      <Rewrite field="srcip" value="Ip(NAT)" />
      <Rewrite field="srcmac" value="Ip(NAT)" />
      <Rewrite field="dstmac" value="Mac(GW)" />
    </TransformationFn>
    <TransformationFn name="Snat_rev">
      <Param description="original source IP">si</Param>
      <Param description="original soruce port">sp</Param>
      <Rewrite field="dstip" value="si" />
      <Rewrite field="dstport" value="sp" />
      <Rewrite field="dstmac" value="Mac(si)" />
      <Rewrite field="srcmac" value="Mac(NAT)" />
    </TransformationFn>
  </TransformationFns>
  <ProcessingRules>
    <Rule id="1">
      <LHS>
        <Z>int</Z>
        <I>TRUE</I>
        ! <GetState zone="int" key="[h.srcip,h.srcport]" />
      </LHS>
      <RHS>
        <Assign>np = NewPort</Assign>
        <SetState zone="int" key="[h.srcip,h.srcport]" value="np" />
        <SetState zone="ext" key="np" value="{h.srcip;h.srcport}" />
        <Emit zone="ext">
          <Hdr>Snat_fwd(h,np)</Hdr>
          <Payload>d</Payload>
        </Emit>
      </RHS>
    </Rule>
    <Rule id="2">
      <LHS>
        <Z>int</Z>
        <I>TRUE</I>
        <GetState zone="int" key="[h.srcip,h.srcport]" assignto="s" />
      </LHS>
      <RHS>
        <Emit zone="ext">
          <Hdr>Snat_fwd(h,s)</Hdr>
          <Payload>d</Payload>
        </Emit>
      </RHS>
    </Rule>
    <Rule id="3">
      <LHS>
        <Z>ext</Z>
        <I>h.dstip==Ip(NAT) AND h.dstmac==Mac(NAT)</I>
        <GetState zone="ext" key="h.dstport" assignto="s" />
      </LHS>
      <RHS>
        <Emit zone="int">
          <Hdr>Snat_rev(h,s.srcip,s.srcport)</Hdr>
          <Payload>d</Payload>
        </Emit>
      </RHS>
    </Rule>
    <Rule id="4">
      <Description>Represents discrepancy of NAT dropping packet when the model thinks that there is state for it.  Caused by inaccuracies and lack of sync in state expiration between model and NAT</Description>
      <LHS>
        <Z>int</Z>
        <I>TRUE</I>
        <GetState zone="int" key="[h.srcip,h.srcport]" />
      </LHS>
      <RHS> 
        <Drop />
        <Warn msg="inconsistent state" />
      </RHS>
    </Rule>
    <Rule id="5">
      <Description>Represents discrepancy of NAT dropping packet when the model thinks that there is state for it.  Caused by inaccuracies and lack of sync in state expiration between model and NAT</Description>
      <LHS>
        <Z>ext</Z>
        <I>h.dstip==Ip(NAT) AND h.dstmac==Mac(NAT)</I>
        <GetState zone="ext" key="[h.dstport]" />
      </LHS>
      <RHS> 
        <Drop />
        <Warn msg="inconsistent state" />
      </RHS>
    </Rule>

  </ProcessingRules>
</Middlebox>


