Al instalar un debian desde Netinstall en una pc Dell optiplex 760 me encuentro con un pequeño y sencillo problema… El kernel de debian 5 no reconoce la tarjeta de red Ethernet controller: Intel Corporation 82567LM-3 Gigabit Network Connection
El problema radica en que el kernel de Lenny incluye una versión un poco obsoleta del controlador e1000e, la 0.3.3.3-k2 y no la reconoce.

El primer paso es conseguir los fuentes desde la pagina oficial de Intel: downloadcenter.intel.com Estando en Ethernet Components + Ethernet Controllers + Intel 82567 Gigabit Ethernet Controller descargamos el último disponible (latest).

Luego de descargado el codigo fuente de este NIC, vamos a descomprimirlo

[/bash] tar zxf e1000e-x.x.x.tar.gz[/bash]

en la carpeta que el anterior proceso nos creara

   cd e1000e-x.x.x/src/ 

para poder compilarlo en este caso se tuvo que agregar los siguientes paquetes:

linux-source-2.6.26, linux-headers-2.6.26-2-amd64, linux-headers-2.6.26-2-common 2.6.26-19, libncurses5-dev

Ahora si :D

# make install 

Copiamos el modulo.ko a la carpeta correspondiente:

/lib/modules//kernel/drivers/net/e1000e 

ultimos pasos, quitar el modulo antiguo e instalar el nuevo

rmmod e1000e ;  insmod /lib/modules//kernel/drivers/net/e1000e/e1000e.ko

ahora si un ifconfig y mas que listos…

Post to Twitter Tweet This Post Post to Delicious Delicious

Luego de aprender como guardar todos nuestros CDRs dentro de mysql, me ha surgido la duda de como migrar los ya existentes en el master.csv a la base de datos nueva, bueno primero explico algo de como y porque.

Por que:
Esto corriendo asterisk 1.4 y manejandolo con Vicidial (contact center app) pero este utiliza el custom_cdr.conf en donde el guardado en CVS esta definido de la siguiente forma:

Master.csv => "${CDR(clid)}","${CDR(src)}","${CDR(dst)}","${CDR(dcontext)}",
"${CDR(channel)}","${CDR(dstchannel)}","${CDR(lastapp)}",
"${CDR(lastdata)}","${CDR(start)}","${CDR(answer)}","${CDR(end)}",
"${CDR(duration)}","${CDR(billsec)}","${CDR(disposition)}",
"${CDR(amaflags)}",
"${CDR(accountcode)}","${CDR(uniqueid)}","${CDR(userfield)}"

Que significa esto ?? http://www.voip-info.org/wiki/view/Asterisk+billing

ahora bien he encontrado algunos scripts que dicen ser la herramienta mas util para este tipo de migracion lo cual luego de probarlos ha resultado falso!! jejeje

aqui les dejo el que yo modifique y utilize para que migrara de forma transparente los datos del Master.csv con la configuracion cdr_custom de vicidial.

<?php
/*** process asterisk cdr file (Master.csv) insert usage
* values into a mysql database which is created for use
* with the Asterisk_addons cdr_addon_mysql.so
* The script will only insert NEW records so it is safe
* to run on the same log over-and-over.
*
* Author: John Lange (john@johnlange.ca)
* Date: Version 2 Released July 8, 2008
*
*
* Here is what the script does:
*
* Parse each row from the text log and insert it into the database after testing for a
* matching "calldate, src, duration" record in the database. Note that not all fields are
* tested.
*
* If you have a large existing database it is recomended that you add an index to the calldate
* field which will greatly speed up this import.
*
*/
/*
 * Modified by Leif Madsen, July 29, 2009 to add additional columns.
 * Original post and code by John Lange: http://www.johnlange.ca/tech-tips/asterisk/asterisk-cdr-csv-mysql-import-v20/
 */
/*
 * Modified by Paulo Alvarado, Nov. 09 2009 to run with the custom master.cvs from vicidial now
 * Original post and code by John Lange: http://www.johnlange.ca/tech-tips/asterisk/asterisk-cdr-csv-mysql-import-v20/
 */
$locale_db_host = 'localhost';
$locale_db_name = 'asterisk';
$locale_db_login = 'root';
$locale_db_pass = 'vicidialnow';
if($argc == 2) {
$logfile = $argv[1];
} else {
print("Usage ".$argv[0]." <filename>\n");
print("Where filename is the path to the Asterisk csv file to import (Master.csv)\n");
print("This script is safe to run multiple times on a growing log file as it only imports records that are newer than the database\n");
exit(0);
}
// connect to db
$linkmb = mysql_connect($locale_db_host, $locale_db_login, $locale_db_pass) or die("Could not connect : " . mysql_error());
mysql_select_db($locale_db_name, $linkmb) or die("Could not select database $locale_db_name");
//** 1) Find records in the asterisk log file. **
$rows = 0;
$handle = fopen($logfile, "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// NOTE: the fields in Master.csv can vary. This should work by default on all installations but you may have to edit the next line to match your configuration

list($clid, $src, $dst, $dcontext, $channel, $dstchannel, $lastapp, $lastdata, $start, $answer, $end, $duration, $billsec, $disposition, $amaflag, $accountcode,$uniqueid, $userfield ) = $data;

/** 2) Test to see if the entry is unique **/
$sql="SELECT calldate, src, duration".
" FROM cdr".
" WHERE calldate='$end'".
" AND src='$src'".
" AND duration='$duration'".
" LIMIT 1";
if(!($result = mysql_query($sql, $linkmb))) {
print("Invalid query: " . mysql_error()."\n");
print("SQL: $sql\n");
die();
}
if(mysql_num_rows($result) == 0) { // we found a new record so add it to the DB
// 3) insert each row in the database

$sql = "INSERT INTO cdr (calldate, answerdate, hangupdate, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata, duration, billsec, disposition, amaflag, accountcode, uniqueid, userfield)
VALUES('$start', '$answer', '$end', '$clid', '$src', '$dst', '$dcontext', '$channel', '$dstchannel','$lastapp', '$lastdata', '$duration', '$billsec', '$disposition', '$amaflag', '$accountcode', '$uniqueid', '$userfield')";

if(!($result2 = mysql_query($sql, $linkmb))) {
print("Invalid query: " . mysql_error()."\n");
print("SQL: $sql\n");
die();
}
print("Inserted: $end $src $duration\n");
$rows++;
} else {
print("Not unique: $end $src $duration\n");
}
}
fclose($handle);
print("$rows imported\n");
?>

ahora la parte mas dificil, como ejecutarlo: :D

php import.php Master.csv

Nota: si por algun motivo no funciona el comando php, eso significa que no tienen el paquete php-cli para ejecutar sentencias php en linea de comando.

Post to Twitter Tweet This Post Post to Delicious Delicious

Call Detail Records
Las centrales telefónicas generan los llamados Call Detail Records (CDR) que son archivos o logs que contienen información detallada acerca de las llamadas tanto de donde fueron originadas, terminadas o que pasa por el intercambio de las mismas. Y claro no es sorprendente que los CDR se utilizan para la facturación. Fuente: http://www.voip-info.org/wiki/view/CDR

Ahora bien Asterisk es una central telefonica en la que podemos variar  tipo de informacion y almacenamiento que este sistema va a recolectar para sus  CDRs

Asterisk puede trabajar sus CDR de las siguientes formas:

  • Csv – archivos de texto con valores separados coma
  • Cdr SQLite – logs de CDR en la base de datos de SQLite
  • Pgsql – logs de CDR en las bases de datos de PostgreSQL
  • Odbc – logs de CDR a cualquier base de datos con soporte unixODBC
  • Mysql – logs  de CDR en las bases de datos de MySQL
  • Cdr FreeTDS – logs CDR en MS SQL o a la base de datos de Sybase a través de los conductores de FreeTDS
  • Yada – logs de CDR registrados en cualquier base de datos con soporte  yada.

Pero lo que veremos por el momento es como conectar nuestro mysql para guardar los CDRs

Primero vamos a crear la tabla que guardara nuestros datos en el Mysql

CREATE DATABASE asterisk;

GRANT INSERT
  ON asterisk.*
  TO asterisk@localhost
  IDENTIFIED BY 'tu_clave';

USE asterisk;
CREATE TABLE cdr (
  calldate datetime NOT NULL default '0000-00-00 00:00:00',
  clid varchar(80) NOT NULL default '',
  src varchar(80) NOT NULL default '',
  dst varchar(80) NOT NULL default '',
  dcontext varchar(80) NOT NULL default '',
  channel varchar(80) NOT NULL default '',
  dstchannel varchar(80) NOT NULL default '',
  lastapp varchar(80) NOT NULL default '',
  lastdata varchar(80) NOT NULL default '',
  duration int(11) NOT NULL default '0',
  billsec int(11) NOT NULL default '0',
  disposition varchar(45) NOT NULL default '',
  amaflags int(11) NOT NULL default '0',
  accountcode varchar(20) NOT NULL default '',
  uniqueid varchar(32) NOT NULL default '',
  userfield varchar(255) NOT NULL default ''
);

Segundo tenemos que contar con soporte cdr_mysql en nuestro sistema asterisk, como verificamos esto:

dentro del CLI de asterisk corremos

 show modules

…. y la salida tendria que ser algo asi

app_addon_sql_mysql.so         Simple Mysql Interface                   0
cdr_addon_mysql.so             MySQL CDR Backend                        0
134 modules loaded

si por alguna razon no los tenemos cargados, podemos compilar los add-ons de asterisk y luego cargarlos

load app_addon_sql_mysql.so
load cdr_addon_mysql.so

por ultimo crearemos la conexion entre estos 2 sistemas modificaremos el archivo cdr_mysql.conf

[root@SRV-ASTERISK asterisk]# nano /etc/asterisk/cdr_mysql.conf
[global]

hostname=127.0.0.1
dbname=asterisk
table=cdr
password=usuario
user=password
port=3306
;sock=/tmp/mysql.sock
;userfield=1

bueno luego de estos 3 pasos quedara listo nuestros CDRs en Mysql para la central telefonica Asterisk.

Post to Twitter Tweet This Post Post to Delicious Delicious

Un tip super rapido y super util con esta linea podemos bajar todo el contenido de una web especificando el tipo de archivos que queremos descargar, en el siguiente ejemplo :

wget -r -A.pdf http://url-to-webpage-with-pdfs/

Post to Twitter Tweet This Post Post to Delicious Delicious

WordPress 2.8.5

In: Uncategorized

20 Oct 2009

wordpress

Recien salido del horno:
como dicen sus autores esta vez es : WordPress 2.8.5: Hardening Release esperemos que asi sea :D

* A fix for the Trackback Denial-of-Service attack that is currently being seen.
* Removal of areas within the code where php code in variables was evaluated.
* Switched the file upload functionality to be whitelisted for all users including Admins.
* Retiring of the two importers of Tag data from old plugins.

Asi que aqui les dejo el link para de la nota de prensa:

Post to Twitter Tweet This Post Post to Delicious Delicious

Este es un tip para poder saber quien o quienes estan loggeados en nuestros sistemas linux ya sea via ssh, o via consola fisica.

Con el comando “w” podemos ver quien o quienes anda por ahi

techno@srv-test:~$ w
 11:40:13 up 1 day,  1:24,  2 users,  load average: 1.76, 1.68, 1.62
USER     TTY      FROM              LOGIN@   IDLE
techno tty7     :0               Mon10   31:23m 35:49
root pts/0    :0.0             11:40    0.00s  0.19s

como podemos ver aqui los usuarios conectados en el sistema son “root” y “techno”

ahora bien si por algun motivo no quisieramos que mas de alguno de los usuarios listado estuviera dentro de nuestro sistema vamos a utilizar un par de comandos super utilies

Expulsar a un usuario

 skill -STOP -u techno 

Si por equivocacion lo sacamos, podemos corregirlo con

 skill -CONT -u techno 

Ahora si queremos ser mas drasticos y sacar del sistema a todos los usuarios, contandonos entre ellos claro!

 skill -KILL -v /dev/pts/* 

Post to Twitter Tweet This Post Post to Delicious Delicious

androidlogo1 Una de las cosas que me he preguntado es como funciona o cual es el desempeño real de Android, el tan mencionado sistema operativo elaborado por Google, como estos dispositivos todavia no llega a nuestras manos, tenemos la oportunidad de jugar con el OS y asi saber algunos detalles de antemano.

Instalacion desde Linux (ubuntu):

Paso 1: instalar java
El SDK de Android está programado sobre Java. Así que tendrás que instalar la máquina virtual Java antes de pensar en instalar Android. Aqui esta como hacerlo

Carros con ideas digitales click aqui

Paso 2: Descargar el SDK
La versión actual 1.6R1 está disponible como fichero tar.gz en Google. Utiliza este enlace, el SDK. Ocupa unos 222 MB.

Paso 3: Descomprimir el fichero descargado

Puedes utilizar el directorio /var así:

  $ cd /var
  $ sudo tar -xzvf android-sdk-linux_x86-1.6_r1.tgz

Todos los ficheros serán descomprimidos a un directorio llamado android-sdk-linux_x86-1.6_r1, y en su interior verás lo siguiente:

 root@palvarado-desktop:/var/android-sdk-linux_x86-1.6_r1$ ls
add-ons  docs  documentation.html  platforms  RELEASE_NOTES.html  tools

Las herramientas de desarrollo y emulacion para Android están bajo el directorio tools.

Paso 4: ahora vamos a probar el emulador

Dado que todas las herramientas para Android están bajo /var/android-sdk-linux_x86-1.6_r1/tools, habrá que modificar la variable de entorno PATH de forma que incluya ese directorio. Abre un terminal y ejecuta lo siguiente:

  $ PATH=${PATH}:/var/android-sdk-linux_x86-1.6_r1/tools
  $ export PATH

Querrás añadir un código similar a tu .bashrc de forma que la modificación esté siempre disponible.

Puedes empezar las pruebas. Es buena idea conservar todos tus ficheros para Android en un directorio separado. Crea por ejemplo ~/src/android y ejecuta todos los comandos de debajo en ese directorio.

Los moviles pueden ser creados de forma virtual por android SDK y son llamados AVDs ( android virtual device) vamos a experimentar un poco con un teléfono virtual.

Para crear una SDcard virtual:

  $ ./mksdcard 2048M SDCARD

Mira el contenido del directorio y verás ahora un fichero de 2 GB llamado SDCARD. Ahora vamos a crea un teléfono virtual Android llamado googleimagen.

$ ./android create avd -n googleimagen -t 2
Android 1.6 is a basic Android platform.
Do you wish to create a custom hardware profile [no]

Pulsa Enter para elegir no. Verás el siguiente mensaje.

Created AVD ‘googleimage’ based on Android 1.6, with the following hardware config:
hw.lcd.density=160

Arranca ahora el emulador.

$ ./emulator @googleimagen -sdcard SDCARD

Aparecerá tu teléfono virtual asi :

android

Otras instalaciones:
Instalacion de Android SDK en windows

Post to Twitter Tweet This Post Post to Delicious Delicious

El mensaje que nunca queremos ver al intentar conectarnos en nuestro Mysql, y que significa esto, pues que todas las conexiones disponibles (100 por default) dentro de nuestro mysql han sido ya tomadas.

Lo primero que debemos de verificar es que clase de conexiones esta manejando el mysql server, debido a que algunas de ellas pueden estar “colgadas”.

mysqladmin -uUSUARIO -pPASSWORD processlist

para aumentar el numero de conexiones concurrentes que nuestro servidor mysql puede manejar vamos a editar el archivo /etc/mysql/my.cnf:

port = 3306
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip-locking
set-variable = max_connections=100

aquí cambiaremos el valor predeterminado de 100 a 250 o un poco mas, recuerden que esta cantidad depende linealmente de la cantidad de memoria ram de que la dispongamos y así también del poder de CPU.

NOTA: algunas veces este problema tambien puede estar realacionado con la resolucion DNS, asi que tambien podemos verificar el archivo /etc/hosts de cliente para ver si esta bien definido el nombre e IP del servidor, asi tambien estos mismos datos dentro del /etc/hosts del server.

Post to Twitter Tweet This Post Post to Delicious Delicious

a la calle pues…. y salio el google chrome 3 Estable

chrome3

A casi ya dias de cumplir 1 año de haber sido su lanzamiento inicial (2 de septiembre de 2008), Goole lanza la ultima versión estable 3.0.195.21 (15 de septiembre de 2009) luego de mas de 5 mil bugs limpiados y arreglados… He aqui el anuncio oficial de este lanzamiento

Para los que no nos gustan los installers web, aqui les dejo el link para bajar el instalador FULL offline

Link | Google Chrome 3 Full installer (win)

Post to Twitter Tweet This Post Post to Delicious Delicious

wordpress Como ya habia platicado al inicio de este nuevo blog, por culpa de malas practicas de seguridad en mi sitio, el wordpress que tenia instalado sufrió varios ataques.. que como resultado de los mismos, fue la eliminación casi completa de toda la información contenida en el :(
Ahora bien les dejo 10 tips muy importantes a tomar en cuenta a la hora de administrar un sitio basado en nuestro bondadoso pero vulnerable wordpress. Nota aclaratoria: este post tiene la intención de dar algunos tips de seguridad esencial y basica, mas no cerrar bugs o problemas de código que wordpress (cms) tiene en su en su estructura original.

Aclarando esto: vamos a lo que nos interesa.

1 .- Cuidado con los roles dentro del wordpress:
uno de los mayores errores a veces es el manejo de varios usuarios que son “admin” en el CMS, y a veces al ser creado en forma “test” los hacemos con passwords débiles, derivado a su carácter temporal, pero como es de esperarse a veces se nos olvida borrarlos.

2 .- Renombrar el user admin, una de las cosas que wordpress no permite es cambiar el usuario “admin” (equivalente de root en linux) a otro nombre menos genérico ejem: “root”. Con este script lo podremos hacer.
Recuerden siempre antes de cualquier cambio en la DB hacer una copia de seguridad

$ mysql -u USERDB -p
Password: CLAVE
mysql> use DB_BLOG;
mysql> update wp_users set user_login='root' where user_login='admin';
mysql> exit;

3.- No permitir que los usuarios en la web puedan navegar por nuestras carpetas del blog, lease wp-content/plugins, wp-content/themes, wp-content/uploads, wp-admin …, muchos de los problemas ataque de exploids, bugs y demas bichos, son porque permitimos que nuestros “visitantes” sepan que plugins estamos usando y que versión de ellos tenemos instalados, como saben no todo es totalmente seguro y a diario surgen parches para todo, y wordpress no es la excepción así que entre mas oculto tengamos que plugs y que versiones usamos sera mucho mejor, además que nos sirve para que no nos copien el theme :D

he aqui el codigo que hay que agregar al .htaccess que se encuentra el root del website, para evitar todos estos problemas:

Options All -Indexes

4 .- Permisos en las carpetas y/o archivos (si esta hosteado en sistemas linux)
muchas veces hacemos nuestra instalación de wordpress tan vanilla (flat, OOB) que nos saltamos la verificación de permisos, y en nuestro afan de tener el sitio “up and running” tan pronto nos sea posible, o en el calor de la emoción de nuestro nuevo theme nos olvidamos de este paso tan importante.

Este es un posible esquema de seguridad según el árbol de archivos/carpetas de wordpress

/ — La raiz del directorio WordPress: Todos los archivos ubicados aqui deben ser legibles y escribiles únicamente por el usuario master de la cuenta de hosting a Excepcion de .htaccess si se desea que WordPress genere reglas de rewrite por su propia cuenta
/wp-admin/ — El area de administración de WordPress: aqui todos los archivos deben de ser escribiles únicamente por la usuario master.
/wp-includes/ — aqui se guarda el grueso de código que mueve a WordPress: nuevamente todos los archivos únicamente deben de ser escribiles por el usuario master.
/wp-images/ — Archivos de imágenes usadas por WordPress: escribibles por el usuario master, aunque legible por casi todos
/wp-content/ — directorio de contenido para los usuarios y el motor de wordpress: Diseñado por los Desarrolladores para ser accesado por completo por todos por (owner/user, group y public).
/wp-content/themes/ — Directorio de las pieles o temas. Si deseas usar el editor incluido en wordpress todos los archivos deben de ser escribibles por el grupo de usuarios de lo contrario únicamente debe de poder ser modificados por el usuario master
/wp-content/plugins/ — plugins: estos archivos deben de ser escritos únicamente por la cuenta master de hosting
otros directorios dentro de /wp-content/ debe de investigarse según los requerimientos de los plugins específicos en este caso los permisos pueden variar

Vamos a arreglar nuestros permisos desde SSH

Para Directorios

find [path] -type d -exec chmod 755 {} \;

Para Archivos

find [path] -type f -exec chmod 644 {} \;

el único directorio que se tiene que omitir cuando corremos estas lineas es /wp-includes/.

5 .- Ocultemos información que a simple vista parece inofensiva: muchas veces en el código generado por wordpress hay muchas pistas que podrían delatar nuestras vulnerabilidades, como por ejemplo en el código podemos ver que versión de wordpress estamos corriendo para evitar esto..
borremos del header.php de nuestro theme la siguiente linea:

<meta name=”generator”
content=”WordPress <?php bloginfo(’version’); ?>” />

6 .- Seguridad en la base de datos I: aunque sonara bastante obvio, si manejamos varios sitios en un mismo hosting tratemos de mantener en lo posible las bases de datos independientes para cada sitio, muchas veces por falta de recursos en el plan de hosting usamos 1 sola db para mas de 1 sitio, esto no es nada recomendable.

7 .- Seguridad en la base de datos II: cambiemos el esquema de nuestra base de datos con respecto a los prefix “wp_” si personalizamos esto le hara mucho mas difícil la intrusión a cualquier hacker. Ejem: miblog_wp_tabla…

8 .- Aseguremos el acceso a nuestro wp-admin: vamos a ponernos un poco mas paranoicos y vamos a permitir únicamente accesso a wp-admin desde 1 o varias ips conocidas.

Coloquemos esto en nuestro .htaccess en el / de nuestro website

Order Deny,Allow
Allow from ww.xx.yy.zz #reemplazar con la/las iPs
Deny from all

9 .- Eliminar archivos innecesarios: borrar lo siguientes archivos /wp-admin/install.php y /wp-admin/upgrade.php puesto que son otro foco de vulnerabilidad

y….

10 .- Aunque la ultima pero no menos importante: Siempre mantengamos un backup de nuestra DB al día, así también actualicemos todos los plugins a la ultima versión así como el WordPress.

Como un plus les dejo un par de artículos y un video que me gustaría que vieran

Plugin de deteccion y bloqueo de intrusos | WPIDS es un port de PHPIDS a WordPress.

20 Plugins y tips de seguridad | 20 WordPress Security Plug-ins And Tips To keep Hackers Away

10 Tips To Make WordPress Hack-Proof from guvnrDOTcom on Vimeo.

Les recuerdo mucha de esta información puede parecer obvia a algunos y nueva para otros, pero la razón de este post es tan solo dar algunos tips para no caer por confiados.

Post to Twitter Tweet This Post Post to Delicious Delicious

Acerca de este Blog

Este espacio esta dedicado a la difusión del software libre en todas sus expresiones, es mi espacio técnico personal, para difundir a todos los rincones el conocimiento libre. "La verdad os hará libres" (Jn 8,32); El techno :Editor, redactor, ingeniero, tecnico, desarrollador, musico y DJ wannabe, etc.. ese soy yo y este es mi espacio

  • http://newspcs.com: [...] y también pensando que la maravillosa SGAE nos pueda sancionar.Éste post fué visto en el bl [...]
  • techno: @maski: para los que no tienen acceso a ediar el .htaccess hay un plugin que lo hace desde adentro d [...]
  • Maski: Me gusta, muy importante resaltar lo de los accesos a directorios, lo del wp-admin no se me habia oc [...]
  • Como Forzar la velocidad de la placa de red en Debian o Ubuntu | AdslFaqs.com.ar: [...] | Forzar velocidad en NIC debian / ubuntu Tags: chmod, Debian, Linux Debian, scripts, sis [...]
  • El techno: lo que podrias hacer es reemplazar el $(which ethtool)" por el path completo de tu binario ejem: /us [...]

Nuestro Patrocinadores

Tags

Mi galeria de fotos

Mazinger ZMazinger Zno se como lo hace (bruno)no se como lo hace (bruno) 2carga pesada al estilo indu 1carga pesada al estilo indu 2una tv en Solid Statepauloalvarado ipodEsquilandia GuatemalaEl techno en una sinagogaDSC00966DSC00962

Este blog se publica bajo licencia

Blog bajo licencia Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License
Creative Commons License

Calendario

September 2010
M T W T F S S
« Jul    
 12345
6789101112
13141516171819
20212223242526
27282930