giovedì 16 ottobre 2008

Select Distinct su DataSet in Vb.Net

Le funzioni sotto riportate permettono di effettuare da codice una query con "Select Distinct" su un DataSet.

FieldNames è un array di string con in campi su cui fare la select distinct.



Public Function SelectDistinct(ByVal SourceTable As DataTable, _
    ByVal ParamArray FieldNames() As String) As DataTable

    Dim lastValues() As Object
    Dim newTable As DataTable

    If FieldNames Is Nothing OrElse FieldNames.Length = 0 Then
        Throw New ArgumentNullException("FieldNames")
    End If

    lastValues = New Object(FieldNames.Length - 1) {}
    newTable = New DataTable

    For Each field As String In FieldNames
        newTable.Columns.Add(field, SourceTable.Columns(field).DataType)
    Next

    For Each Row As DataRow In SourceTable.Select("", String.Join(", ", FieldNames))
        If Not fieldValuesAreEqual(lastValues, Row, FieldNames) Then
            newTable.Rows.Add(createRowClone(Row, newTable.NewRow(), FieldNames))
            setLastValues(lastValues, Row, FieldNames)
        End If
    Next

    Return newTable
End Function



Private Function fieldValuesAreEqual(ByVal lastValues() As Object, _
    ByVal currentRow As DataRow, ByVal fieldNames() As String) As Boolean

    Dim areEqual As Boolean = True

    For i As Integer = 0 To fieldNames.Length - 1
        If lastValues(i) Is Nothing OrElse Not lastValues(i).Equals(currentRow(fieldNames(i))) Then
            areEqual = False
            Exit For
        End If
    Next

    Return areEqual
End Function



Private Function createRowClone(ByVal sourceRow As DataRow, _
    ByVal newRow As DataRow, ByVal fieldNames() As String) As DataRow

    For Each field As String In fieldNames
        newRow(field) = sourceRow(field)
    Next

    Return newRow
End Function



Private Shared Sub setLastValues(ByVal lastValues() As Object, _
    ByVal sourceRow As DataRow, ByVal fieldNames() As String)

    For i As Integer = 0 To fieldNames.Length - 1
        lastValues(i) = sourceRow(fieldNames(i))
    Next
End Sub

lunedì 6 ottobre 2008

Configurazione Cisco SOHO 97 per NGI con 8 ip statici

Avendo la necessità di configurare un router Cisco SOHO 97 per un'Adsl di NGI con 8 IP statici, mi sono fatto un giro per internet ma non ho trovato nulla che facesse al caso mio. Mi spiego:

Degli 8 indirizzi pubblici statici assegnati, in realta solo 5 sono utilizzabili, in quanto il primo, il secondo e l'ultimo della subnet sono indirizzi di "servizio".

La mia necessita era di riuscire a fare il NAT 1:1 degli indirizzi pubblici su indirizzi privati in modo che da permettere la gestione di quest'ultimi attraverso il mio server PFSense. Praticamente la struttura della rete è questa:

Router <--> PFSense <--> Rete interna (MZ e DMZ)

Praticamente, una persona dal "mondo" fa una richiesta all'indirizzo pubblico, il router lo passa al PFSense come indirizzo privato sull'interfaccia WAN del PFSense, il PFSense lo traduce in un indirizzo di un server sull'interfaccia LAN o DMZ.

Siccome la configurazione del Router mi ha fatto "dannare" un po', la posto di seguito:


no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
enable secret
!
hostname NomeDelRouter
!
boot-start-marker
boot-end-marker
!
enable password PasswordDiEnable
!
no aaa new-model
!
resource policy
!
!
!
ip cef
ip domain name ngi.it.
ip name-server 88.149.128.12
ip name-server 88.149.128.22
!
username UserAR password 0 PasswordAR
!
!
!
!
interface Ethernet0
 ip address 192.168.0.254 255.255.255.0
 ip nat inside
!
interface ATM0
 no ip address
 ip nat outside
 no ip mroute-cache
 no atm ilmi-keepalive
 dsl operating-mode auto
 hold-queue 224 in
 pvc 8/35
  encapsulation aal5snap
  protocol ppp dialer
  dialer pool-member 1
 !
!
interface Dialer0
 ip address negotiated
 ip nat outside
 encapsulation ppp
 dialer pool 1
 dialer-group 1
 ppp pap sent-username UserADSL password 0 PassADSL
!
ip route 0.0.0.0 0.0.0.0 Dialer0
no ip http server
!
ip nat inside source static 192.168.0.1 interface Dialer0
ip nat inside source static 192.168.0.10 IpPubblico1
ip nat inside source static 192.168.0.11 IpPubblico2
ip nat inside source static 192.168.0.12 IpPubblico3
ip nat inside source static 192.168.0.13 IpPubblico4
ip nat inside source static 192.168.0.14 IpPubblico5
!
!
control-plane
!
!
line con 0
 no modem enable
line aux 0
line vty 0 4
 login local
!
scheduler max-task-time 5000
end

Dove UserAR e PasswordAR sono rispettivamente il nome utente e la password per l'accesso da remoto (console o telnet), UserADSL e PassADSL sono utente e password della connessione.
192.168.0.254 è l'indirizzo di rete del router.
192.168.0.1 è l'indirizzo dell'interfaccia WAN del PFSense.
192.168.0.10-14 sono gli indirizzi su cui natto gli indirizzi pubblici.

Degno di nota il fatto che NGI, come si vede, non assegna un indirizzo ip statico di punto-punto (interfaccia Dialer0 del router) ma lo da via DHCP, anche se in realtà l'indirizzo assegnato appunto via DHCP sarà sempre il II nel pool di indirizzi assegnato.