It is fixed now. It was a silly issue with one "if" (plus a few other minor issues in the option string parser).<br><br>Now everything seems to be working ok. <br><br>The match function looks like this now:<br><br>
<pre><div class="line" id="LC165"><span class="k">static</span> <span class="kt">int</span> <span class="nf">DetectGeoipMatch</span><span class="p">(</span><span class="n">ThreadVars</span> <span class="o">*</span><span class="n">t</span><span class="p">,</span> <span class="n">DetectEngineThreadCtx</span> <span class="o">*</span><span class="n">det_ctx</span><span class="p">,</span></div>
<div class="line" id="LC166">                             <span class="n">Packet</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="n">Signature</span> <span class="o">*</span><span class="n">s</span><span class="p">,</span> <span class="n">SigMatch</span> <span class="o">*</span><span class="n">m</span><span class="p">)</span></div>
<div class="line" id="LC167"><span class="p">{</span></div><div class="line" id="LC168">    <span class="n">DetectGeoipData</span> <span class="o">*</span><span class="n">geoipdata</span> <span class="o">=</span> <span class="p">(</span><span class="n">DetectGeoipData</span> <span class="o">*</span><span class="p">)</span><span class="n">m</span><span class="o">-></span><span class="n">ctx</span><span class="p">;</span></div>
<div class="line" id="LC169">    <span class="kt">int</span> <span class="n">match</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></div><div class="line" id="LC170">    <span class="kt">int</span> <span class="n">matches</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></div>
<div class="line" id="LC171"><br></div><div class="line" id="LC172">    <span class="k">if</span> <span class="p">(</span><span class="n">PKT_IS_IPV4</span><span class="p">(</span><span class="n">p</span><span class="p">))</span></div>
<div class="line" id="LC173">    <span class="p">{</span></div><div class="line" id="LC174">        <span class="k">if</span> <span class="p">(</span><span class="n">geoipdata</span><span class="o">-></span><span class="n">flags</span> <span class="o">&</span> <span class="n">GEOIP_MATCH_SRC_FLAG</span> <span class="o">||</span> <span class="n">geoipdata</span><span class="o">-></span><span class="n">flags</span> <span class="o">&</span> <span class="n">GEOIP_MATCH_BOTH_FLAG</span><span class="p">)</span></div>
<div class="line" id="LC175">        <span class="p">{</span>        </div><div class="line" id="LC176">            <span class="cm">/* if there is a flow get SRC IP of the flow, not packet */</span>            </div><div class="line" id="LC177">
            <span class="k">if</span> <span class="p">(</span><span class="n">p</span><span class="o">-></span><span class="n">flowflags</span> <span class="o">&</span> <span class="n">FLOW_PKT_TOCLIENT</span><span class="p">)</span></div>
<div class="line" id="LC178">                <span class="cm">/* the dst (from server to client) is our src */</span></div><div class="line" id="LC179">                <span class="n">match</span> <span class="o">=</span> <span class="n">CheckGeoMatchIPv4</span><span class="p">(</span><span class="n">geoipdata</span><span class="p">,</span> <span class="n">GET_IPV4_DST_ADDR_U32</span><span class="p">(</span><span class="n">p</span><span class="p">));</span></div>
<div class="line" id="LC180">            <span class="k">else</span> </div><div class="line" id="LC181">                <span class="n">match</span> <span class="o">=</span> <span class="n">CheckGeoMatchIPv4</span><span class="p">(</span><span class="n">geoipdata</span><span class="p">,</span> <span class="n">GET_IPV4_SRC_ADDR_U32</span><span class="p">(</span><span class="n">p</span><span class="p">));</span></div>
<div class="line" id="LC182">            <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">)</span></div><div class="line" id="LC183">            <span class="p">{</span></div><div class="line" id="LC184">
                <span class="k">if</span> <span class="p">(</span><span class="n">geoipdata</span><span class="o">-></span><span class="n">flags</span> <span class="o">&</span> <span class="n">GEOIP_MATCH_BOTH_FLAG</span><span class="p">)</span></div>
<div class="line" id="LC185">                    <span class="n">matches</span><span class="o">++</span><span class="p">;</span></div><div class="line" id="LC186">                <span class="k">else</span>                    </div>
<div class="line" id="LC187">                    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span></div><div class="line" id="LC188">            <span class="p">}</span></div><div class="line" id="LC189">
        <span class="p">}</span></div><div class="line" id="LC190">        <span class="k">if</span> <span class="p">(</span><span class="n">geoipdata</span><span class="o">-></span><span class="n">flags</span> <span class="o">&</span> <span class="n">GEOIP_MATCH_DST_FLAG</span> <span class="o">||</span> <span class="n">geoipdata</span><span class="o">-></span><span class="n">flags</span> <span class="o">&</span> <span class="n">GEOIP_MATCH_BOTH_FLAG</span><span class="p">)</span></div>
<div class="line" id="LC191">        <span class="p">{</span>     </div><div class="line" id="LC192">            <span class="cm">/* if there is a flow get DST IP of the flow, not packet */</span>            </div><div class="line" id="LC193">
            <span class="k">if</span> <span class="p">(</span><span class="n">p</span><span class="o">-></span><span class="n">flowflags</span> <span class="o">&</span> <span class="n">FLOW_PKT_TOCLIENT</span><span class="p">)</span></div>
<div class="line" id="LC194">                <span class="cm">/* the src (from server to client) is our dst */</span></div><div class="line" id="LC195">                <span class="n">match</span> <span class="o">=</span> <span class="n">CheckGeoMatchIPv4</span><span class="p">(</span><span class="n">geoipdata</span><span class="p">,</span> <span class="n">GET_IPV4_SRC_ADDR_U32</span><span class="p">(</span><span class="n">p</span><span class="p">));</span></div>
<div class="line" id="LC196">            <span class="k">else</span> </div><div class="line" id="LC197">                <span class="n">match</span> <span class="o">=</span> <span class="n">CheckGeoMatchIPv4</span><span class="p">(</span><span class="n">geoipdata</span><span class="p">,</span> <span class="n">GET_IPV4_DST_ADDR_U32</span><span class="p">(</span><span class="n">p</span><span class="p">));</span></div>
<div class="line" id="LC198">            <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">)</span></div><div class="line" id="LC199">            <span class="p">{</span></div><div class="line" id="LC200">
                <span class="k">if</span> <span class="p">(</span><span class="n">geoipdata</span><span class="o">-></span><span class="n">flags</span> <span class="o">&</span> <span class="n">GEOIP_MATCH_BOTH_FLAG</span><span class="p">)</span></div>
<div class="line" id="LC201">                    <span class="n">matches</span><span class="o">++</span><span class="p">;</span></div><div class="line" id="LC202">                <span class="k">else</span>                    </div>
<div class="line" id="LC203">                    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span></div><div class="line" id="LC204">            <span class="p">}</span></div><div class="line" id="LC205">
        <span class="p">}</span></div><div class="line" id="LC206">        <span class="cm">/* if matches == 2 is because match-on is "both" */</span></div><div class="line" id="LC207">        <span class="k">if</span> <span class="p">(</span><span class="n">matches</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> </div>
<div class="line" id="LC208">            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span></div><div class="line" id="LC209">    <span class="p">}</span></div><div class="line" id="LC210">    </div>
<div class="line" id="LC211">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span></div><div class="line" id="LC212"><span class="p">}</span></div></pre><br><br><div class="gmail_quote">On Sat, Oct 13, 2012 at 9:46 PM, I. Sanchez <span dir="ltr"><<a href="mailto:sanchezmartin.ji@gmail.com" target="_blank">sanchezmartin.ji@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ok, I have done an initial implementation (just country geolocation for now). It is available at <a href="https://github.com/owlsec/suricata/tree/geoip" target="_blank">https://github.com/owlsec/suricata/tree/geoip</a><br>
<br>When checking a packet, I take into account the flow source and destination IPs for the match-on condition, if a flow exists. However in my tests I have seen it is not working well... a geoip:src,US; rule will be triggered as well when talking HTTP to <a href="http://google.com" target="_blank">google.com</a> from a non US source IP address.<br>

<br>I am not sure about the reason of this behavior, so perhaps somebody could let me know what is wrong here.<br><br><a href="https://github.com/owlsec/suricata/blob/geoip/src/detect-geoip.c" target="_blank">https://github.com/owlsec/suricata/blob/geoip/src/detect-geoip.c</a><br>

<br>The relevant function is this one:<br><br><pre><div><span>static</span> <span>int</span> <span>DetectGeoipMatch</span><span>(</span><span>ThreadVars</span> <span>*</span><span>t</span><span>,</span> <span>DetectEngineThreadCtx</span> <span>*</span><span>det_ctx</span><span>,</span></div>

<div>                             <span>Packet</span> <span>*</span><span>p</span><span>,</span> <span>Signature</span> <span>*</span><span>s</span><span>,</span> <span>SigMatch</span> <span>*</span><span>m</span><span>)</span></div>

<div><span>{</span></div><div>    <span>DetectGeoipData</span> <span>*</span><span>geoipdata</span> <span>=</span> <span>(</span><span>DetectGeoipData</span> <span>*</span><span>)</span><span>m</span><span>-></span><span>ctx</span><span>;</span></div>

<div>    <span>int</span> <span>match</span> <span>=</span> <span>0</span><span>;</span></div><div>    <span>int</span> <span>matches</span> <span>=</span> <span>0</span><span>;</span></div>
<div>    <span>uint32_t</span> <span>ip</span><span>;</span></div><div><br></div><div>    <span>if</span> <span>(</span><span>PKT_IS_IPV4</span><span>(</span><span>p</span><span>))</span></div>
<div>    <span>{</span></div><div>        <span>if</span> <span>(</span><span>geoipdata</span><span>-></span><span>flags</span> <span>&</span> <span>GEOIP_MATCH_SRC_FLAG</span> <span>||</span> <span>geoipdata</span><span>-></span><span>flags</span> <span>&</span> <span>GEOIP_MATCH_BOTH_FLAG</span><span>)</span></div>

<div>        <span>{</span>        </div><div>            <span>/* if there is a flow get SRC IP of the flow, not packet */</span>            </div><div>
            <span>if</span> <span>(</span><span>p</span><span>-></span><span>flowflags</span> <span>&</span> <span>FLOW_PKT_TOCLIENT</span><span>)</span></div>
<div>                <span>ip</span> <span>=</span> <span>GET_IPV4_DST_ADDR_U32</span><span>(</span><span>p</span><span>);</span> <span>/* the dst (from server to client) is our src */</span></div>
<div>            <span>else</span> </div><div>                <span>ip</span> <span>=</span> <span>GET_IPV4_SRC_ADDR_U32</span><span>(</span><span>p</span><span>);</span></div>
<div>            <span>match</span> <span>=</span> <span>CheckGeoMatchIPv4</span><span>(</span><span>geoipdata</span><span>,</span> <span>ip</span><span>);</span></div>
<div>            <span>if</span> <span>(</span><span>match</span> <span>&&</span> <span>geoipdata</span><span>-></span><span>flags</span> <span>&</span> <span>GEOIP_MATCH_BOTH_FLAG</span><span>)</span></div>

<div>                <span>matches</span><span>++</span><span>;</span></div><div>            <span>else</span>                    </div>
<div>                <span>return</span> <span>1</span><span>;</span></div><div>        <span>}</span></div><div>
        <span>if</span> <span>(</span><span>geoipdata</span><span>-></span><span>flags</span> <span>&</span> <span>GEOIP_MATCH_DST_FLAG</span> <span>||</span> <span>geoipdata</span><span>-></span><span>flags</span> <span>&</span> <span>GEOIP_MATCH_BOTH_FLAG</span><span>)</span></div>

<div>        <span>{</span>     </div><div>            <span>/* if there is a flow get DST IP of the flow, not packet */</span>            </div><div>
            <span>if</span> <span>(</span><span>p</span><span>-></span><span>flowflags</span> <span>&</span> <span>FLOW_PKT_TOCLIENT</span><span>)</span></div>
<div>                <span>ip</span> <span>=</span> <span>GET_IPV4_SRC_ADDR_U32</span><span>(</span><span>p</span><span>);</span> <span>/* the src (from server to client) is our dst */</span></div>
<div>            <span>else</span> </div><div>                <span>ip</span> <span>=</span> <span>GET_IPV4_DST_ADDR_U32</span><span>(</span><span>p</span><span>);</span></div>
<div>            <span>match</span> <span>=</span> <span>CheckGeoMatchIPv4</span><span>(</span><span>geoipdata</span><span>,</span> <span>ip</span><span>);</span></div>
<div>            <span>if</span> <span>(</span><span>match</span> <span>&&</span> <span>geoipdata</span><span>-></span><span>flags</span> <span>&</span> <span>GEOIP_MATCH_BOTH_FLAG</span><span>)</span></div>

<div>                <span>matches</span><span>++</span><span>;</span></div><div>            <span>else</span>                    </div>
<div>                <span>return</span> <span>1</span><span>;</span></div><div>        <span>}</span></div><div>
<br></div><div>        <span>/* if matches == 2 is because match-on is "both" */</span></div><div>        <span>if</span> <span>(</span><span>matches</span> <span>==</span> <span>2</span><span>)</span> </div>
<div>            <span>return</span> <span>1</span><span>;</span></div><div>    <span>}</span></div><div>    </div>
<div>    <span>return</span> <span>0</span><span>;</span></div><div><span>}<br></span></div></pre><div class="HOEnZb"><div class="h5"><br><br><div class="gmail_quote">On Fri, Oct 12, 2012 at 11:35 AM, I. Sanchez <span dir="ltr"><<a href="mailto:sanchezmartin.ji@gmail.com" target="_blank">sanchezmartin.ji@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Yes, I forgot to mention it. Negation will be supported.<div><div><br><br><div class="gmail_quote">
On Fri, Oct 12, 2012 at 10:03 AM, Peter Manev <span dir="ltr"><<a href="mailto:petermanev@gmail.com" target="_blank">petermanev@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Excellent - thank you.<br>comments bellow ...<br><br><div class="gmail_quote"><div>On Thu, Oct 11, 2012 at 10:07 PM, I. Sanchez <span dir="ltr"><<a href="mailto:sanchezmartin.ji@gmail.com" target="_blank">sanchezmartin.ji@gmail.com</a>></span> wrote:<br>



<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Good idea, I will implement multiple conditions(countries) in the same rule. Let's use the <match-on><condition>+ syntax where match-on can be src, dst, both or any.<div>



<br><br><div style="margin-left:40px">alert http any any -> any any (msg:"GEOIP: IP located in US/Germany/Canada/France";<b> geoip:src,US,DE,CA,FR</b>; sid:3450002; rev:1;)<br>
</div><br></div>I can also support geoip:US; by assuming geoip:any,US; , for simplicity. <br></blockquote></div><div><br>I agree with the assumption here - i think it is good to assume so. <br>I was thinking further on the matter and I am not sure if i am starting to sound annoying - but wouldn't it be nice if we can also negate geoip? :<br>



alert http any any -> any any (msg:"GEOIP: IP destination  <b>NOT</b> located in US/Canada";<b> </b>geoip:<b>dst,!</b>US,CA; sid:3450002; rev:1;)<br><br><br></div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<br>Regarding the city support, indeed the MaxMind DBs in their free versions support cities in addition to countries although the accuracy drops from 99.5% (for countries) to 78% in US (for cities), and I guess much less accuracy in other countries. <br>




<br>In the commercial DBs, they apparently support regions, organizations... <a href="http://www.maxmind.com/en/geolocation_landing" target="_blank">http://www.maxmind.com/en/geolocation_landing</a><br><br>For now I will just implement support for countries, but we should take this into account for the keyword syntax. I see some options:<br>




<ul><li>Autodetect city vs country. I could detect whether the condition is a known country code, and assume city otherwise. However this will not work for regions, organizations...</li><li>Allow -for future versions- the check type as an optional param of the <match-on> condition. ie: geoip:src,city,Madrid;</li>



</ul></blockquote></div><div><br>this would be awesome in my opinion. <br></div><div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><ul>
</ul>Regards,<div><div><br><br><br><br><br><div class="gmail_quote">On Thu, Oct 11, 2012 at 9:02 PM, Peter Manev <span dir="ltr"><<a href="mailto:petermanev@gmail.com" target="_blank">petermanev@gmail.com</a>></span> wrote:<br>




<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br><br>I think i love that new geoip keyword - thank you for the efforts !<br><br>A couple of suggestions/requests if I may:<br>




<br>1.I agree/like the proposal - but I wonder if it would be possible to include multiples(maybe up to a certain number [32 or something] ) of countries - like:<br>
alert http any any -> any any (msg:"GEOIP: IP located in US/Germany/Canada/France";<b> geoip:src,US,DE,CA,FR</b>; sid:3450002; rev:1;)<br><br>2. As there is - <b>src, dst, both</b> - i think it would be nice if there is also "<b>any</b>" - <br>





alert http any any -> any any (msg:"GEOIP: some traffic to/from the Cayman Islands";<b> geoip:any,KY</b>; sid:3450005; rev:1;)<br>any - meaning either source or destination.<br><br>thanks a bunch!<div>
<div><br><br><div class="gmail_quote">
On Thu, Oct 11, 2012 at 6:42 PM, Victor Julien <span dir="ltr"><<a href="mailto:victor@inliniac.net" target="_blank">victor@inliniac.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div>On 10/11/2012 06:16 PM, I. Sanchez wrote:<br>
> Hi,<br>
><br>
> I am implementing support for IP address country geolocation in<br>
> Suricata, and I wanted to ask your opinion about the syntax to be used<br>
> for the geoip keyword options.<br>
><br>
> <a href="https://redmine.openinfosecfoundation.org/issues/559" target="_blank">https://redmine.openinfosecfoundation.org/issues/559</a><br>
><br>
> The keyword options would be:<br>
><br>
</div>>   * Country code. ie: US<br>
>   * Match condition: match on source IP, match on destination IP, or<br>
<div>>     match on both.<br>
><br>
> What do you think would be the best syntax for this?<br>
><br>
> Some possibilities:<br>
><br>
</div>>   * geoip:<src|dst|both>,<countrycode>;<br>
>       o alert http any any -> any any (msg:"GEOIP: IP located in<br>
>         US";*geoip:src,US*;sid:3450002;rev:1;)<br>
>   * geoip:<countrycode>,<src|dst|both>;<br>
>       o alert http any any -> any any (msg:"GEOIP: IP located in<br>
>         US";*geoip:US,src*;sid:3450002;rev:1;)<br>
<br>
Thanks for picking this up!<br>
<br>
Doesn't the geoip also allow for other types of data, such as city? I'm<br>
sure that if we have this in Suricata ppl will be interested in buying<br>
the more detailed databases as well.<br>
<span><font color="#888888"><br>
--<br>
---------------------------------------------<br>
Victor Julien<br>
<a href="http://www.inliniac.net/" target="_blank">http://www.inliniac.net/</a><br>
PGP: <a href="http://www.inliniac.net/victorjulien.asc" target="_blank">http://www.inliniac.net/victorjulien.asc</a><br>
---------------------------------------------<br>
</font></span><div><div><br>
_______________________________________________<br>
Oisf-devel mailing list<br>
<a href="mailto:Oisf-devel@openinfosecfoundation.org" target="_blank">Oisf-devel@openinfosecfoundation.org</a><br>
<a href="https://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel" target="_blank">https://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel</a><br>
</div></div></blockquote></div><br><br clear="all"><br></div></div><span><font color="#888888">-- <br><div>Regards,</div>
<div>Peter Manev</div><br>
</font></span><br>_______________________________________________<br>
Oisf-devel mailing list<br>
<a href="mailto:Oisf-devel@openinfosecfoundation.org" target="_blank">Oisf-devel@openinfosecfoundation.org</a><br>
<a href="https://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel" target="_blank">https://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel</a><br></blockquote></div><br>
</div></div></blockquote></div></div></div><span><font color="#888888"><br><br clear="all"><br>-- <br><div>Regards,</div>
<div>Peter Manev</div><br>
</font></span></blockquote></div><br>
</div></div></blockquote></div><br>
</div></div></blockquote></div><br>